From eb45d6bf286414bac34886c7e5c8deaffc82fbd0 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Mon, 15 Sep 2025 08:07:26 +0200 Subject: [PATCH] [client,sdl] explicitly handle KMOD_NONE If KMOD_NONE is set in SDL_KeyModMask disable hotkeys --- client/SDL/SDL2/sdl_kbd.cpp | 44 ++++++++++++++++++++++++++++++------- client/SDL/SDL2/sdl_kbd.hpp | 2 ++ client/SDL/SDL3/sdl_kbd.cpp | 37 +++++++++++++++++++++++++------ client/SDL/SDL3/sdl_kbd.hpp | 4 +++- 4 files changed, 71 insertions(+), 16 deletions(-) diff --git a/client/SDL/SDL2/sdl_kbd.cpp b/client/SDL/SDL2/sdl_kbd.cpp index 1a3db8cae..40fb91593 100644 --- a/client/SDL/SDL2/sdl_kbd.cpp +++ b/client/SDL/SDL2/sdl_kbd.cpp @@ -386,29 +386,56 @@ BOOL sdlInput::keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 return TRUE; } -uint32_t sdlInput::prefToMask() +static const std::map& getSdlMap() { - const std::map mapping = { + static std::map s_map = { { "KMOD_LSHIFT", KMOD_LSHIFT }, { "KMOD_RSHIFT", KMOD_RSHIFT }, { "KMOD_LCTRL", KMOD_LCTRL }, { "KMOD_RCTRL", KMOD_RCTRL }, { "KMOD_LALT", KMOD_LALT }, { "KMOD_RALT", KMOD_RALT }, { "KMOD_LGUI", KMOD_LGUI }, { "KMOD_RGUI", KMOD_RGUI }, { "KMOD_NUM", KMOD_NUM }, { "KMOD_CAPS", KMOD_CAPS }, - { "KMOD_MODE", KMOD_MODE }, #if SDL_VERSION_ATLEAST(2, 0, 18) { "KMOD_SCROLL", KMOD_SCROLL }, #endif { "KMOD_CTRL", KMOD_CTRL }, { "KMOD_SHIFT", KMOD_SHIFT }, - { "KMOD_ALT", KMOD_ALT }, { "KMOD_GUI", KMOD_GUI } + { "KMOD_ALT", KMOD_ALT }, { "KMOD_GUI", KMOD_GUI }, + { "KMOD_NONE", KMOD_NONE } }; + + return s_map; +} + +bool sdlInput::prefToEnabled() +{ + bool enable = true; + const auto& m = getSdlMap(); + for (const auto& val : SdlPref::instance()->get_array("SDL_KeyModMask", { "KMOD_RSHIFT" })) + { + auto it = m.find(val); + if (it != m.end()) + { + if (it->second == KMOD_NONE) + enabled = false; + } + else + { + WLog_WARN(TAG, "Invalid config::SDL_KeyModMask entry value '%s', disabling hotkeys", + val.c_str()); + enable = false; + } + } + return enable; +} + +uint32_t sdlInput::prefToMask() +{ + const auto& mapping = getSdlMap(); uint32_t mod = KMOD_NONE; for (const auto& val : SdlPref::instance()->get_array("SDL_KeyModMask", { "KMOD_RSHIFT" })) { auto it = mapping.find(val); if (it != mapping.end()) - { mod |= it->second; - } } return mod; } @@ -483,7 +510,7 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev) const UINT32 rdp_scancode = sdl_scancode_to_rdp(ev->keysym.scancode); const SDL_Keymod mods = SDL_GetModState(); - if ((mods & _hotkeyModmask) == _hotkeyModmask) + if (_hotkeysEnabled && (mods & _hotkeyModmask) == _hotkeyModmask) { if (ev->type == SDL_KEYDOWN) { @@ -556,7 +583,8 @@ BOOL sdlInput::mouse_grab(Uint32 windowID, SDL_bool enable) } sdlInput::sdlInput(SdlContext* sdl) - : _sdl(sdl), _lastWindowID(UINT32_MAX), _hotkeyModmask(prefToMask()) + : _sdl(sdl), _lastWindowID(UINT32_MAX), _hotkeysEnabled(prefToEnabled()), + _hotkeyModmask(prefToMask()) { auto list = freerdp_settings_get_string(_sdl->context()->settings, FreeRDP_KeyboardRemappingList); diff --git a/client/SDL/SDL2/sdl_kbd.hpp b/client/SDL/SDL2/sdl_kbd.hpp index 802e077af..e65e8ccac 100644 --- a/client/SDL/SDL2/sdl_kbd.hpp +++ b/client/SDL/SDL2/sdl_kbd.hpp @@ -55,6 +55,7 @@ class sdlInput static BOOL keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState, UINT32 imeConvMode); + static bool prefToEnabled(); static uint32_t prefToMask(); static uint32_t prefKeyValue(const std::string& key, uint32_t fallback = SDL_SCANCODE_UNKNOWN); @@ -67,6 +68,7 @@ class sdlInput Uint32 _lastWindowID; // hotkey handling + bool _hotkeysEnabled; uint32_t _hotkeyModmask; // modifier keys mask uint32_t _hotkeyFullscreen; uint32_t _hotkeyResizable; diff --git a/client/SDL/SDL3/sdl_kbd.cpp b/client/SDL/SDL3/sdl_kbd.cpp index e5143a96a..2dd8c0554 100644 --- a/client/SDL/SDL3/sdl_kbd.cpp +++ b/client/SDL/SDL3/sdl_kbd.cpp @@ -383,7 +383,8 @@ static const std::map& getSdlMap() { "KMOD_NUM", SDL_KMOD_NUM }, { "KMOD_CAPS", SDL_KMOD_CAPS }, { "KMOD_MODE", SDL_KMOD_MODE }, { "KMOD_SCROLL", SDL_KMOD_SCROLL }, { "KMOD_CTRL", SDL_KMOD_CTRL }, { "KMOD_SHIFT", SDL_KMOD_SHIFT }, - { "KMOD_ALT", SDL_KMOD_ALT }, { "KMOD_GUI", SDL_KMOD_GUI } + { "KMOD_ALT", SDL_KMOD_ALT }, { "KMOD_GUI", SDL_KMOD_GUI }, + { "KMOD_NONE", SDL_KMOD_NONE } }; return s_map; @@ -424,17 +425,38 @@ static std::string masktostr(uint32_t mask) return str; } -uint32_t sdlInput::prefToMask() +bool sdlInput::prefToEnabled() { - auto m = getSdlMap(); - uint32_t mod = SDL_KMOD_NONE; + bool enabled = true; + const auto& m = getSdlMap(); for (const auto& val : SdlPref::instance()->get_array("SDL_KeyModMask", { "KMOD_RSHIFT" })) { auto it = m.find(val); if (it != m.end()) { - mod |= it->second; + if (it->second == SDL_KMOD_NONE) + enabled = false; } + else + { + WLog_Print(_sdl->log, WLOG_WARN, + "Invalid config::SDL_KeyModMask entry value '%s', disabling hotkeys", + val.c_str()); + enabled = false; + } + } + return enabled; +} + +uint32_t sdlInput::prefToMask() +{ + const auto& m = getSdlMap(); + uint32_t mod = SDL_KMOD_NONE; + for (const auto& val : SdlPref::instance()->get_array("SDL_KeyModMask", { "KMOD_RSHIFT" })) + { + auto it = m.find(val); + if (it != m.end()) + mod |= it->second; } return mod; } @@ -544,7 +566,7 @@ BOOL sdlInput::keyboard_handle_event(const SDL_KeyboardEvent* ev) const UINT32 rdp_scancode = scancode_to_rdp(ev->scancode); const SDL_Keymod mods = SDL_GetModState(); - if ((mods & _hotkeyModmask) == _hotkeyModmask) + if (_hotkeysEnabled && (mods & _hotkeyModmask) == _hotkeyModmask) { if (ev->type == SDL_EVENT_KEY_DOWN) { @@ -651,7 +673,8 @@ BOOL sdlInput::mouse_grab(Uint32 windowID, bool enable) } sdlInput::sdlInput(SdlContext* sdl) - : _sdl(sdl), _lastWindowID(UINT32_MAX), _hotkeyModmask(prefToMask()) + : _sdl(sdl), _lastWindowID(UINT32_MAX), _hotkeysEnabled(prefToEnabled()), + _hotkeyModmask(prefToMask()) { _hotkeyFullscreen = prefKeyValue("SDL_Fullscreen", SDL_SCANCODE_RETURN); _hotkeyResizable = prefKeyValue("SDL_Resizeable", SDL_SCANCODE_R); diff --git a/client/SDL/SDL3/sdl_kbd.hpp b/client/SDL/SDL3/sdl_kbd.hpp index d767462b8..901f79a0f 100644 --- a/client/SDL/SDL3/sdl_kbd.hpp +++ b/client/SDL/SDL3/sdl_kbd.hpp @@ -57,7 +57,8 @@ class sdlInput static BOOL keyboard_set_ime_status(rdpContext* context, UINT16 imeId, UINT32 imeState, UINT32 imeConvMode); - static uint32_t prefToMask(); + bool prefToEnabled(); + uint32_t prefToMask(); static uint32_t prefKeyValue(const std::string& key, uint32_t fallback = SDL_SCANCODE_UNKNOWN); private: @@ -71,6 +72,7 @@ class sdlInput Uint32 _lastWindowID; // hotkey handling + bool _hotkeysEnabled; uint32_t _hotkeyModmask; // modifier keys mask uint32_t _hotkeyFullscreen; uint32_t _hotkeyResizable;