src/video/x11/SDL_x11window.c
changeset 6480 d02a4369b3f5
parent 6479 388318faf0fb
child 6481 fab4b15b17e9
     1.1 --- a/src/video/x11/SDL_x11window.c	Thu Sep 27 14:38:56 2012 -0700
     1.2 +++ b/src/video/x11/SDL_x11window.c	Thu Sep 27 17:17:33 2012 -0700
     1.3 @@ -54,7 +54,15 @@
     1.4  }
     1.5  static Bool isConfigureNotify(Display *dpy, XEvent *ev, XPointer win)
     1.6  {
     1.7 -    return ev->type == ConfigureNotify && ev->xunmap.window == *((Window*)win);
     1.8 +    return ev->type == ConfigureNotify && ev->xconfigure.window == *((Window*)win);
     1.9 +}
    1.10 +static Bool isFocusIn(Display *dpy, XEvent *ev, XPointer win)
    1.11 +{
    1.12 +    return ev->type == FocusIn && ev->xfocus.window == *((Window*)win);
    1.13 +}
    1.14 +static Bool isFocusOut(Display *dpy, XEvent *ev, XPointer win)
    1.15 +{
    1.16 +    return ev->type == FocusOut && ev->xfocus.window == *((Window*)win);
    1.17  }
    1.18  
    1.19  static SDL_bool
    1.20 @@ -1002,13 +1010,6 @@
    1.21  
    1.22      X11_GetDisplayBounds(_this, _display, &rect);
    1.23  
    1.24 -    /* Ungrab the input so that we can move the mouse around */
    1.25 -    XUngrabPointer(display, CurrentTime);
    1.26 -
    1.27 -    #if SDL_VIDEO_DRIVER_X11_XINERAMA
    1.28 -    /* !!! FIXME: there was some Xinerama code in 1.2 here to set x,y to the origin of a specific screen. */
    1.29 -    #endif
    1.30 -
    1.31      SDL_zero(xattr);
    1.32      xattr.override_redirect = True;
    1.33      xattrmask |= CWOverrideRedirect;
    1.34 @@ -1025,11 +1026,12 @@
    1.35                                     visual, xattrmask, &xattr);
    1.36  
    1.37      XSelectInput(display, data->fswindow, StructureNotifyMask);
    1.38 -
    1.39      XSetWindowBackground(display, data->fswindow, 0);
    1.40      XClearWindow(display, data->fswindow);
    1.41 +    XMapRaised(display, data->fswindow);
    1.42  
    1.43 -    XMapRaised(display, data->fswindow);
    1.44 +    /* Make sure the fswindow is in view by warping mouse to the corner */
    1.45 +    XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
    1.46  
    1.47      /* Wait to be mapped, filter Unmap event out if it arrives. */
    1.48      XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->fswindow);
    1.49 @@ -1040,22 +1042,14 @@
    1.50          XF86VidModeLockModeSwitch(display, screen, True);
    1.51      }
    1.52  #endif
    1.53 -
    1.54      XInstallColormap(display, data->colormap);
    1.55  
    1.56      SetWindowBordered(display, displaydata->screen, data->xwindow, SDL_FALSE);
    1.57 -    XFlush(display);
    1.58 -    //XIfEvent(display, &ev, &isConfigureNotify, (XPointer)&data->xwindow);
    1.59  
    1.60      /* Center actual window within our cover-the-screen window. */
    1.61      rect.x += (rect.w - window->w) / 2;
    1.62      rect.y += (rect.h - window->h) / 2;
    1.63      XReparentWindow(display, data->xwindow, data->fswindow, rect.x, rect.y);
    1.64 -    XRaiseWindow(display, data->xwindow);
    1.65 -
    1.66 -    /* Make sure the fswindow is in view by warping mouse to the corner */
    1.67 -    XWarpPointer(display, None, root, 0, 0, 0, 0, 0, 0);
    1.68 -    XFlush(display);
    1.69  
    1.70      /* Center mouse in the window. */
    1.71      rect.x += (window->w / 2);
    1.72 @@ -1063,25 +1057,14 @@
    1.73      XWarpPointer(display, None, root, 0, 0, 0, 0, rect.x, rect.y);
    1.74  
    1.75      /* Wait to be mapped, filter Unmap event out if it arrives. */
    1.76 -    XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
    1.77      XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
    1.78 +    XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
    1.79  
    1.80 -    /* Wait to be visible, or XSetInputFocus() triggers an X error. */
    1.81 -    while (SDL_TRUE) {
    1.82 -        XWindowAttributes attr;
    1.83 -        XSync(display, False);
    1.84 -        XGetWindowAttributes(display, data->xwindow, &attr);
    1.85 -        if (attr.map_state == IsViewable)
    1.86 -            break;
    1.87 -    }
    1.88 -
    1.89 -    XSetInputFocus(display, data->xwindow, RevertToParent, CurrentTime);
    1.90 +    /* Set the input focus because we're about to grab input */
    1.91      window->flags |= SDL_WINDOW_INPUT_FOCUS;
    1.92      SDL_SetKeyboardFocus(data->window);
    1.93  
    1.94      X11_SetWindowGrab(_this, window);
    1.95 -
    1.96 -    XSync(display, False);
    1.97  }
    1.98  
    1.99  static void
   1.100 @@ -1092,12 +1075,14 @@
   1.101      Display *display = data->videodata->display;
   1.102      const int screen = displaydata->screen;
   1.103      Window root = RootWindow(display, screen);
   1.104 +    Window fswindow = data->fswindow;
   1.105      XEvent ev;
   1.106  
   1.107 -    if (!data->fswindow)
   1.108 +    if (!data->fswindow) {
   1.109          return;  /* already not fullscreen, I hope. */
   1.110 +    }
   1.111  
   1.112 -    XReparentWindow(display, data->xwindow, root, window->x, window->y);
   1.113 +    data->fswindow = None;
   1.114  
   1.115  #if SDL_VIDEO_DRIVER_X11_VIDMODE
   1.116      if ( displaydata->use_vidmode ) {
   1.117 @@ -1105,24 +1090,22 @@
   1.118      }
   1.119  #endif
   1.120  
   1.121 -    XUnmapWindow(display, data->fswindow);
   1.122 -    /* Wait to be unmapped. */
   1.123 -    XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->fswindow);
   1.124 -    XDestroyWindow(display, data->fswindow);
   1.125 -    data->fswindow = 0;
   1.126 +    X11_SetWindowGrab(_this, window);
   1.127  
   1.128 -    /* catch these events so we know the window is back in business. */
   1.129 +    XReparentWindow(display, data->xwindow, root, window->x, window->y);
   1.130 +
   1.131 +    /* flush these events so they don't confuse normal event handling */
   1.132      XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
   1.133      XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
   1.134  
   1.135 -    XSync(display, True);   /* Flush spurious mode change events */
   1.136 -
   1.137 -    X11_SetWindowGrab(_this, window);
   1.138 -
   1.139      SetWindowBordered(display, screen, data->xwindow,
   1.140                        (window->flags & SDL_WINDOW_BORDERLESS) == 0);
   1.141  
   1.142 -    XFlush(display);
   1.143 +    XUnmapWindow(display, fswindow);
   1.144 +
   1.145 +    /* Wait to be unmapped. */
   1.146 +    XIfEvent(display, &ev, &isUnmapNotify, (XPointer)&fswindow);
   1.147 +    XDestroyWindow(display, fswindow);
   1.148  }
   1.149  
   1.150  
   1.151 @@ -1241,6 +1224,8 @@
   1.152  
   1.153      if (((window->flags & SDL_WINDOW_INPUT_GRABBED) || oldstyle_fullscreen)
   1.154          && (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
   1.155 +        XEvent ev;
   1.156 +
   1.157          /* Try to grab the mouse */
   1.158          for (;;) {
   1.159              int result =
   1.160 @@ -1258,6 +1243,11 @@
   1.161          /* Now grab the keyboard */
   1.162          XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
   1.163                        GrabModeAsync, CurrentTime);
   1.164 +
   1.165 +        /* flush these events so they don't confuse normal event handling */
   1.166 +        XSync(display, False);
   1.167 +        XIfEvent(display, &ev, &isFocusIn, (XPointer)&data->xwindow);
   1.168 +        XIfEvent(display, &ev, &isFocusOut, (XPointer)&data->xwindow);
   1.169      } else {
   1.170          XUngrabPointer(display, CurrentTime);
   1.171          XUngrabKeyboard(display, CurrentTime);