diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 7621c6c7..f94835b6 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -147,6 +147,9 @@ if(ENABLE_WAYLAND) wayland_generate( "${WAYLAND_PROTOCOLS_BASE}/unstable/pointer-constraints/pointer-constraints-unstable-v1.xml" "${PROJECT_TOP}/client/src/wayland-pointer-constraints-unstable-v1-client-protocol") + wayland_generate( + "${WAYLAND_PROTOCOLS_BASE}/unstable/keyboard-shortcuts-inhibit/keyboard-shortcuts-inhibit-unstable-v1.xml" + "${PROJECT_TOP}/client/src/wayland-keyboard-shortcuts-inhibit-unstable-v1-client-protocol") endif() feature_summary(WHAT ENABLED_FEATURES DISABLED_FEATURES) diff --git a/client/src/main.c b/client/src/main.c index c6b890ac..4db15066 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -1240,12 +1240,26 @@ int eventFilter(void * userdata, SDL_Event * event) case SDL_WINDOWEVENT_FOCUS_GAINED: if (g_state.wminfo.subsystem != SDL_SYSWM_X11) + { g_state.focused = true; + + if (!inputEnabled()) + break; + if (params.grabKeyboardOnFocus) + wmGrabKeyboard(); + } break; case SDL_WINDOWEVENT_FOCUS_LOST: if (g_state.wminfo.subsystem != SDL_SYSWM_X11) + { g_state.focused = false; + + if (!inputEnabled()) + break; + if (params.grabKeyboardOnFocus) + wmUngrabKeyboard(); + } break; case SDL_WINDOWEVENT_SIZE_CHANGED: diff --git a/client/src/wm.c b/client/src/wm.c index 0a9f56e1..5fc9598e 100644 --- a/client/src/wm.c +++ b/client/src/wm.c @@ -27,6 +27,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "common/debug.h" +#include "wayland-keyboard-shortcuts-inhibit-unstable-v1-client-protocol.h" #include "wayland-pointer-constraints-unstable-v1-client-protocol.h" #include "wayland-relative-pointer-unstable-v1-client-protocol.h" @@ -42,6 +43,8 @@ static struct WMState g_wmState; static void wmWaylandInit(); static void wmWaylandFree(); +static void wmWaylandGrabKeyboard(); +static void wmWaylandUngrabKeyboard(); static void wmWaylandGrabPointer(); static void wmWaylandUngrabPointer(); @@ -135,6 +138,7 @@ void wmGrabKeyboard() break; case SDL_SYSWM_WAYLAND: + wmWaylandGrabKeyboard(); break; default: @@ -163,6 +167,7 @@ void wmUngrabKeyboard() break; case SDL_SYSWM_WAYLAND: + wmWaylandUngrabKeyboard(); break; default: @@ -224,6 +229,8 @@ struct WMDataWayland struct zwp_pointer_constraints_v1 * pointerConstraints; struct zwp_relative_pointer_v1 * relativePointer; struct zwp_confined_pointer_v1 * confinedPointer; + struct zwp_keyboard_shortcuts_inhibit_manager_v1 * keyboardInhibitManager; + struct zwp_keyboard_shortcuts_inhibitor_v1 * keyboardInhibitor; }; // Registry-handling listeners. @@ -241,6 +248,9 @@ static void registryGlobalHandler(void * data, struct wl_registry * registry, else if (!strcmp(interface, zwp_pointer_constraints_v1_interface.name)) wm->pointerConstraints = wl_registry_bind(wm->registry, name, &zwp_pointer_constraints_v1_interface, 1); + else if (!strcmp(interface, zwp_keyboard_shortcuts_inhibit_manager_v1_interface.name)) + wm->keyboardInhibitManager = wl_registry_bind(wm->registry, name, + &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1); } static void registryGlobalRemoveHandler(void * data, @@ -358,6 +368,28 @@ static void wmWaylandUngrabPointer() } } +static void wmWaylandGrabKeyboard() +{ + struct WMDataWayland * wm = g_wmState.opaque; + + if (wm->keyboardInhibitManager) + { + wm->keyboardInhibitor = zwp_keyboard_shortcuts_inhibit_manager_v1_inhibit_shortcuts( + wm->keyboardInhibitManager, wm->surface, wm->seat); + } +} + +static void wmWaylandUngrabKeyboard() +{ + struct WMDataWayland * wm = g_wmState.opaque; + + if (wm->keyboardInhibitor) + { + zwp_keyboard_shortcuts_inhibitor_v1_destroy(wm->keyboardInhibitor); + wm->keyboardInhibitor = NULL; + } +} + static void wmWaylandFree() { struct WMDataWayland * wm = g_wmState.opaque;