うぃんどーまねーじゃーを自作しよう - X 2.0 の時代へ

そう、Linuxにあって、OSXに無いのは、「ウィンドウマネージャを弄る文化」だな。だから、つまり、「forkが速くて、パッケージシステムが色々あって、かつ、ウィンドウマネージャを弄る文化があるのはLinuxだけ!」というところか。
MacWindowsしか使ったことが無い人は、ウィンドウマネージャの重要さを知らない!はっきり言って、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です。