X11: Handle _NET_WM_PING protocol, so window manager knows when app is hung up.

This commit is contained in:
Ryan C. Gordon 2012-11-02 15:22:37 -04:00
parent d7d06ad754
commit dbbd206084
4 changed files with 34 additions and 2 deletions

View file

@ -387,10 +387,34 @@ X11_DispatchEvent(_THIS)
/* Have we been requested to quit (or another client message?) */
case ClientMessage:{
if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
(xevent.xclient.format == 32) &&
(xevent.xclient.data.l[0] == videodata->_NET_WM_PING)) {
SDL_DisplayData *dpydata;
Window root;
#ifdef DEBUG_XEVENTS
printf("window %p: _NET_WM_PING\n", data);
#endif
dpydata = (SDL_DisplayData *)
SDL_GetDisplayForWindow(data->window);
root = RootWindow(display, dpydata->screen);
xevent.xclient.window = root;
XSendEvent(display, root, False, SubstructureRedirectMask | SubstructureNotifyMask, &xevent);
break;
}
else if ((xevent.xclient.message_type == videodata->WM_PROTOCOLS) &&
(xevent.xclient.format == 32) &&
(xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW)) {
#ifdef DEBUG_XEVENTS
printf("window %p: WM_DELETE_WINDOW\n", data);
#endif
SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_CLOSE, 0, 0);
break;
}
}
break;

View file

@ -383,6 +383,7 @@ X11_VideoInit(_THIS)
GET_ATOM(_NET_WM_NAME);
GET_ATOM(_NET_WM_ICON_NAME);
GET_ATOM(_NET_WM_ICON);
GET_ATOM(_NET_WM_PING);
GET_ATOM(UTF8_STRING);
/* Detect the window manager */

View file

@ -93,6 +93,7 @@ typedef struct SDL_VideoData
Atom _NET_WM_NAME;
Atom _NET_WM_ICON_NAME;
Atom _NET_WM_ICON;
Atom _NET_WM_PING;
Atom UTF8_STRING;
SDL_Scancode key_layout[256];

View file

@ -536,8 +536,14 @@ X11_CreateWindow(_THIS, SDL_Window * window)
PropModeReplace,
(unsigned char *)&_NET_WM_WINDOW_TYPE_NORMAL, 1);
/* Allow the window to be deleted by the window manager */
XSetWMProtocols(display, w, &data->WM_DELETE_WINDOW, 1);
{
Atom protocols[] = {
data->WM_DELETE_WINDOW, /* Allow window to be deleted by the WM */
data->_NET_WM_PING, /* Respond so WM knows we're alive */
};
XSetWMProtocols(display, w, protocols, sizeof (protocols) / sizeof (protocols[0]));
}
if (SetupWindowData(_this, window, w, SDL_TRUE) < 0) {
XDestroyWindow(display, w);