From 58d8d126655f50f920e3afde47d63bec96a5e685 Mon Sep 17 00:00:00 2001 From: Unknown Date: Fri, 22 Dec 2017 17:03:24 +0100 Subject: [PATCH] Qt/Input: fix numpad (regression) --- rpcs3/keyboard_pad_handler.cpp | 140 ++++++++++++++++++++++++--------- rpcs3/keyboard_pad_handler.h | 2 + 2 files changed, 105 insertions(+), 37 deletions(-) diff --git a/rpcs3/keyboard_pad_handler.cpp b/rpcs3/keyboard_pad_handler.cpp index f4c6a806ef..073b0e170e 100644 --- a/rpcs3/keyboard_pad_handler.cpp +++ b/rpcs3/keyboard_pad_handler.cpp @@ -174,29 +174,52 @@ void keyboard_pad_handler::processKeyEvent(QKeyEvent* event, bool pressed) return; } + auto handleKey = [this, pressed, event]() + { + const QString name = qstr(GetKeyName(event)); + QStringList list = GetKeyNames(event); + if (list.isEmpty()) + return; + + bool is_num_key = list.contains("Num"); + if (is_num_key) + list.removeAll("Num"); + + // TODO: Edge case: switching numlock keeps numpad keys pressed due to now different modifier + + // Handle every possible key combination, for example: ctrl+A -> {ctrl, A, ctrl+A} + for (const auto& keyname : list) + { + // skip the 'original keys' when handling numpad keys + if (is_num_key && !keyname.contains("Num")) + continue; + // skip held modifiers when handling another key + if (keyname != name && list.count() > 1 && (keyname == "Alt" || keyname == "AltGr" || keyname == "Ctrl" || keyname == "Meta" || keyname == "Shift")) + continue; + Key(GetKeyCode(keyname), pressed); + } + }; + + // We need to ignore keys when using rpcs3 keyboard shortcuts int key = event->key(); switch (key) { + case Qt::Key_Escape: + break; case Qt::Key_L: case Qt::Key_Return: - if (!(event->modifiers() == Qt::AltModifier)) - Key(key, pressed); - break; - case Qt::Key_Escape: + if (event->modifiers() != Qt::AltModifier) + handleKey(); break; case Qt::Key_P: case Qt::Key_S: case Qt::Key_R: case Qt::Key_E: - if (!(event->modifiers() == Qt::ControlModifier)) - Key(key, pressed); + if (event->modifiers() != Qt::ControlModifier) + handleKey(); break; default: - int keymod = key + GetModifierCode(event); - if (keymod == key) - Key(keymod, pressed); - else - Key(key, pressed); + handleKey(); break; } event->ignore(); @@ -244,6 +267,62 @@ std::string keyboard_pad_handler::GetMouseName(u32 button) return "FAIL"; } +QStringList keyboard_pad_handler::GetKeyNames(const QKeyEvent* keyEvent) +{ + QStringList list; + + if (keyEvent->modifiers() & Qt::ShiftModifier) + { + list.append("Shift"); + list.append(QKeySequence(keyEvent->key() | Qt::ShiftModifier).toString(QKeySequence::NativeText)); + } + if (keyEvent->modifiers() & Qt::AltModifier) + { + list.append("Alt"); + list.append(QKeySequence(keyEvent->key() | Qt::AltModifier).toString(QKeySequence::NativeText)); + } + if (keyEvent->modifiers() & Qt::ControlModifier) + { + list.append("Ctrl"); + list.append(QKeySequence(keyEvent->key() | Qt::ControlModifier).toString(QKeySequence::NativeText)); + } + if (keyEvent->modifiers() & Qt::MetaModifier) + { + list.append("Meta"); + list.append(QKeySequence(keyEvent->key() | Qt::MetaModifier).toString(QKeySequence::NativeText)); + } + if (keyEvent->modifiers() & Qt::KeypadModifier) + { + list.append("Num"); // helper object, not used as actual key + list.append(QKeySequence(keyEvent->key() | Qt::KeypadModifier).toString(QKeySequence::NativeText)); + } + + switch (keyEvent->key()) + { + case Qt::Key_Alt: + list.append("Alt"); + break; + case Qt::Key_AltGr: + list.append("AltGr"); + break; + case Qt::Key_Shift: + list.append("Shift"); + break; + case Qt::Key_Control: + list.append("Ctrl"); + break; + case Qt::Key_Meta: + list.append("Meta"); + break; + default: + list.append(QKeySequence(keyEvent->key()).toString(QKeySequence::NativeText)); + break; + } + + list.removeDuplicates(); + return list; +} + std::string keyboard_pad_handler::GetKeyName(const QKeyEvent* keyEvent) { switch (keyEvent->key()) @@ -273,7 +352,14 @@ std::string keyboard_pad_handler::GetKeyName(const u32& keyCode) u32 keyboard_pad_handler::GetKeyCode(const std::string& keyName) { - if (keyName == "Alt") + return GetKeyCode(qstr(keyName)); +} + +u32 keyboard_pad_handler::GetKeyCode(const QString& keyName) +{ + if (keyName.isEmpty()) + return 0; + else if (keyName == "Alt") return Qt::Key_Alt; else if (keyName == "AltGr") return Qt::Key_AltGr; @@ -284,34 +370,14 @@ u32 keyboard_pad_handler::GetKeyCode(const std::string& keyName) else if (keyName == "Meta") return Qt::Key_Meta; - QString key = qstr(keyName); - QKeySequence seq(key); - u32 keyCode; - // We should only working with a single key here + QKeySequence seq(keyName); + u32 keyCode = 0; + if (seq.count() == 1) - { keyCode = seq[0]; - } else - { - // TODO: Maybe ditch this code - // Should be here only if a modifier key (e.g. Ctrl, Alt) is pressed. - if (seq.count() != 0) - { - LOG_ERROR(GENERAL, "GetKeyCode(%s): seq.count() != 0 . seq.count() = %d", keyName, seq.count()); - return 0; - } - // Add a non-modifier key "A" to the picture because QKeySequence - // seems to need that to acknowledge the modifier. We know that A has - // a keyCode of 65 (or 0x41 in hex) - seq = QKeySequence(key + "+A"); - if (seq.count() != 0 || seq[0] <= 65) - { - LOG_ERROR(GENERAL, "GetKeyCode(%s): seq.count() != 0 || seq[0] <= 65 . seq[0] = %d . seq.count() = %d", keyName, seq[0], seq.count()); - return 0; - } - keyCode = seq[0] - 65; - } + LOG_NOTICE(GENERAL, "GetKeyCode(%s): seq.count() = %d", sstr(keyName), seq.count()); + return keyCode; } diff --git a/rpcs3/keyboard_pad_handler.h b/rpcs3/keyboard_pad_handler.h index 27d84f6d4d..79d213ae6a 100644 --- a/rpcs3/keyboard_pad_handler.h +++ b/rpcs3/keyboard_pad_handler.h @@ -63,9 +63,11 @@ public: std::string GetMouseName(const QMouseEvent* event); std::string GetMouseName(u32 button); + QStringList GetKeyNames(const QKeyEvent* keyEvent); std::string GetKeyName(const QKeyEvent* keyEvent); std::string GetKeyName(const u32& keyCode); u32 GetKeyCode(const std::string& keyName); + u32 GetKeyCode(const QString& keyName); protected: void Key(const u32 code, bool pressed, u16 value = 255);