ログイン
編集不可のページディスカッション情報添付ファイル
"clear/note/2013-03"の差分

MMA
2と3のリビジョン間の差分
2013-03-07 21:15:18時点のリビジョン2
サイズ: 3786
編集者: clear
コメント:
2013-03-07 21:15:35時点のリビジョン3
サイズ: 3790
編集者: clear
コメント:
削除された箇所はこのように表示されます。 追加された箇所はこのように表示されます。
行 20: 行 20:
EWMHにおいて現在アクティブなウィンドウを表す`_NET_WM_WINDOW`の変化を監視する。WMのデバッグ用。 EWMHにおいて現在アクティブなウィンドウを表す`_NET_ACTIVE_WINDOW`の変化を監視する。WMのデバッグ用。

2013/03

  • いつのまにやら3月

03/01

XCBを使ったWMを書き始めて3ヶ月くらいになるが、ようやくXCBが分かってきた。

  • 結局のところXプロトコルをしゃべるための薄いラッパーで、リクエストとリプライを投げつけ合うための道具
  • 分からない時期に見てもさっぱり分からないが、しばらく触って分かるようになるとすごく明瞭
  • ドキュメンテーションの整備が進まないのがよく分かる
    • ほぼプロトコルとの一対一対応で、XCB特有の部分というのはほとんどない
    • ライブラリの大部分が仕様から自動生成されているだけあって、インターフェースの一貫性が非常に高い
      • 超がつくレベルのパターンゲー
  • ある程度Xlibを知っていれば移行は難しくない
  • XlibだろうがXCBだろうが、数多くの規約を知らなければならないのは変わらない
    • GUIプログラミングで苦労するのはむしろこちら

この手の「分かる人には説明するまでもないんだけど、分からない人にはさっぱり」という類のものは敷居が高くなりがちなので、チュートリアルが大事だと思う。XCBに関して言えば、公式にチュートリアルがあるもののXlibを知っている人向けに書かれている感じが強い(そもそもWMでも書かない限りはXCBなんかよりGTKなりQtを使うべきなので、それでも問題はないのかもしれないが)。

03/07

_NET_ACTIVE_WINDOWの追跡

EWMHにおいて現在アクティブなウィンドウを表す_NET_ACTIVE_WINDOWの変化を監視する。WMのデバッグ用。

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <string.h>
   4 #include <xcb/xcb.h>
   5 
   6 xcb_connection_t *conn;
   7 xcb_screen_t *screen;
   8 xcb_atom_t net_active_window;
   9 
  10 int main(void)
  11 {
  12     int screen_num, i;
  13     xcb_screen_iterator_t iter;
  14 
  15     conn = xcb_connect(NULL, &screen_num);
  16 
  17     iter = xcb_setup_roots_iterator(xcb_get_setup(conn));
  18     for (i = 0; i < screen_num; ++i)
  19         xcb_screen_next(&iter);
  20     screen = iter.data;
  21 
  22     xcb_intern_atom_reply_t *r = xcb_intern_atom_reply(conn,
  23         xcb_intern_atom(conn, 0, strlen("_NET_ACTIVE_WINDOW"), "_NET_ACTIVE_WINDOW"),
  24         NULL);
  25     if (r) {
  26         net_active_window = r->atom;
  27         free(r);
  28     } else {
  29         fputs("cannot intern atom\n", stderr);
  30         exit(EXIT_FAILURE);
  31     }
  32 
  33     xcb_void_cookie_t cookie = xcb_change_window_attributes(conn, screen->root,
  34         XCB_CW_EVENT_MASK, (const uint32_t[]){ XCB_EVENT_MASK_PROPERTY_CHANGE });
  35     xcb_flush(conn);
  36 
  37     xcb_generic_event_t *event;
  38     xcb_property_notify_event_t *e;
  39     while (event = xcb_wait_for_event(conn)) {
  40         switch (event->response_type & 0x7f) {
  41         case XCB_PROPERTY_NOTIFY:
  42             e = (xcb_property_notify_event_t *)event;
  43             if ((e->atom == net_active_window) && (e->state == XCB_PROPERTY_NEW_VALUE)) {
  44                 xcb_get_property_reply_t *r = xcb_get_property_reply(conn,
  45                     xcb_get_property(conn, 0, screen->root, net_active_window, XCB_ATOM_WINDOW, 0, 1),
  46                     NULL);
  47                 if (r) {
  48                     xcb_window_t *win = xcb_get_property_value(r);
  49                     printf("%x\n", *win);
  50                     free(r);
  51                 }
  52             }
  53             break;
  54         }
  55         free(event);
  56     }
  57     xcb_disconnect(conn);
  58     return 0;
  59 }

この程度のツールなら、Cで書かずにpythonとかでさくっと作ってしまうのが良いだろう…と書いた後に思う。

clear/note/2013-03 (最終更新日時 2013-03-26 14:35:32 更新者 clear)