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 4559f8c3870af5a2
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
     1.1 --- a/src/video/x11/SDL_x11video.c	Tue Jul 20 00:05:32 2010 -0700
     1.2 +++ b/src/video/x11/SDL_x11video.c	Tue Jul 20 00:57:01 2010 -0700
     1.3 @@ -241,6 +241,16 @@
     1.4      X11_Available, X11_CreateDevice
     1.5  };
     1.6  
     1.7 +static int (*handler) (Display *, XErrorEvent *) = NULL;
     1.8 +static int
     1.9 +X11_CheckWindowManagerErrorHandler(Display * d, XErrorEvent * e)
    1.10 +{
    1.11 +    if (e->error_code == BadWindow) {
    1.12 +        return (0);
    1.13 +    } else {
    1.14 +        return (handler(d, e));
    1.15 +    }
    1.16 +}
    1.17  
    1.18  static void
    1.19  X11_CheckWindowManager(_THIS)
    1.20 @@ -257,12 +267,32 @@
    1.21      char *wm_name;
    1.22  #endif
    1.23  
    1.24 +    /* Set up a handler to gracefully catch errors */
    1.25 +    XSync(display, False);
    1.26 +    handler = XSetErrorHandler(X11_CheckWindowManagerErrorHandler);
    1.27 +
    1.28      _NET_SUPPORTING_WM_CHECK = XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", False);
    1.29      status = XGetWindowProperty(display, DefaultRootWindow(display), _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
    1.30      if (status == Success && items_read) {
    1.31          wm_window = ((Window*)propdata)[0];
    1.32      }
    1.33 -    XFree(propdata);
    1.34 +    if (propdata) {
    1.35 +        XFree(propdata);
    1.36 +    }
    1.37 +
    1.38 +    if (wm_window) {
    1.39 +        status = XGetWindowProperty(display, wm_window, _NET_SUPPORTING_WM_CHECK, 0L, 1L, False, XA_WINDOW, &real_type, &real_format, &items_read, &items_left, &propdata);
    1.40 +        if (status != Success || !items_read || wm_window != ((Window*)propdata)[0]) {
    1.41 +            wm_window = None;
    1.42 +        }
    1.43 +        if (propdata) {
    1.44 +            XFree(propdata);
    1.45 +        }
    1.46 +    }
    1.47 +
    1.48 +    /* Reset the error handler, we're done checking */
    1.49 +    XSync(display, False);
    1.50 +    XSetErrorHandler(handler);
    1.51  
    1.52      if (!wm_window) {
    1.53  #ifdef DEBUG_WINDOW_MANAGER