mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2025-02-17 03:15:39 +00:00
CommonHostInterface: Fix key inputs getting stuck with modifiers
This commit is contained in:
parent
091b745af6
commit
a48fa4097b
|
@ -1,10 +1,10 @@
|
||||||
#include "sdl_host_interface.h"
|
#include "sdl_host_interface.h"
|
||||||
#include "frontend-common/controller_interface.h"
|
#include "frontend-common/controller_interface.h"
|
||||||
|
#include "frontend-common/fullscreen_ui.h"
|
||||||
#include "frontend-common/icon.h"
|
#include "frontend-common/icon.h"
|
||||||
#include "frontend-common/ini_settings_interface.h"
|
#include "frontend-common/ini_settings_interface.h"
|
||||||
#include "frontend-common/sdl_controller_interface.h"
|
#include "frontend-common/sdl_controller_interface.h"
|
||||||
#include "frontend-common/sdl_initializer.h"
|
#include "frontend-common/sdl_initializer.h"
|
||||||
#include "frontend-common/fullscreen_ui.h"
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_impl_sdl.h"
|
#include "imgui_impl_sdl.h"
|
||||||
#include "scmversion/scmversion.h"
|
#include "scmversion/scmversion.h"
|
||||||
|
@ -307,7 +307,8 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event)
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
{
|
{
|
||||||
// Binding mode
|
// Binding mode
|
||||||
if (m_fullscreen_ui_enabled && m_controller_interface && m_controller_interface->HasHook() && event->key.repeat == 0)
|
if (m_fullscreen_ui_enabled && m_controller_interface && m_controller_interface->HasHook() &&
|
||||||
|
event->key.repeat == 0)
|
||||||
{
|
{
|
||||||
String keyName;
|
String keyName;
|
||||||
if (!SDLKeyNames::KeyEventToString(event, keyName))
|
if (!SDLKeyNames::KeyEventToString(event, keyName))
|
||||||
|
@ -324,9 +325,9 @@ void SDLHostInterface::HandleSDLEvent(const SDL_Event* event)
|
||||||
|
|
||||||
if (!ImGui::GetIO().WantCaptureKeyboard && event->key.repeat == 0)
|
if (!ImGui::GetIO().WantCaptureKeyboard && event->key.repeat == 0)
|
||||||
{
|
{
|
||||||
const HostKeyCode code = static_cast<HostKeyCode>(SDLKeyNames::KeyEventToInt(event));
|
const u32 code = SDLKeyNames::KeyEventToInt(event);
|
||||||
const bool pressed = (event->type == SDL_KEYDOWN);
|
const bool pressed = (event->type == SDL_KEYDOWN);
|
||||||
HandleHostKeyEvent(code, pressed);
|
HandleHostKeyEvent(code & SDLKeyNames::KEY_MASK, code & SDLKeyNames::MODIFIER_MASK, pressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
|
|
||||||
namespace SDLKeyNames {
|
namespace SDLKeyNames {
|
||||||
|
|
||||||
|
enum : u32
|
||||||
|
{
|
||||||
|
MODIFIER_SHIFT = 16,
|
||||||
|
KEY_MASK = ((1 << MODIFIER_SHIFT) - 1),
|
||||||
|
MODIFIER_MASK = ~KEY_MASK,
|
||||||
|
};
|
||||||
|
|
||||||
static const std::map<int, const char*> s_sdl_key_names = {{SDLK_RETURN, "Return"},
|
static const std::map<int, const char*> s_sdl_key_names = {{SDLK_RETURN, "Return"},
|
||||||
{SDLK_ESCAPE, "Escape"},
|
{SDLK_ESCAPE, "Escape"},
|
||||||
{SDLK_BACKSPACE, "Backspace"},
|
{SDLK_BACKSPACE, "Backspace"},
|
||||||
|
@ -265,13 +272,13 @@ static const std::array<SDLKeyModifierEntry, 4> s_sdl_key_modifiers = {
|
||||||
{KMOD_LALT, static_cast<SDL_Keymod>(KMOD_LALT | KMOD_RALT), SDLK_LALT, SDLK_RALT, "Alt"},
|
{KMOD_LALT, static_cast<SDL_Keymod>(KMOD_LALT | KMOD_RALT), SDLK_LALT, SDLK_RALT, "Alt"},
|
||||||
{KMOD_LGUI, static_cast<SDL_Keymod>(KMOD_LGUI | KMOD_RGUI), SDLK_LGUI, SDLK_RGUI, "Meta"}}};
|
{KMOD_LGUI, static_cast<SDL_Keymod>(KMOD_LGUI | KMOD_RGUI), SDLK_LGUI, SDLK_RGUI, "Meta"}}};
|
||||||
|
|
||||||
const char* GetKeyName(SDL_Keycode key)
|
static const char* GetKeyName(SDL_Keycode key)
|
||||||
{
|
{
|
||||||
const auto it = s_sdl_key_names.find(key);
|
const auto it = s_sdl_key_names.find(key);
|
||||||
return it == s_sdl_key_names.end() ? nullptr : it->second;
|
return it == s_sdl_key_names.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<SDL_Keycode> GetKeyCodeForName(const std::string_view key_name)
|
static std::optional<SDL_Keycode> GetKeyCodeForName(const std::string_view key_name)
|
||||||
{
|
{
|
||||||
for (const auto& it : s_sdl_key_names)
|
for (const auto& it : s_sdl_key_names)
|
||||||
{
|
{
|
||||||
|
@ -282,24 +289,24 @@ std::optional<SDL_Keycode> GetKeyCodeForName(const std::string_view key_name)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 KeyEventToInt(const SDL_Event* event)
|
static u32 KeyEventToInt(const SDL_Event* event)
|
||||||
{
|
{
|
||||||
u32 code = static_cast<u32>(event->key.keysym.sym);
|
u32 code = static_cast<u32>(event->key.keysym.sym);
|
||||||
|
|
||||||
const SDL_Keymod mods = static_cast<SDL_Keymod>(event->key.keysym.mod);
|
const SDL_Keymod mods = static_cast<SDL_Keymod>(event->key.keysym.mod);
|
||||||
if (mods & (KMOD_LSHIFT | KMOD_RSHIFT))
|
if (mods & (KMOD_LSHIFT | KMOD_RSHIFT))
|
||||||
code |= static_cast<u32>(KMOD_LSHIFT) << 16;
|
code |= static_cast<u32>(KMOD_LSHIFT) << MODIFIER_SHIFT;
|
||||||
if (mods & (KMOD_LCTRL | KMOD_RCTRL))
|
if (mods & (KMOD_LCTRL | KMOD_RCTRL))
|
||||||
code |= static_cast<u32>(KMOD_LCTRL) << 16;
|
code |= static_cast<u32>(KMOD_LCTRL) << MODIFIER_SHIFT;
|
||||||
if (mods & (KMOD_LALT | KMOD_RALT))
|
if (mods & (KMOD_LALT | KMOD_RALT))
|
||||||
code |= static_cast<u32>(KMOD_LALT) << 16;
|
code |= static_cast<u32>(KMOD_LALT) << MODIFIER_SHIFT;
|
||||||
if (mods & (KMOD_LGUI | KMOD_RGUI))
|
if (mods & (KMOD_LGUI | KMOD_RGUI))
|
||||||
code |= static_cast<u32>(KMOD_LGUI) << 16;
|
code |= static_cast<u32>(KMOD_LGUI) << MODIFIER_SHIFT;
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KeyEventToString(const SDL_Event* event, String& out_string)
|
static bool KeyEventToString(const SDL_Event* event, String& out_string)
|
||||||
{
|
{
|
||||||
const SDL_Keycode key = event->key.keysym.sym;
|
const SDL_Keycode key = event->key.keysym.sym;
|
||||||
const SDL_Keymod mods = static_cast<SDL_Keymod>(event->key.keysym.mod);
|
const SDL_Keymod mods = static_cast<SDL_Keymod>(event->key.keysym.mod);
|
||||||
|
@ -322,7 +329,7 @@ bool KeyEventToString(const SDL_Event* event, String& out_string)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<u32> ParseKeyString(const std::string_view key_str)
|
static std::optional<u32> ParseKeyString(const std::string_view key_str)
|
||||||
{
|
{
|
||||||
u32 modifiers = 0;
|
u32 modifiers = 0;
|
||||||
std::string_view::size_type pos = 0;
|
std::string_view::size_type pos = 0;
|
||||||
|
@ -356,6 +363,6 @@ std::optional<u32> ParseKeyString(const std::string_view key_str)
|
||||||
if (!key_code)
|
if (!key_code)
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
return static_cast<u32>(key_code.value()) | (modifiers << 16);
|
return static_cast<u32>(key_code.value()) | (modifiers << MODIFIER_SHIFT);
|
||||||
}
|
}
|
||||||
} // namespace SDLKeyNames
|
} // namespace SDLKeyNames
|
||||||
|
|
|
@ -381,7 +381,7 @@ void QtHostInterface::onDisplayWindowKeyEvent(int key, bool pressed)
|
||||||
if (masked_key < countof(ImGuiIO::KeysDown))
|
if (masked_key < countof(ImGuiIO::KeysDown))
|
||||||
ImGui::GetIO().KeysDown[masked_key] = pressed;
|
ImGui::GetIO().KeysDown[masked_key] = pressed;
|
||||||
|
|
||||||
HandleHostKeyEvent(key, pressed);
|
HandleHostKeyEvent(key & ~Qt::KeyboardModifierMask, key & Qt::KeyboardModifierMask, pressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtHostInterface::onDisplayWindowMouseMoveEvent(int x, int y)
|
void QtHostInterface::onDisplayWindowMouseMoveEvent(int x, int y)
|
||||||
|
|
|
@ -1267,11 +1267,15 @@ void CommonHostInterface::RegisterHotkey(String category, String name, String di
|
||||||
m_hotkeys.push_back(HotkeyInfo{std::move(category), std::move(name), std::move(display_name), std::move(handler)});
|
m_hotkeys.push_back(HotkeyInfo{std::move(category), std::move(name), std::move(display_name), std::move(handler)});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommonHostInterface::HandleHostKeyEvent(HostKeyCode key, bool pressed)
|
bool CommonHostInterface::HandleHostKeyEvent(HostKeyCode code, HostKeyCode modifiers, bool pressed)
|
||||||
{
|
{
|
||||||
const auto iter = m_keyboard_input_handlers.find(key);
|
auto iter = m_keyboard_input_handlers.find(code | modifiers);
|
||||||
if (iter == m_keyboard_input_handlers.end())
|
if (iter == m_keyboard_input_handlers.end())
|
||||||
return false;
|
{
|
||||||
|
// try without the modifier
|
||||||
|
if (modifiers == 0 || (iter = m_keyboard_input_handlers.find(code)) == m_keyboard_input_handlers.end())
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
iter->second(pressed);
|
iter->second(pressed);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -347,7 +347,7 @@ protected:
|
||||||
virtual bool AddRumbleToInputMap(const std::string& binding, u32 controller_index, u32 num_motors);
|
virtual bool AddRumbleToInputMap(const std::string& binding, u32 controller_index, u32 num_motors);
|
||||||
|
|
||||||
void RegisterHotkey(String category, String name, String display_name, InputButtonHandler handler);
|
void RegisterHotkey(String category, String name, String display_name, InputButtonHandler handler);
|
||||||
bool HandleHostKeyEvent(HostKeyCode code, bool pressed);
|
bool HandleHostKeyEvent(HostKeyCode code, HostKeyCode modifiers, bool pressed);
|
||||||
bool HandleHostMouseEvent(HostMouseButton button, bool pressed);
|
bool HandleHostMouseEvent(HostMouseButton button, bool pressed);
|
||||||
void UpdateInputMap(SettingsInterface& si);
|
void UpdateInputMap(SettingsInterface& si);
|
||||||
void ClearInputMap();
|
void ClearInputMap();
|
||||||
|
@ -492,8 +492,8 @@ private:
|
||||||
u32 controller_index;
|
u32 controller_index;
|
||||||
u32 num_motors;
|
u32 num_motors;
|
||||||
std::array<float, MAX_MOTORS> last_strength;
|
std::array<float, MAX_MOTORS> last_strength;
|
||||||
ControllerRumbleCallback update_callback;
|
|
||||||
u64 last_update_time;
|
u64 last_update_time;
|
||||||
|
ControllerRumbleCallback update_callback;
|
||||||
};
|
};
|
||||||
std::vector<ControllerRumbleState> m_controller_vibration_motors;
|
std::vector<ControllerRumbleState> m_controller_vibration_motors;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue