如何在使用XCB启动新应用程序时获取事件

如何在使用XCB启动新应用程序时获取事件,c,events,x11,window-managers,xcb,C,Events,X11,Window Managers,Xcb,为了学习,我正在尝试制作一个非常简单的窗口管理器。我正在使用C和xcb库。如果启动了新的应用程序,我将尝试引发一个事件 现在,我创建了一个根窗口,可以在其中接收鼠标和键盘事件。我还在窗户的顶部画了一个彩色条。当我按enter键时,xterm将使用fork和execvp启动。这一切都很好 当xterm(或我认为的任何应用程序)启动时,它会被绘制在条的顶部(x=0,y=0)。我想把它移低一点(x=0,y=16)。我想我知道如何使用xcb\u configure\u window移动窗口。但我不知道如

为了学习,我正在尝试制作一个非常简单的窗口管理器。我正在使用
C
xcb
库。如果启动了新的应用程序,我将尝试引发一个事件

现在,我创建了一个根窗口,可以在其中接收鼠标和键盘事件。我还在窗户的顶部画了一个彩色条。当我按enter键时,xterm将使用fork和execvp启动。这一切都很好

当xterm(或我认为的任何应用程序)启动时,它会被绘制在条的顶部(x=0,y=0)。我想把它移低一点(x=0,y=16)。我想我知道如何使用
xcb\u configure\u 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_通知。但是,我无法在屏幕上绘制任何内容,因为我没有“订阅”
XCB\u事件\u MASK\u EXPOSE
事件。如果我将值[0]行更改为:

values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE;
我仍将接收创建事件,但程序启动后不会立即调用expose事件,因此不会绘制我的条形图。不过,一旦我启动一个新的终端,它就会得到一个曝光事件,但我的初始绘图不会发生

我以前创建父窗口的方法是:

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_事件\u掩码\u曝光事件。但它不会得到XCB_CREATE_NOTIFY事件


那么,获得XCB_CREATE_NOTIFY事件和XCB_EVENT_MASK_EXPOSURE事件的正确方法是什么呢?

我太傻了,我修复了它

我以为只有在我启动了一个新的终端后,我才得到曝光事件。但在进入事件循环之前,我甚至从未画过我的条形图和背景,我只在我的
XCB_EXPOSE
循环中画过它们。因此,当一个新终端启动时,expose事件将被调用,我的工具栏和背景出现

现在,我将绘图函数也放在事件循环之前,一切正常。我不知道这是否是正确/最好的方法,但为了将来参考,请使用以下方法创建根屏幕:

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\u CREATE\u NOTIFY
事件中。

@JoachimPileborg感谢您的评论。我尝试使用XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,因为我在其他WM的代码中读到了类似的内容,但在我的事件循环中从未收到任何XCB_MAP_请求或XCB_MAP_NOTIFY事件。今年早些时候,我用Python和XCB制作了一个非常简单的窗口管理器。除了
XCB\u EVENT\u MASK\u SUBSTRUCTURE\u NOTIFY
之外,我还有
XCB\u EVENT\u MASK\u SUBSTRUCTURE\u REDIRECT
XCB\u EVENT\u MASK\u STRUCTURE\u NOTIFY。您刚刚将它们添加到父窗口的掩码中?我现在这样做没有结果。也许我需要一种不同的方式来产生一个新的终端?我有机会看到你的代码吗?我有根窗口的所有代码。@JoachimPileborg我现在在
XCB\u EVENT\u MASK\u SUBSTRUCTURE\u NOTIFY
方面取得了一些成功,但我不会得到暴露事件。这取决于我如何创建我的根窗口。我用一些代码更新了我的帖子。如何创建根窗口?例如,捕获公开事件时,事件循环是什么样子的?