SDL no longer grabs the keyboard by default on X11.
authorSam Lantinga <slouken@libsdl.org>
Wed, 07 Nov 2012 15:55:43 -0800
changeset 6662698c2e533a7e
parent 6661 cd8befc0a969
child 6663 2cbffb5aa19d
SDL no longer grabs the keyboard by default on X11.
You can re-enable that functionality by setting a new hint SDL_HINT_GRAB_KEYBOARD
include/SDL_hints.h
src/video/SDL_sysvideo.h
src/video/SDL_video.c
src/video/bwindow/SDL_bwindow.cc
src/video/bwindow/SDL_bwindow.h
src/video/cocoa/SDL_cocoawindow.h
src/video/cocoa/SDL_cocoawindow.m
src/video/windows/SDL_windowswindow.c
src/video/windows/SDL_windowswindow.h
src/video/x11/SDL_x11window.c
src/video/x11/SDL_x11window.h
     1.1 --- a/include/SDL_hints.h	Wed Nov 07 11:13:28 2012 -0800
     1.2 +++ b/include/SDL_hints.h	Wed Nov 07 15:55:43 2012 -0800
     1.3 @@ -153,6 +153,17 @@
     1.4  #define SDL_HINT_VIDEO_X11_XRANDR           "SDL_VIDEO_X11_XRANDR"
     1.5  
     1.6  /**
     1.7 + *  \brief  A variable controlling whether grabbing input grabs the keyboard
     1.8 + *
     1.9 + *  This variable can be set to the following values:
    1.10 + *    "0"       - Grab will affect only the mouse
    1.11 + *    "1"       - Grab will affect mouse and keyboard
    1.12 + *
    1.13 + *  By default SDL will not grab the keyboard so system shortcuts still work.
    1.14 + */
    1.15 +#define SDL_HINT_GRAB_KEYBOARD              "SDL_GRAB_KEYBOARD"
    1.16 +
    1.17 +/**
    1.18   *  \brief  A variable controlling whether the idle timer is disabled on iOS.
    1.19   *
    1.20   *  When an iOS app does not receive touches for some time, the screen is
     2.1 --- a/src/video/SDL_sysvideo.h	Wed Nov 07 11:13:28 2012 -0800
     2.2 +++ b/src/video/SDL_sysvideo.h	Wed Nov 07 15:55:43 2012 -0800
     2.3 @@ -191,7 +191,7 @@
     2.4      void (*SetWindowFullscreen) (_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
     2.5      int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp);
     2.6      int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp);
     2.7 -    void (*SetWindowGrab) (_THIS, SDL_Window * window);
     2.8 +    void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed);
     2.9      void (*DestroyWindow) (_THIS, SDL_Window * window);
    2.10      int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch);
    2.11      int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, SDL_Rect * rects, int numrects);
    2.12 @@ -364,6 +364,7 @@
    2.13  extern void SDL_OnWindowRestored(SDL_Window * window);
    2.14  extern void SDL_OnWindowFocusGained(SDL_Window * window);
    2.15  extern void SDL_OnWindowFocusLost(SDL_Window * window);
    2.16 +extern void SDL_UpdateWindowGrab(SDL_Window * window);
    2.17  extern SDL_Window * SDL_GetFocusWindow(void);
    2.18  
    2.19  #endif /* _SDL_sysvideo_h */
     3.1 --- a/src/video/SDL_video.c	Wed Nov 07 11:13:28 2012 -0800
     3.2 +++ b/src/video/SDL_video.c	Wed Nov 07 15:55:43 2012 -0800
     3.3 @@ -1850,11 +1850,18 @@
     3.4      return 0;
     3.5  }
     3.6  
     3.7 -static void
     3.8 +void
     3.9  SDL_UpdateWindowGrab(SDL_Window * window)
    3.10  {
    3.11 -    if ((window->flags & SDL_WINDOW_INPUT_FOCUS) && _this->SetWindowGrab) {
    3.12 -        _this->SetWindowGrab(_this, window);
    3.13 +    if (_this->SetWindowGrab) {
    3.14 +        SDL_bool grabbed;
    3.15 +        if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
    3.16 +            (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
    3.17 +            grabbed = SDL_TRUE;
    3.18 +        } else {
    3.19 +            grabbed = SDL_FALSE;
    3.20 +        }
    3.21 +        _this->SetWindowGrab(_this, window, grabbed);
    3.22      }
    3.23  }
    3.24  
    3.25 @@ -1924,10 +1931,7 @@
    3.26          _this->SetWindowGammaRamp(_this, window, window->gamma);
    3.27      }
    3.28  
    3.29 -    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) &&
    3.30 -        _this->SetWindowGrab) {
    3.31 -        _this->SetWindowGrab(_this, window);
    3.32 -    }
    3.33 +    SDL_UpdateWindowGrab(window);
    3.34  }
    3.35  
    3.36  void
    3.37 @@ -1937,10 +1941,7 @@
    3.38          _this->SetWindowGammaRamp(_this, window, window->saved_gamma);
    3.39      }
    3.40  
    3.41 -    if ((window->flags & (SDL_WINDOW_INPUT_GRABBED | SDL_WINDOW_FULLSCREEN)) &&
    3.42 -        _this->SetWindowGrab) {
    3.43 -        _this->SetWindowGrab(_this, window);
    3.44 -    }
    3.45 +    SDL_UpdateWindowGrab(window);
    3.46  
    3.47      /* If we're fullscreen on a single-head system and lose focus, minimize */
    3.48      if ((window->flags & SDL_WINDOW_FULLSCREEN) && _this->num_displays == 1) {
     4.1 --- a/src/video/bwindow/SDL_bwindow.cc	Wed Nov 07 11:13:28 2012 -0800
     4.2 +++ b/src/video/bwindow/SDL_bwindow.cc	Wed Nov 07 15:55:43 2012 -0800
     4.3 @@ -195,7 +195,7 @@
     4.4  }
     4.5  
     4.6  
     4.7 -void BE_SetWindowGrab(_THIS, SDL_Window * window) {
     4.8 +void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) {
     4.9  	/* TODO: Implement this! */
    4.10  }
    4.11  
     5.1 --- a/src/video/bwindow/SDL_bwindow.h	Wed Nov 07 11:13:28 2012 -0800
     5.2 +++ b/src/video/bwindow/SDL_bwindow.h	Wed Nov 07 15:55:43 2012 -0800
     5.3 @@ -42,7 +42,7 @@
     5.4  extern void BE_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
     5.5  extern int BE_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
     5.6  extern int BE_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
     5.7 -extern void BE_SetWindowGrab(_THIS, SDL_Window * window);
     5.8 +extern void BE_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
     5.9  extern void BE_DestroyWindow(_THIS, SDL_Window * window);
    5.10  extern SDL_bool BE_GetWindowWMInfo(_THIS, SDL_Window * window,
    5.11                                      struct SDL_SysWMinfo *info);
     6.1 --- a/src/video/cocoa/SDL_cocoawindow.h	Wed Nov 07 11:13:28 2012 -0800
     6.2 +++ b/src/video/cocoa/SDL_cocoawindow.h	Wed Nov 07 15:55:43 2012 -0800
     6.3 @@ -106,7 +106,7 @@
     6.4  extern void Cocoa_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
     6.5  extern int Cocoa_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
     6.6  extern int Cocoa_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
     6.7 -extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window);
     6.8 +extern void Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
     6.9  extern void Cocoa_DestroyWindow(_THIS, SDL_Window * window);
    6.10  extern SDL_bool Cocoa_GetWindowWMInfo(_THIS, SDL_Window * window,
    6.11                                        struct SDL_SysWMinfo *info);
     7.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Wed Nov 07 11:13:28 2012 -0800
     7.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Wed Nov 07 15:55:43 2012 -0800
     7.3 @@ -992,11 +992,10 @@
     7.4  }
     7.5  
     7.6  void
     7.7 -Cocoa_SetWindowGrab(_THIS, SDL_Window * window)
     7.8 +Cocoa_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
     7.9  {
    7.10      /* Move the cursor to the nearest point in the window */
    7.11 -    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
    7.12 -        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
    7.13 +    if (grabbed) {
    7.14          int x, y;
    7.15          CGPoint cgpoint;
    7.16  
     8.1 --- a/src/video/windows/SDL_windowswindow.c	Wed Nov 07 11:13:28 2012 -0800
     8.2 +++ b/src/video/windows/SDL_windowswindow.c	Wed Nov 07 15:55:43 2012 -0800
     8.3 @@ -538,12 +538,11 @@
     8.4  }
     8.5  
     8.6  void
     8.7 -WIN_SetWindowGrab(_THIS, SDL_Window * window)
     8.8 +WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
     8.9  {
    8.10      HWND hwnd = ((SDL_WindowData *) window->driverdata)->hwnd;
    8.11  
    8.12 -    if ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
    8.13 -        (window->flags & SDL_WINDOW_INPUT_FOCUS)) {
    8.14 +    if (grabbed) {
    8.15          RECT rect;
    8.16          GetClientRect(hwnd, &rect);
    8.17          ClientToScreen(hwnd, (LPPOINT) & rect);
     9.1 --- a/src/video/windows/SDL_windowswindow.h	Wed Nov 07 11:13:28 2012 -0800
     9.2 +++ b/src/video/windows/SDL_windowswindow.h	Wed Nov 07 15:55:43 2012 -0800
     9.3 @@ -52,7 +52,7 @@
     9.4  extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
     9.5  extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
     9.6  extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp);
     9.7 -extern void WIN_SetWindowGrab(_THIS, SDL_Window * window);
     9.8 +extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
     9.9  extern void WIN_DestroyWindow(_THIS, SDL_Window * window);
    9.10  extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window,
    9.11                                      struct SDL_SysWMinfo *info);
    10.1 --- a/src/video/x11/SDL_x11window.c	Wed Nov 07 11:13:28 2012 -0800
    10.2 +++ b/src/video/x11/SDL_x11window.c	Wed Nov 07 15:55:43 2012 -0800
    10.3 @@ -22,6 +22,7 @@
    10.4  
    10.5  #if SDL_VIDEO_DRIVER_X11
    10.6  
    10.7 +#include "SDL_hints.h"
    10.8  #include "../SDL_sysvideo.h"
    10.9  #include "../SDL_pixels_c.h"
   10.10  #include "../../events/SDL_keyboard_c.h"
   10.11 @@ -1089,7 +1090,7 @@
   10.12      XIfEvent(display, &ev, &isMapNotify, (XPointer)&data->xwindow);
   10.13      XCheckIfEvent(display, &ev, &isUnmapNotify, (XPointer)&data->xwindow);
   10.14  
   10.15 -    X11_SetWindowGrab(_this, window);
   10.16 +    SDL_UpdateWindowGrab(window);
   10.17  }
   10.18  
   10.19  static void
   10.20 @@ -1115,7 +1116,7 @@
   10.21      }
   10.22  #endif
   10.23  
   10.24 -    X11_SetWindowGrab(_this, window);
   10.25 +    SDL_UpdateWindowGrab(window);
   10.26  
   10.27      XReparentWindow(display, data->xwindow, root, window->x, window->y);
   10.28  
   10.29 @@ -1238,19 +1239,21 @@
   10.30  }
   10.31  
   10.32  void
   10.33 -X11_SetWindowGrab(_THIS, SDL_Window * window)
   10.34 +X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed)
   10.35  {
   10.36      SDL_WindowData *data = (SDL_WindowData *) window->driverdata;
   10.37      Display *display = data->videodata->display;
   10.38      SDL_bool oldstyle_fullscreen;
   10.39 +    SDL_bool grab_keyboard;
   10.40 +    const char *hint;
   10.41  
   10.42 -    /* ICCCM2.0-compliant window managers can handle fullscreen windows */
   10.43 +    /* ICCCM2.0-compliant window managers can handle fullscreen windows
   10.44 +       If we're using XVidMode to change resolution we need to confine
   10.45 +       the cursor so we don't pan around the virtual desktop.
   10.46 +     */
   10.47      oldstyle_fullscreen = X11_IsWindowLegacyFullscreen(_this, window);
   10.48  
   10.49 -    if (oldstyle_fullscreen ||
   10.50 -        ((window->flags & SDL_WINDOW_INPUT_GRABBED) &&
   10.51 -         (window->flags & SDL_WINDOW_INPUT_FOCUS))) {
   10.52 -
   10.53 +    if (oldstyle_fullscreen || grabbed) {
   10.54          /* Try to grab the mouse */
   10.55          for (;;) {
   10.56              int result =
   10.57 @@ -1259,15 +1262,26 @@
   10.58              if (result == GrabSuccess) {
   10.59                  break;
   10.60              }
   10.61 -            SDL_Delay(100);
   10.62 +            SDL_Delay(50);
   10.63          }
   10.64  
   10.65          /* Raise the window if we grab the mouse */
   10.66          XRaiseWindow(display, data->xwindow);
   10.67  
   10.68          /* Now grab the keyboard */
   10.69 -        XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
   10.70 -                      GrabModeAsync, CurrentTime);
   10.71 +        hint = SDL_GetHint(SDL_HINT_GRAB_KEYBOARD);
   10.72 +        if (hint && SDL_atoi(hint)) {
   10.73 +            grab_keyboard = SDL_TRUE;
   10.74 +        } else {
   10.75 +            /* We need to do this with the old style override_redirect
   10.76 +               fullscreen window otherwise we won't get keyboard focus.
   10.77 +            */
   10.78 +            grab_keyboard = oldstyle_fullscreen;
   10.79 +        }
   10.80 +        if (grab_keyboard) {
   10.81 +            XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
   10.82 +                          GrabModeAsync, CurrentTime);
   10.83 +        }
   10.84      } else {
   10.85          XUngrabPointer(display, CurrentTime);
   10.86          XUngrabKeyboard(display, CurrentTime);
    11.1 --- a/src/video/x11/SDL_x11window.h	Wed Nov 07 11:13:28 2012 -0800
    11.2 +++ b/src/video/x11/SDL_x11window.h	Wed Nov 07 15:55:43 2012 -0800
    11.3 @@ -78,7 +78,7 @@
    11.4  extern void X11_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered);
    11.5  extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen);
    11.6  extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp);
    11.7 -extern void X11_SetWindowGrab(_THIS, SDL_Window * window);
    11.8 +extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed);
    11.9  extern void X11_DestroyWindow(_THIS, SDL_Window * window);
   11.10  extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window,
   11.11                                      struct SDL_SysWMinfo *info);