2012-10-15 25 views
2

我正在尝试为学习目的制作一个非常简单的窗口管理器。我正在使用Cxcb库。如果启动了一个新应用程序,我正试图获得一个事件。如何使用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事件的正确方法是什么?

+0

其中一个映射事件? –

+0

@JoachimPileborg感谢您的评论。我尝试过使用XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY,因为我在其他WM代码中阅读了类似内容,但在事件循环中从未获取任何XCB_MAP_REQUEST或XCB_MAP_NOTIFY事件。我用更多的信息更新了我的帖子。 – Carlito

+0

今年早些时候,我用Python和XCB做了一个非常简单的窗口管理器。除了'XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY',我还有'XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT'和'XCB_EVENT_MASK_STRUCTURE_NOTIFY'。 –

回答

3

我很傻,我修好了!

我以为我在发起一个新的终端后才会有暴露事件。但是我在进入事件循环之前从未画过酒吧和背景,我只是在我的XCB_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_CREATE_NOTIFY事件。

相关问题