X11: Handle _NET_WM_PING protocol, so window manager knows when app is hung up.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 02 Nov 2012 15:22:37 -0400
changeset 6638 3d221da309d3
parent 6637 31e3f5b04120
child 6639 c7e81fae23c4
X11: Handle _NET_WM_PING protocol, so window manager knows when app is hung up.
src/video/x11/SDL_x11events.c
src/video/x11/SDL_x11video.c
src/video/x11/SDL_x11video.h
src/video/x11/SDL_x11window.c
--- a/src/video/x11/SDL_x11events.c	Fri Nov 02 14:15:21 2012 -0400
+++ b/src/video/x11/SDL_x11events.c	Fri Nov 02 15:22:37 2012 -0400
@@ -388,9 +388,33 @@
     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;
--- a/src/video/x11/SDL_x11video.c	Fri Nov 02 14:15:21 2012 -0400
+++ b/src/video/x11/SDL_x11video.c	Fri Nov 02 15:22:37 2012 -0400
@@ -383,6 +383,7 @@
     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 */
--- a/src/video/x11/SDL_x11video.h	Fri Nov 02 14:15:21 2012 -0400
+++ b/src/video/x11/SDL_x11video.h	Fri Nov 02 15:22:37 2012 -0400
@@ -93,6 +93,7 @@
     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];
--- a/src/video/x11/SDL_x11window.c	Fri Nov 02 14:15:21 2012 -0400
+++ b/src/video/x11/SDL_x11window.c	Fri Nov 02 15:22:37 2012 -0400
@@ -536,8 +536,14 @@
                     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);