diff --git a/ChangeLog.md b/ChangeLog.md index f633da35f..f21e4be31 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -35,6 +35,9 @@ automatic WebSocket detection code if an ill-behaved client sent 3 or fewer bytes of data immediately after connecting. Certain versions of Apache Guacamole were known to trigger this issue sporadically. +8. The TurboVNC Viewer now works around an issue that prevented keyboard +grabbing from working when running the viewer in a GNOME/Wayland session. + 3.1.2 ===== diff --git a/unix/vncviewer/turbovnchelper.c b/unix/vncviewer/turbovnchelper.c index 5c952ad20..c4391236a 100644 --- a/unix/vncviewer/turbovnchelper.c +++ b/unix/vncviewer/turbovnchelper.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2015-2019, 2021-2022 D. R. Commander. All Rights Reserved. +/* Copyright (C) 2015-2019, 2021-2022, 2024 D. R. Commander. + * All Rights Reserved. * * This is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -227,6 +228,28 @@ JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_x11FullScreen } +/* + * Allow/disallow keyboard grabbing when using GNOME/Wayland. + */ + +static void xwayland_grab_keyboard(Display *dpy, Window win, int on) +{ + XEvent e; + Atom _XWAYLAND_MAY_GRAB_KEYBOARD = + XInternAtom(dpy, "_XWAYLAND_MAY_GRAB_KEYBOARD", False); + + memset(&e, 0, sizeof(e)); + e.xclient.type = ClientMessage; + e.xclient.message_type = _XWAYLAND_MAY_GRAB_KEYBOARD; + e.xclient.display = dpy; + e.xclient.window = win; + e.xclient.format = 32; + e.xclient.data.l[0] = on; + + XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureRedirectMask, &e); +} + + JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_grabKeyboard (JNIEnv *env, jobject obj, jboolean on, jboolean pointer) { @@ -261,6 +284,7 @@ JNIEXPORT void JNICALL Java_com_turbovnc_vncviewer_Viewport_grabKeyboard THROW("Could not get X11 drawing surface info"); XSync(x11dsi->display, False); + xwayland_grab_keyboard(x11dsi->display, x11dsi->drawable, on); if (on) { int count = 5;