うぃんどーまねーじゃーを自作しよう - X 2.0 の時代へ
そう、Linuxにあって、OSXに無いのは、「ウィンドウマネージャを弄る文化」だな。だから、つまり、「forkが速くて、パッケージシステムが色々あって、かつ、ウィンドウマネージャを弄る文化があるのはLinuxだけ!」というところか。
MacやWindowsしか使ったことが無い人は、ウィンドウマネージャの重要さを知らない!はっきり言って、Alt-Tabとか、Exposeとか使ってるのなんて、アレだよ。アレ。キーボードのみで、瞬時に任意のウィンドウに移動できてこそウィンドウマネージャだよ。
まあ、それはいいんだけど、最近は、「自由とかセキュリティとかいう言葉を使わないで、デスクトップLinuxを褒めたたえよう!」というのがまあ、アレ。と、いうのは、某書籍の著者の方が実はサーバーでしかLinuxを使ってなくてデスクトップはWindowsを使ってるだとか、まあ、そういうのがあまりにショックだったリバウンド。
と、いうわけで、デスクトップLinuxにおいて一番重要な部分であるウィンドウマネージャを自作してしまおう、という話。いつまで続くかは知らん。
さて、まず、ウィンドウマネージャと、普通のXクライアントとの違い。
ウィンドウマネージャは、普通のXクライアントでは拾えないイベントを拾っている。
man XSelectInputより、このへん。
o Only one client at a time can select CirculateRequest, ConfigureRequest, or MapRe-
quest events, which are associated with the event mask SubstructureRedirectMask.o Only one client at a time can select a ResizeRequest event, which is associated
with the event mask ResizeRedirectMask.
CirculateRequestやら、ResizeRequestは、一個のクライアントしかイベントを拾うことはできないらしい。
そいつらを拾うようにするには、SubstructureRedirectと、ResizeRequestをSelectInputしておく。
#include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/X.h> #include <stdio.h> #include "global.h" Display *dpy; Window root; int main( int argc, char **argv ) { const char *opt_dpy = NULL; dpy = XOpenDisplay( opt_dpy ); if ( dpy == NULL ) { fputs( "can't open display.\n", stderr ); return 1; } root = RootWindow( dpy, DefaultScreen(dpy) ); XSelectInput( dpy, root, SubstructureRedirectMask|ResizeRedirectMask|SubstructureNotifyMask ); while ( 1 ) { XEvent ev; XNextEvent(dpy,&ev); printf("%d\n",ev.type); } XCloseDisplay( dpy ); return 0; }
これで、ウィンドウマネージャのできあがり。機能は、「他のウィンドウマネージャが起動できなくなる」。
ちなみに、他のウィンドウマネージャが起動した状態で上のを動かすと、エラーに。
~/test/wm/nullwm$ X -version
X Window System Version 6.8.2 (Ubuntu 6.8.2-77 20051010180225 root@adare.warthogs.hbd.com)
Xは6.8です。