はじめに
こんにちは、野村です。
前回は、あらかじめ決められた位置にウィンドウを配置するスクリプトを紹介しました。
ウィンドウマネージャ「TWM」は、ウィンドウのリサイズ操作が面倒。したがって、ウィンドウを配置するのも面倒。なので、コマンド「xdotool」を使ってみました。
で、これを使っているうち、ウィンドウマネージャが不要な気がしてきたのですよ。
思い立ったら即実行。
とりあえず今回は下準備です。
まずは、ウィンドウのフォーカスを切り替える仕組みを作ってみます。
必要なパッケージ
今回必要なものは以下のコマンドです。
- xdotool(ウィンドウやマウスを制御するコマンド)
インストールはこんな感じ(debianの場合)
$ sudo apt install xdotool
ウィンドウのIDの一覧を取得するコマンドを作成
コマンド「xwininfo」を駆使すれば、表示しているウィンドウのIDの一覧を取得することができると思うけど、なんかめんどくさい。
いっそのことC言語でコマンドを書いてしまおうと思う。
コマンド名は「winlist」でいいや。
ソース
winlist.c
#include <X11/Xlib.h>
#include <stdlib.h>
#include <stdio.h>
int CMP( const void *p, const void *q ){
return *(Window*)p - *(Window*)q;
}
void WindowIdList(Display *dpy, Window root){
Window dum, *kids;
XWindowAttributes att;
unsigned int i, n;
XQueryTree(dpy, root, &dum, &dum, &kids, &n);
qsort(kids, n, sizeof(Window), CMP);
for (i=0; i<n; i++) {
XGetWindowAttributes(dpy, kids[i], &att);
if (att.map_state != 2 || att.override_redirect != 0) continue;
printf("%d\n", kids[i]);
}
}
int main() {
Display *dpy;
Window root;
if (!(dpy = XOpenDisplay(0x0))) return 1;
root = DefaultRootWindow(dpy);
WindowIdList(dpy, root);
return 0;
}
ビルド
ビルドするにはパッケージ「xorg-dev」が必要です(debianの場合)。
$ sudo apt install xorg-dev
ビルドしたらパスの通ったデレクトリに「winlist」という名前でコピーする。
$ gcc winlist.c -I/usr/X11R6/include -L/usr/X11R6/lib -lX11
$ cp a.out ~/bin/winlist
ウィンドウのフォーカスを切り替えるコマンドを作成
bashで書きます。
パスの通ったデレクトリに「winring」という名前で保存し、パーミッションを755にします。
#!/bin/bash
declare -a IDS
IDS=(`winlist`)
LEN=${#IDS[@]}
NOW=`xdotool getwindowfocus`
NOWCNT=0
for ((i=0; i < $LEN; i++)); do
if [ $NOW = ${IDS[$i]} ]; then
NOWCNT=`expr $i + 1`
fi
done
if [ $NOWCNT -ge $LEN ]; then
NOWCNT=0
fi
ID=${IDS[$NOWCNT]}
xdotool windowraise $ID
xdotool windowfocus $ID
終わりに
以上、ウィンドウのフォーカスを切り替える仕組みを作ってみました。
次回は、実際にウィンドウマネージャを使わずにGUIを起動させてみます。
ウィンドウマネージャなしでGUIを使えるようにするためにやってみたこと、その後半戦です。ウィンドウの配置を変える自作コマンド「winpos」を修正しました。
というわけで、今回はこれにて。