简体   繁体   English

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

[英]How to get event when new application launches using XCB

I am trying to make a very simple window manager for learning purposes. 我正在尝试为学习目的制作一个非常简单的窗口管理器。 I am using C and the xcb library. 我正在使用Cxcb库。 I am trying to get an event raised if a new application is launched. 我正在尝试在启动新应用程序时引发事件。

For now, I create a root window where I can receive mouse and keyboard events. 现在,我创建了一个根窗口,我可以在其中接收鼠标和键盘事件。 I also draw a colored bar on the top of the window. 我还在窗户顶部画了一个彩色条。 When I press enter, xterm will launch using fork and execvp. 当我按回车键时,xterm将使用fork和execvp启动。 This all works great. 一切都很好。

When xterm (or any application I think) launches, it gets drawn on top of the bar (x = 0, y = 0). 当xterm(或我认为的任何应用程序)启动时,它会被绘制在条形图的顶部(x = 0,y = 0)。 I would like to move it a bit lower (x = 0, y = 16). 我想把它移动一点(x = 0,y = 16)。 I think I know how to move the window, using xcb_configure_window . 我想我知道如何移动窗口,使用xcb_configure_window But I don't know how to get an event for the newly launched application. 但我不知道如何为新推出的应用程序获取事件。

Edit: 编辑:
After some messing around I came to the following conclusions: 经过一番乱搞,我得出以下结论:
If I create my parent window like this: 如果我像这样创建我的父窗口:

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);

i will receive a XCB_CREATE_NOTIFY when I spawn a new terminal. 当我产生一个新终端时,我将收到一个XCB_CREATE_NOTIFY。 However, I am not able to draw anything on the screen, because I am not "subscribed" to the XCB_EVENT_MASK_EXPOSE event. 但是,我无法在屏幕上绘制任何内容,因为我没有“订阅” XCB_EVENT_MASK_EXPOSE事件。 If I change the values[0] line to this: 如果我将值[0]行更改为:

values[0] = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_EXPOSURE;

i will still receive creation events, but the expose event does not get called as soon as the program starts, so my bar will not get drawn. 我仍然会收到创建事件,但是一旦程序启动就不会调用expose事件,因此我的栏不会被绘制。 It will get an expose event as soon as I launch a new terminal though, but my initial drawing won't happen. 一旦我启动了一个新终端,它就会得到一个暴露事件,但我的初始绘图不会发生。

My old method of creating a parent window was: 我创建父窗口的旧方法是:

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);

This will draw a white background and draw my colored bar, because it immediately gets an XCB_EVENT_MASK_EXPOSURE event. 这将绘制一个白色背景并绘制我的彩色条,因为它会立即获得XCB_EVENT_MASK_EXPOSURE事件。 But it won't get an XCB_CREATE_NOTIFY event. 但它不会得到XCB_CREATE_NOTIFY事件。

So what is the correct way to get both the XCB_CREATE_NOTIFY events and the XCB_EVENT_MASK_EXPOSURE events? 那么获取XCB_CREATE_NOTIFY事件和XCB_EVENT_MASK_EXPOSURE事件的正确方法是什么?

I was being silly and I fixed it! 我很傻,我修好了!

I thought I only got expose events after I launched a new terminal. 在我推出新终端之后,我以为我只揭露了事件。 But I never even drew my bar and background before entering the event loop, I only drew them in my XCB_EXPOSE loop. 但是在进入事件循环之前我从未画过我的条形图和背景,我只是在我的XCB_EXPOSE循环中绘制它们。 So when a new terminal got launched, the expose event would get called, and my bar and background appeared. 因此,当一个新终端启动时,将调用公开事件,并显示我的条形图和背景。

Now I placed the drawing functions before my event loop as well, and everything works like it should. 现在我将绘图函数放在我的事件循环之前,一切都按照它应该的方式工作。 I don't know if this is the right/best way to go, but for future reference, use the following to create your root screen: 我不知道这是否是正确/最佳方式,但为了将来参考,请使用以下内容创建根屏幕:

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);

You will get expose events, and newly launched programs will appear in the XCB_CREATE_NOTIFY event. 您将获得公开事件,新启动的程序将出现在XCB_CREATE_NOTIFY事件中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM