この日記にツッコミを入れたい人は、ツッコミを入れたい日付をクリックすると、フォームが現れることもある模様です。
次のようなプログラムで、キーボード入力ができなかった。
#include <stdio.h>
#include <X11/Xlib.h>
main()
{
Display *dsp; /* ディスプレイ構造体の宣言 */
Window win; /* ウィンドウ構造体の宣言 */
XEvent ev; /* イベント構造体 */
XSetWindowAttributes att;
char buf[64];
KeySym keysym;
dsp = XOpenDisplay( NULL ); /* ディスプレイのオープン */
if (dsp == NULL) {
fputs("can not connect display\n", stderr);
exit(1);
}
/* ウィンドウの生成 */
win = XCreateSimpleWindow(dsp, DefaultRootWindow(dsp), 0, 0, 800, 400, 1,
BlackPixel(dsp,0), WhitePixel(dsp,0));
att.override_redirect = True;
XChangeWindowAttributes(dsp, win, CWOverrideRedirect, &att);
XSelectInput(dsp, win,
ButtonPressMask|
ButtonReleaseMask|
KeyPressMask|
KeyReleaseMask|
EnterWindowMask|
LeaveWindowMask
);
XMapWindow(dsp, win); /* ウィンドウの表示 */
XFlush(dsp);
while (True) { /* イベントの無限ループの開始 */
XNextEvent(dsp, &ev); /* 新しいイベントを受け取る */
switch (ev.type) { /* イベントのタイプで処理を分ける */
case ButtonPress:
printf("event.type=ButtonPress No=[%d]\n", ev.xbutton.button);
switch (ev.xbutton.button) {
case 3:
goto CLOSE_WINDOW;
break;
default:
break;
}
break;
case KeyPress:
case KeyRelease:
printf("event.type=%s\n",
(ev.type == KeyPress) ? "KeyPress" : "KeyRelease");
if (XLookupString(&(ev.xkey),buf,sizeof(buf),&keysym,NULL) >= 1) {
if (isprint(buf[0])) {
printf("KeyPress=[%s] keysym = [%x]\n", buf, keysym);
} else {
printf("KeyPress=[%02x][%02x] keysym=[%x]\n",
buf[0], buf[1], keysym);
}
} else {
printf("keysym = [%x]\n", buf, keysym);
}
break;
case EnterNotify:
printf("event.type=EnterNotify No=[%d]\n", ev.xbutton.button);
break;
case LeaveNotify:
printf("event.type=LeaveNotify No=[%d]\n", ev.xbutton.button);
break;
default:
break;
}
}
CLOSE_WINDOW:
XCloseDisplay( dsp ); /* ディスプレイのクローズ */
exit(0);
}
原因は、XChangeWindowAttributes()でウィンドウマネージャから独立していたので、ウィンドウにマウスが乗ってもキーボードのフォーカスがウィンドウに当たっていなかったから、らしいです。
なので、EnterNotifyイベントに
XSetInputFocus(dsp, win, RevertToParent, CurrentTime);
を追加して、自分で入力フォーカスを設定したらキーボードイベントが取得できるようになりました。
以上、覚書メモ
なんか、これが解決したら気が抜けてしまってグダグダになってます。