x11: Send the _XWAYLAND_MAY_GRAB_KEYBOARD message when grabbing the keyboard

GNOME requires this to allow keyboard grabs on XWayland. Otherwise, XGrabKeyboard will still report success, but shortcuts won't be inhibited.

See 5f132f3975

(cherry picked from commit 716e33f106)
This commit is contained in:
Frank Praznik
2025-03-25 12:17:39 -04:00
parent 013918cd83
commit 04dace6c75
2 changed files with 31 additions and 0 deletions

View File

@@ -59,6 +59,10 @@ encounter limitations or behavior that is different from other windowing systems
`SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your `SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your
application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`. application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`.
### Keyboard grabs don't work when running under XWayland
- One GNOME based desktops, the dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled.
## Using custom Wayland windowing protocols with SDL windows ## Using custom Wayland windowing protocols with SDL windows
Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window. Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window.

View File

@@ -2019,6 +2019,33 @@ bool X11_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, bool
return true; return true;
} }
/* GNOME needs the _XWAYLAND_MAY_GRAB_KEYBOARD message on XWayland:
*
* - message_type set to "_XWAYLAND_MAY_GRAB_KEYBOARD"
* - window set to the xid of the window on which the grab is to be issued
* - data.l[0] to a non-zero value
*
* The dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled as well.
*
* https://gitlab.gnome.org/GNOME/mutter/-/commit/5f132f39750f684c3732b4346dec810cd218d609
*/
if (_this->internal->is_xwayland) {
Atom _XWAYLAND_MAY_GRAB_ATOM = X11_XInternAtom(display, "_XWAYLAND_MAY_GRAB_KEYBOARD", False);
if (_XWAYLAND_MAY_GRAB_ATOM != None) {
XClientMessageEvent client_message;
client_message.type = ClientMessage;
client_message.window = data->xwindow;
client_message.format = 32;
client_message.message_type = _XWAYLAND_MAY_GRAB_ATOM;
client_message.data.l[0] = 1;
client_message.data.l[1] = CurrentTime;
X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureNotifyMask | SubstructureRedirectMask, (XEvent *)&client_message);
X11_XFlush(display);
}
}
X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync, X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
GrabModeAsync, CurrentTime); GrabModeAsync, CurrentTime);
} else { } else {