Login
Immutable PageDiscussionInfoAttachments
clear/note/2013-03

MMA

2013/03

03/01

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

この手の「分かる人には説明するまでもないんだけど、分からない人にはさっぱり」という類のものは敷居が高くなりがちなので、チュートリアルが大事だと思う。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とかでさくっと作ってしまうのが良いだろう…と書いた後に思う。

03/21

居るだけのウィンドウマネージャ

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <xcb/xcb.h>
   4 #include <xcb/xcb_aux.h>
   5 #include <xcb/xcb_event.h>
   6 
   7 void configure_window(xcb_connection_t *conn, xcb_configure_request_event_t *e)
   8 {
   9     uint32_t values[7];
  10     int i = 0;
  11     if (e->value_mask & XCB_CONFIG_WINDOW_X)
  12         values[i++] = e->x;
  13     if (e->value_mask & XCB_CONFIG_WINDOW_Y)
  14         values[i++] = e->y;
  15     if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH)
  16         values[i++] = e->width;
  17     if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT)
  18         values[i++] = e->height;
  19     if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
  20         values[i++] = e->border_width;
  21     if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING)
  22         values[i++] = e->sibling;
  23     if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE)
  24         values[i++] = e->stack_mode;
  25     xcb_configure_window(conn, e->window, e->value_mask, values);
  26     xcb_flush(conn);
  27 }
  28 
  29 int main(void)
  30 {
  31     int screen_num;
  32     xcb_connection_t *conn = xcb_connect(NULL, &screen_num);
  33     xcb_screen_t *screen = xcb_aux_get_screen(conn, screen_num);
  34 
  35     xcb_change_window_attributes(conn, screen->root, XCB_CW_EVENT_MASK,
  36         &(const uint32_t){ XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT });
  37     xcb_flush(conn);
  38 
  39     xcb_generic_event_t *event;
  40     while ((event = xcb_wait_for_event(conn))) {
  41         if (event->response_type == 0) {
  42             xcb_generic_error_t *e = (xcb_generic_error_t *)event;
  43             fprintf(stderr, "X protocol error: request=%s, error=%s\n",
  44                 xcb_event_get_request_label(e->major_code),
  45                 xcb_event_get_error_label(e->error_code));
  46             exit(EXIT_FAILURE);
  47         } else {
  48             switch (event->response_type & 0x7f) {
  49             case XCB_MAP_REQUEST:
  50                 puts("MapRequest");
  51                 xcb_map_window(conn, ((xcb_map_request_event_t *)event)->window);
  52                 xcb_flush(conn);
  53                 break;
  54             case XCB_CONFIGURE_REQUEST:
  55                 puts("ConfigureRequest");
  56                 configure_window(conn, (void *)event);
  57                 break;
  58             }
  59         }
  60         free(event);
  61     }
  62     xcb_disconnect(conn);
  63     return 0;
  64 }

03/26

画面のロック(gnome-screensaverで)

あらかじめgnome-screensaverを上げておく。

# .xinitrcとか.xsessionとかで
gnome-screensaver &

ロックしたくなったら

gnome-screensaver-command -l

clear/note/2013-03 (last edited 2013-03-26 14:35:32 by clear)