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

标签 c events x11 window-managers xcb

我正在尝试制作一个非常简单的窗口管理器以供学习之用。我正在使用 Cxcb 库。我正在尝试在启动新应用程序时引发事件。

现在,我创建了一个根窗口,我可以在其中接收鼠标和键盘事件。我还在窗口的顶部画了一个彩色条。当我按下回车键时,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;

我仍然会收到创建事件,但不会在程序启动时立即调用公开事件,因此不会绘制我的栏。不过,只要我启动一个新终端,它就会收到一个 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_EVENT_MASK_EXPOSURE 事件。但它不会收到 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_CREATE_NOTIFY事件中。

关于c - 如何在使用 XCB 启动新应用程序时获取事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12904844/

相关文章:

jQuery 调度事件?如何

linux - 没有设置 X11 DISPLAY 变量,但是这个程序执行了一个需要它使用 Putty 的操作?

python - 如何在X11中捕获另一个按键事件后发送按键事件

java - Xlib:使用 XAddToChangeSet 向保存集添加窗口在 Java/JNI 中不起作用

java - 如何在 C 中实现注解?

c - x 的值是多少? x= a+++++a + a++

c - 需要处理大量定时器/超时的建议

c - 运行时不可整除循环大小对 openMP SIMD 的影响

javascript - 防止加法输入

java - 当程序处于循环状态时如何发送事件?