evilwmでskkinputのフォーカスがおかしいのをどうにかする

注意

原因がよくわからんのだけど、ウィンドウ閉じたときにSEGVすることがあるようで、 そのうちなんとかする予定。

what?

evilwmでXIMの変換するとフォーカスがIMウィンドウに移っちゃってうまく変換できないのをなんとかする。

方法

events.cのhandle_enter_eventの中の12行目あたりに


	current_screen = find_screen(e->root);
	/* if (e->window == root && !current) {
		XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
		return;
	} */
	if ((c = find_client(e->window))) {

>		XWMHints *hints = XGetWMHints(dpy, c->window);
>
>		if ( (hints->flags&InputHint) && (hints->input==False) ) {
>			XFree(hints);
>			return;
>		}
>
>		XFree(hints);

#ifdef VWM
		wdesk = c->vdesk;
		if (wdesk != vdesk && wdesk != STICKY)

追記: 環境によっては、XGetWMHintsがNULLを返すことがあるようです。落ちるようになったときはNULLチェック入れてあげてください。

こんなコードを入れておく。で、コンパイル。終わり。

ウィンドウが位置的に格好悪いのは別にどうでもいい…よねぇ…

非常に大雑把に解説

注: あんまり詳しく知らないんで信用しないでください

X上にあるウィンドウはプロパティだか、アトムだかとかいうので、 ウィンドウマネージャー(以下WM)と情報交換している感じになっている。

参考: クライアント間通信

で、そのプロパティの中でもフォーカスの属性はWM_HINTSとかいうプロパティで WMと通信してる。それで、IMの類いはここに、「俺はフォーカスなんていらん」っていうふうな ヒントを載せているわけだ。このへんはxpropで確認できるはず。

# skkinput の変換ウィンドウ(minibufferというらしい)のxprop

WM_STATE(WM_STATE):
		window state: Normal
		icon window: 0x0
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW
WM_TRANSIENT_FOR(WINDOW): window id # 0x400001
WM_CLIENT_LEADER(WINDOW): window id # 0x400001
WM_LOCALE_NAME(STRING) = "C"
WM_CLASS(STRING) = "minibuffer", "Skkinput"
WM_HINTS(WM_HINTS):
		Client accepts input or input focus: False   # ここ
		Initial state is Normal State.
		window id # of group leader: 0x400001
WM_NORMAL_HINTS(WM_SIZE_HINTS):
		user specified size: 640 by 14
		program specified minimum size: 0 by 14
		program specified resize increment: 1 by 14
		program specified base size: 0 by 0
		window gravity: SouthWest
WM_CLIENT_MACHINE(STRING) = "localhost.localdomain"
WM_NAME(STRING) = "minibuffer"

でも、evilwmはWM_HINTSをほとんど(サイズ以外?)無視するので、IMにもフォーカスがいっちゃう。 だから、そのへんを修正すればどうにでもなる、という話。

それと、evilwmのほうのソースはそんなに複雑じゃないので、ちょっと読むだけで結構なんとかなる。

おまけ

evilwm使い易いんだけど、デスクトップ移動した時にウィンドウの大きさの関係で フォーカスどっかいっちゃうことがあるんだよなぁ…

とか思って、このへんなんとかしようと思ったら、なんか既に実装されてるぽい。

Makefile に DEFINES += -DVWM_WARP でいい感じだと思うのですが、どうでしょう。

--

研修の最中に勝手に作ったので給料泥棒だ。まあ、Perl入門の話だったんで許してください。

なんだかんだいって X に詳しくなっていくなぁ…無駄だなぁ…