diff src/video/x11/SDL_x11video.c @ 4559:f8c3870af5a2

Fixed X11 error when running under window managers that don't support the _NET_SUPPORTING_WM_CHECK protocol.
author Sam Lantinga <slouken@libsdl.org>
date Tue, 20 Jul 2010 00:57:01 -0700
parents a956a315fe67
children c24ba2cc9583
line wrap: on
line diff
--- 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