2015-06-28 40 views
2

有關於如何處理窗口的使用XLIB收盤時,其可以在互聯網上找到許多例子:XLIB:調用XSetWMProtocols後窗口管理器不發送客戶端消息

還有幾個。這就是說我試圖在代碼中實現它們,如下所示。但是當我點擊窗口一角的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; 
     } 
    } 
    } 
} 

回答

2

XCheckWindowEvent()不會返回ClientMessage。它不返回任何不可屏蔽的。解決辦法:

while (XPending(display)) 
{ 
    XNextEvent(display, &event); 

但是可以創建額外的工作來按窗口過濾事件。 BR佩卡

0

如果要防止使用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

相關問題