我正在尝试制作一个非常简单的窗口管理器用于学习目的。我正在使用C
和xcb
图书馆。如果启动了新应用程序,我正在尝试引发事件。
现在,我创建了一个根窗口,我可以在其中接收鼠标和键盘事件。我还在窗口顶部画了一个彩色条。当我按下回车键时,xterm 将使用 fork 和 execvp 启动。这一切都很好。
当 xterm(或我认为的任何应用程序)启动时,它会绘制在条形图的顶部(x = 0,y = 0)。我想将它移低一点(x = 0,y = 16)。我想我知道如何移动窗口,使用xcb_configure_window
. 但我不知道如何为新启动的应用程序获取事件。
编辑:
经过一番折腾,我得出以下结论:
如果我像这样创建父窗口:
xcb_window_t window_root = screen->root;
uint32_t mask = 0;
uint32_t values[2];
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
xcb_change_window_attributes_checked(connection, window_root, mask, values);
xcb_flush(connection);
当我生成一个新终端时,我将收到 XCB_CREATE_NOTIFY。但是,我无法在屏幕上绘制任何内容,因为我没有“订阅”该XCB_EVENT_MASK_EXPOSE
事件。如果我将 values[0] 行更改为:
values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE;
我仍然会收到创建事件,但是程序启动后不会立即调用公开事件,因此我的条不会被绘制。不过,一旦我启动一个新终端,它就会得到一个暴露事件,但我的初始绘图不会发生。
我创建父窗口的旧方法是:
xcb_window_t window = xcb_generate_id(connection);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t values[2] = {screen->white_pixel, XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY };
xcb_create_window(connection, 0, window, screen->root, 0, 0, screen->width_in_pixels, screen->height_in_pixels, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values);
xcb_map_window(connection, window);
这将绘制一个白色背景并绘制我的彩色条,因为它会立即获得 XCB_EVENT_MASK_EXPOSURE 事件。但它不会得到 XCB_CREATE_NOTIFY 事件。
那么获取 XCB_CREATE_NOTIFY 事件和 XCB_EVENT_MASK_EXPOSURE 事件的正确方法是什么?