diff --git a/rpcs3/basic_keyboard_handler.cpp b/rpcs3/basic_keyboard_handler.cpp index 4fa5f8cdc1..03a86a57fc 100644 --- a/rpcs3/basic_keyboard_handler.cpp +++ b/rpcs3/basic_keyboard_handler.cpp @@ -1,10 +1,14 @@ -#include "basic_keyboard_handler.h" +#include "basic_keyboard_handler.h" #include #include #include "Emu/System.h" +#ifdef _WIN32 +#include "windows.h" +#endif + void basic_keyboard_handler::Init(const u32 max_connect) { for (u32 i = 0; i < max_connect; i++) @@ -50,6 +54,11 @@ void basic_keyboard_handler::SetTargetWindow(QWindow* target) bool basic_keyboard_handler::eventFilter(QObject* target, QEvent* ev) { + if (!ev) + { + return false; + } + // !m_target is for future proofing when gsrender isn't automatically initialized on load. // !m_target->isVisible() is a hack since currently a guiless application will STILL inititialize a gsrender (providing a valid target) if (!m_target || !m_target->isVisible() || target == m_target) @@ -68,22 +77,71 @@ bool basic_keyboard_handler::eventFilter(QObject* target, QEvent* ev) void basic_keyboard_handler::keyPressEvent(QKeyEvent* keyEvent) { + if (!keyEvent) + { + return; + } + if (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat) { keyEvent->ignore(); return; } - Key(keyEvent->key(), true); + + const int key = getUnmodifiedKey(keyEvent); + + if (key >= 0) + { + Key(static_cast(key), true); + } } void basic_keyboard_handler::keyReleaseEvent(QKeyEvent* keyEvent) { + if (!keyEvent) + { + return; + } + if (keyEvent->isAutoRepeat() && !m_keyboards[0].m_key_repeat) { keyEvent->ignore(); return; } - Key(keyEvent->key(), false); + + const int key = getUnmodifiedKey(keyEvent); + + if (key >= 0) + { + Key(static_cast(key), false); + } +} + +// This should get the actual unmodified key without getting too crazy. +// key() only shows the modifiers and the modified key (e.g. no easy way of knowing that - was pressed in 'SHIFT+-' in order to get _) +int basic_keyboard_handler::getUnmodifiedKey(QKeyEvent* keyEvent) +{ + if (!keyEvent) + { + return -1; + } + + int key = keyEvent->key(); + +#ifdef _WIN32 + if (keyEvent->modifiers() != Qt::NoModifier && !keyEvent->text().isEmpty()) + { + const auto virtual_key = keyEvent->nativeVirtualKey(); + const auto mapped_key = (int)MapVirtualKeyA((UINT)virtual_key, MAPVK_VK_TO_CHAR); + if (key != mapped_key) + { + LOG_NOTICE(HLE, "basic_keyboard_handler: converted key %s (%d) to (%d)", keyEvent->text().toStdString(), key, mapped_key); + key = mapped_key; + } + } +#endif + + return key; } void basic_keyboard_handler::LoadSettings() diff --git a/rpcs3/basic_keyboard_handler.h b/rpcs3/basic_keyboard_handler.h index 58dd0eaebe..ddde7fca75 100644 --- a/rpcs3/basic_keyboard_handler.h +++ b/rpcs3/basic_keyboard_handler.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "stdafx.h" #include "Emu/Io/KeyboardHandler.h" @@ -18,6 +18,7 @@ public: bool eventFilter(QObject* obj, QEvent* ev) override; void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); + int getUnmodifiedKey(QKeyEvent* event); void LoadSettings(); private: QWindow* m_target = nullptr;