我正在尝试为学习目的制作一个非常简单的窗口管理器。我正在使用C
和xcb
库。如果启动了一个新应用程序,我正试图获得一个事件。如何使用XCB启动新应用程序时获取事件
现在,我创建一个可以接收鼠标和键盘事件的根窗口。我还在窗口的顶部画一条彩条。当我按下Enter时,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
事件。如果我改变值[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事件的正确方法是什么?
其中一个映射事件? –
@JoachimPileborg感谢您的评论。我尝试过使用XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,因为我在其他WM代码中阅读了类似内容,但在事件循环中从未获取任何XCB_MAP_REQUEST或XCB_MAP_NOTIFY事件。我用更多的信息更新了我的帖子。 – Carlito
今年早些时候,我用Python和XCB做了一个非常简单的窗口管理器。除了'XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY',我还有'XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT'和'XCB_EVENT_MASK_STRUCTURE_NOTIFY'。 –