Fixed X11 error when running under window managers that don't support the _NET_SUPPORTING_WM_CHECK protocol.
authorSam Lantinga <slouken@libsdl.org>
Tue, 20 Jul 2010 00:57:01 -0700
changeset 4559 f8c3870af5a2
parent 4558 4d95152d9e39
child 4560 95352c671a6e
Fixed X11 error when running under window managers that don't support the _NET_SUPPORTING_WM_CHECK protocol.
src/video/x11/SDL_x11video.c
--- a/src/video/x11/SDL_x11video.c	Tue Jul 20 00:05:32 2010 -0700
+++ b/src/video/x11/SDL_x11video.c	Tue Jul 20 00:57:01 2010 -0700
@@ -241,6 +241,16 @@
     X11_Available, X11_CreateDevice
 };
 
+static int (*handler) (Display *, XErrorEvent *) = NULL;
+static int
+X11_CheckWindowManagerErrorHandler(Display * d, XErrorEvent * e)
+{
+    if (e->error_code == BadWindow) {
+        return (0);
+    } else {
+        return (handler(d, e));
+    }
+}
 
 static void
 X11_CheckWindowManager(_THIS)
@@ -257,12 +267,32 @@
     char *wm_name;
 #endif
 
+    /* Set up a handler to gracefully catch errors */
+    XSync(display, False);
+    handler = XSetErrorHandler(X11_CheckWindowManagerErrorHandler);
+
     _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
     status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
     if (status == Success && items_read) {
         wm_window = ((Window*)propdata)[0];
     }
-    XFree(propdata);
+    if (propdata) {
+        XFree(propdata);
+    }
+
+    if (wm_window) {
+        status = XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
+        if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) {
+            wm_window = None;
+        }
+        if (propdata) {
+            XFree(propdata);
+        }
+    }
+
+    /* Reset the error handler, we're done checking */
+    XSync(display, False);
+    XSetErrorHandler(handler);
 
     if (!wm_window) {
 #ifdef DEBUG_WINDOW_MANAGER