2015-06-28 4 views
2

Есть много примеров о том, как обращаться с закрытием окна с помощью Xlib, который можно найти в Интернете:XLib: Windows Менеджер не Отправка сообщений клиента после вызова XSetWMProtocols

Есть еще несколько. Тем не менее я попытался реализовать их в коде, как показано ниже. Однако, когда я нажимаю на X в углу окна, я не получаю никакого события, отправленного в мой цикл сообщений. Это потому, что XChcekWindowEvent игнорирует или не обрабатывает сообщения клиента? Если это не так, то какие другие вещи я должен искать, чтобы получать сообщения из набора XLib, используя SetWMProtocols?

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