diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index e435af3b2..f720ee594 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -233,6 +233,7 @@ struct SDL_VideoDevice int (*SetWindowGammaRamp) (_THIS, SDL_Window * window, const Uint16 * ramp); int (*GetWindowGammaRamp) (_THIS, SDL_Window * window, Uint16 * ramp); void (*SetWindowGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); + void (*SetWindowKeyboardGrab) (_THIS, SDL_Window * window, SDL_bool grabbed); void (*DestroyWindow) (_THIS, SDL_Window * window); int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 * format, void ** pixels, int *pitch); int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, const SDL_Rect * rects, int numrects); diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 0b730be95..33bf5337a 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -2655,6 +2655,9 @@ SDL_UpdateWindowGrab(SDL_Window * window) if (_this->SetWindowGrab) { _this->SetWindowGrab(_this, grabbed_window, SDL_FALSE); } + if (_this->SetWindowKeyboardGrab) { + _this->SetWindowKeyboardGrab(_this, grabbed_window, SDL_FALSE); + } } _this->grabbed_window = window; } else if (grabbed_window == window) { @@ -2664,6 +2667,13 @@ SDL_UpdateWindowGrab(SDL_Window * window) if (_this->SetWindowGrab) { _this->SetWindowGrab(_this, window, grabbed); } + if (_this->SetWindowKeyboardGrab) { + if (grabbed && SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { + _this->SetWindowKeyboardGrab(_this, window, SDL_TRUE); + } else { + _this->SetWindowKeyboardGrab(_this, window, SDL_FALSE); + } + } } void diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c index 61034f4fb..c4e48375f 100644 --- a/src/video/wayland/SDL_waylandvideo.c +++ b/src/video/wayland/SDL_waylandvideo.c @@ -201,6 +201,7 @@ Wayland_CreateDevice(int devindex) device->MaximizeWindow = Wayland_MaximizeWindow; device->MinimizeWindow = Wayland_MinimizeWindow; device->SetWindowGrab = Wayland_SetWindowGrab; + device->SetWindowKeyboardGrab = Wayland_SetWindowKeyboardGrab; device->RestoreWindow = Wayland_RestoreWindow; device->SetWindowBordered = Wayland_SetWindowBordered; device->SetWindowResizable = Wayland_SetWindowResizable; diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c index 16c6fa6b7..97dfb3075 100644 --- a/src/video/wayland/SDL_waylandwindow.c +++ b/src/video/wayland/SDL_waylandwindow.c @@ -676,12 +676,20 @@ Wayland_SetWindowGrab(_THIS, SDL_Window *window, SDL_bool grabbed) if (grabbed) { Wayland_input_confine_pointer(window, data->input); + } else { + Wayland_input_unconfine_pointer(data->input); + } +} - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) - Wayland_input_grab_keyboard(window, data->input); +void +Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed) +{ + SDL_VideoData *data = (SDL_VideoData *) _this->driverdata; + + if (grabbed) { + Wayland_input_grab_keyboard(window, data->input); } else { Wayland_input_ungrab_keyboard(window); - Wayland_input_unconfine_pointer(data->input); } } diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h index 4753cae3d..a67044a12 100644 --- a/src/video/wayland/SDL_waylandwindow.h +++ b/src/video/wayland/SDL_waylandwindow.h @@ -92,6 +92,7 @@ extern void Wayland_SetWindowFullscreen(_THIS, SDL_Window * window, extern void Wayland_MaximizeWindow(_THIS, SDL_Window * window); extern void Wayland_MinimizeWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void Wayland_SetWindowKeyboardGrab(_THIS, SDL_Window *window, SDL_bool grabbed); extern void Wayland_RestoreWindow(_THIS, SDL_Window * window); extern void Wayland_SetWindowBordered(_THIS, SDL_Window * window, SDL_bool bordered); extern void Wayland_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizable); diff --git a/src/video/windows/SDL_windowsvideo.c b/src/video/windows/SDL_windowsvideo.c index 9ef93605f..962bcf71b 100644 --- a/src/video/windows/SDL_windowsvideo.c +++ b/src/video/windows/SDL_windowsvideo.c @@ -161,6 +161,7 @@ WIN_CreateDevice(int devindex) device->SetWindowGammaRamp = WIN_SetWindowGammaRamp; device->GetWindowGammaRamp = WIN_GetWindowGammaRamp; device->SetWindowGrab = WIN_SetWindowGrab; + device->SetWindowKeyboardGrab = WIN_SetWindowKeyboardGrab; device->DestroyWindow = WIN_DestroyWindow; device->GetWindowWMInfo = WIN_GetWindowWMInfo; device->CreateWindowFramebuffer = WIN_CreateWindowFramebuffer; diff --git a/src/video/windows/SDL_windowswindow.c b/src/video/windows/SDL_windowswindow.c index cae93f769..6593f4257 100644 --- a/src/video/windows/SDL_windowswindow.c +++ b/src/video/windows/SDL_windowswindow.c @@ -782,14 +782,6 @@ WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) { WIN_UpdateClipCursor(window); - if (grabbed) { - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { - WIN_GrabKeyboard(window); - } - } else { - WIN_UngrabKeyboard(window); - } - if (window->flags & SDL_WINDOW_FULLSCREEN) { UINT flags = SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOSIZE; @@ -800,6 +792,16 @@ WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) } } +void +WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + if (grabbed) { + WIN_GrabKeyboard(window); + } else { + WIN_UngrabKeyboard(window); + } +} + void WIN_DestroyWindow(_THIS, SDL_Window * window) { diff --git a/src/video/windows/SDL_windowswindow.h b/src/video/windows/SDL_windowswindow.h index cbadc858a..b0fe74823 100644 --- a/src/video/windows/SDL_windowswindow.h +++ b/src/video/windows/SDL_windowswindow.h @@ -77,6 +77,7 @@ extern void WIN_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay extern int WIN_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern int WIN_GetWindowGammaRamp(_THIS, SDL_Window * window, Uint16 * ramp); extern void WIN_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void WIN_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void WIN_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool WIN_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info); diff --git a/src/video/x11/SDL_x11video.c b/src/video/x11/SDL_x11video.c index 72a64bb36..34be3965e 100644 --- a/src/video/x11/SDL_x11video.c +++ b/src/video/x11/SDL_x11video.c @@ -225,6 +225,7 @@ X11_CreateDevice(int devindex) device->SetWindowFullscreen = X11_SetWindowFullscreen; device->SetWindowGammaRamp = X11_SetWindowGammaRamp; device->SetWindowGrab = X11_SetWindowGrab; + device->SetWindowKeyboardGrab = X11_SetWindowKeyboardGrab; device->DestroyWindow = X11_DestroyWindow; device->CreateWindowFramebuffer = X11_CreateWindowFramebuffer; device->UpdateWindowFramebuffer = X11_UpdateWindowFramebuffer; diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c index a0f85e52d..e3c052f20 100644 --- a/src/video/x11/SDL_x11window.c +++ b/src/video/x11/SDL_x11window.c @@ -1566,7 +1566,6 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) SDL_WindowData *data = (SDL_WindowData *) window->driverdata; Display *display = data->videodata->display; SDL_bool oldstyle_fullscreen; - SDL_bool grab_keyboard; /* ICCCM2.0-compliant window managers can handle fullscreen windows If we're using XVidMode to change resolution we need to confine @@ -1607,21 +1606,26 @@ X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed) /* Raise the window if we grab the mouse */ X11_XRaiseWindow(display, data->xwindow); - /* Now grab the keyboard */ - if (SDL_GetHintBoolean(SDL_HINT_GRAB_KEYBOARD, SDL_FALSE)) { - grab_keyboard = SDL_TRUE; - } else { - /* We need to do this with the old style override_redirect - fullscreen window otherwise we won't get keyboard focus. - */ - grab_keyboard = oldstyle_fullscreen; - } - if (grab_keyboard) { - X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, - GrabModeAsync, CurrentTime); + /* Now grab the keyboard on old-style fullscreen */ + if (oldstyle_fullscreen) { + X11_SetWindowKeyboardGrab(_this, window, SDL_TRUE); } } else { X11_XUngrabPointer(display, CurrentTime); + } + X11_XSync(display, False); +} + +void +X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed) +{ + SDL_WindowData *data = (SDL_WindowData *) window->driverdata; + Display *display = data->videodata->display; + + if (grabbed) { + X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, + GrabModeAsync, CurrentTime); + } else { X11_XUngrabKeyboard(display, CurrentTime); } X11_XSync(display, False); diff --git a/src/video/x11/SDL_x11window.h b/src/video/x11/SDL_x11window.h index f98a67f90..c6cc578ab 100644 --- a/src/video/x11/SDL_x11window.h +++ b/src/video/x11/SDL_x11window.h @@ -100,6 +100,7 @@ extern void X11_SetWindowResizable(_THIS, SDL_Window * window, SDL_bool resizabl extern void X11_SetWindowFullscreen(_THIS, SDL_Window * window, SDL_VideoDisplay * display, SDL_bool fullscreen); extern int X11_SetWindowGammaRamp(_THIS, SDL_Window * window, const Uint16 * ramp); extern void X11_SetWindowGrab(_THIS, SDL_Window * window, SDL_bool grabbed); +extern void X11_SetWindowKeyboardGrab(_THIS, SDL_Window * window, SDL_bool grabbed); extern void X11_DestroyWindow(_THIS, SDL_Window * window); extern SDL_bool X11_GetWindowWMInfo(_THIS, SDL_Window * window, struct SDL_SysWMinfo *info);