XCB_POLL_FOR_EVENT未检测到关闭窗口的XCB_CLIENT_MESSAGE事件
xcb_poll_for_event does not detect XCB_CLIENT_MESSAGE event for closing window
我正在将应用程序移植到Linux,并且我正在使用XCB库进行窗口处理。我需要检测窗口何时关闭,以便应用程序可以退出。但是,由于系统的设计方式,系统无法阻止主窗口循环。这在Windows中很容易,因为您只使用PeekMessage
。但是,当我尝试使用xcb_poll_for_event
检测XCB_CLIENT_MESSAGE
时,XCB似乎不起作用。当我尝试注入WM_DELETE_WINDOW
协议时,窗口上的关闭按钮实际上没有功能。
窗口设置:
// initialize XCB
this->connection = xcb_connect(NULL, NULL);
this->screen = xcb_setup_roots_iterator(xcb_get_setup(this->connection)).data;;
// create window
u32 mask = 0;
u32 values[1];
this->window = xcb_generate_id(this->connection);
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_EXPOSURE;
xcb_create_window(this->connection, 0, this->window, this->screen->root, 0, 0, width, height, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, this->screen->root_visual, mask, values);
// setup close handler event
xcb_intern_atom_cookie_t protocolCookie = xcb_intern_atom_unchecked(this->connection, 1, 12, "WM_PROTOCOLS");
xcb_intern_atom_reply_t* protocolReply = xcb_intern_atom_reply(this->connection, protocolCookie, 0);
xcb_intern_atom_cookie_t closeCookie = xcb_intern_atom_unchecked(this->connection, 0, 16, "WM_DELETE_WINDOW");
this->m_closeReply = xcb_intern_atom_reply(this->connection, closeCookie, 0);
xcb_change_property(this->connection, XCB_PROP_MODE_REPLACE, this->window, protocolReply->atom, 4, 32, 1, &(this->m_closeReply->atom));
free(protocolReply);
// map and flush
xcb_map_window(this->connection, this->window);
xcb_flush(this->connection);
消息循环:
// handle all incoming messages
xcb_generic_event_t* e;
while(e = xcb_poll_for_event(connection))
{
// take action from message
switch(e->response_type & ~0x80)
{
case XCB_EXPOSE:
// invalidated
xcb_flush(connection);
break;
case XCB_CLIENT_MESSAGE:
// close window
if(((xcb_client_message_event_t*)e)->data.data32[0] == (*this->m_closeReply).atom)
return false;
break;
}
// cleanup
free(e);
}
窗口关闭时,当我用xcb_wait_for_event
替换xcb_poll_for_event
时,窗口关闭的作品是完美的,但是在等待消息时,窗口循环被阻止。我只需要知道我在使用xcb_poll_for_event
时永远不会检测到的事件。
来自XCB教程
注意:一个常见的错误程序员确实是添加代码以处理其程序中的新事件类型,同时忘记在创建窗口中为这些事件添加蒙版。这样的程序员应该坐下几个小时来调试他的程序,想知道"为什么我的程序不通知我发布了按钮?"只是为了发现他们注册了按钮按下按钮事件,但没有用于按钮发布事件。<<<<<。/p>
和您的代码
mask = XCB_CW_EVENT_MASK;
values[0] = XCB_EVENT_MASK_EXPOSURE;
xcb_create_window(
this->connection,
0,
this->window,
this->screen->root,
0, 0,
width, height,
0,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
this->screen->root_visual,
mask, values // <--
);
您已经告诉X服务器仅向您发送某些事件,而您忽略了包括XCB_EVENT_MASK_STRUCTURE_NOTIFY
。
- values[0] = XCB_EVENT_MASK_EXPOSURE;
+ values[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY;
相关文章:
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 问:如何使用C++中的按钮从窗口打开窗口
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 处理闪烁窗口事件
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- C++win32 API创建多个类似视口的窗口
- SFML RenderWindow打开窗口需要很长时间
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 获取 SFML 窗口的 HWND 和高可用性?
- 如何获取 GLFW 窗口 ID?
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 用于窗口的 HID 终端
- SFML 文本未绘制在窗口上
- 如何为窗口截屏
- 使用XCB获取活动窗口的宽度