有很多关于如何使用XLib处理窗口关闭的示例,可以在互联网上找到:
还有几个。这就是说我试图在代码中实现它们,如下所示。但是,当我点击窗口一角的X时,我没有收到任何事件发送到我的消息循环。这是因为XChcekWindowEvent
忽略或不处理客户端消息?如果不是这种情况,我应该寻找什么其他东西来使用SetWMProtocols
从XLib集中获取消息?
m_impl->m_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
if (!XSetWMProtocols(display, window, &m_impl->m_delete_window, 1)) {
std::cout << "Set Window Protocols Failed" << std::endl;
}
...
while (!terminate) {
while (::XCheckWindowEvent(display, window, events::mask, &x_event)) {
if (x_event.type == ClientMessage) {
std::cout << "Client Message" << std::endl;
if ((Atom)x_event.xclient.data.l[0] == m_impl->m_delete_window) {
terminate = true;
}
}
}
}
XCheckWindowEvent()不会返回ClientMessage。它不返回任何不可屏蔽的。解决方法:
while (XPending(display))
{
XNextEvent(display, &event);
但是可以通过窗口创建额外的工作来过滤事件。 BR Pekka
如果要防止使用XNextEvent
(不在实时事件循环中应用),可以使用以下基于XCheckTypedWindowEvent
的代码:
// Globals
Atom wm_protocols;
Atom wm_delete_window;
// Functions
void PreventClose(Display* disp, Window& win)
{
wm_protocols = XInternAtom(disp, "WM_PROTOCOLS", false);
wm_delete_window = XInternAtom(disp, "WM_DELETE_WINDOW", false);
XSetWMProtocols(disp, win, &wm_delete_window, 1);
}
bool IsClosed(Display* disp, Window& win)
{
XEvent e;
if (XCheckTypedWindowEvent(disp, win, ClientMessage, &e))
if (e.xclient.message_type == wm_protocols &&
e.xclient.data.l[0] == wm_delete_window_)
return true;
return false;
}
// Usage
int main()
{
...
PreventClose(disp, win);
do {
if (IsClosed(disp, win))
// break, some actions, etc...
...
} while(true);
return 0;
}
有关更多信息,请参阅man 3 XCheckTypedWindowEvent