From a6ffdc2a8a7f2331dc4a76821ecf89588f0c7cd5 Mon Sep 17 00:00:00 2001 From: Johannes Schultz Date: Sat, 23 Nov 2024 23:46:14 +0000 Subject: [PATCH] [Fix] When restoring default keymaps, ignore cross-context conflicts. [Fix] Special key interception was broken, probably since r21616. [Mod] Special key interception is now only done when a shortcut was recognized. This means that e.g. Caps Lock will continue to work as normal outside of the pattern editor in a FT2-like keyboard setup. git-svn-id: https://source.openmpt.org/svn/openmpt/trunk/OpenMPT@22265 56274372-70c3-4bfc-bfc3-4c3a0b034d27 --- mptrack/CommandSet.cpp | 9 +++++++-- mptrack/InputHandler.cpp | 23 +++++++++++------------ mptrack/InputHandler.h | 2 +- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/mptrack/CommandSet.cpp b/mptrack/CommandSet.cpp index 38488b20925..211873e774e 100644 --- a/mptrack/CommandSet.cpp +++ b/mptrack/CommandSet.cpp @@ -2548,10 +2548,11 @@ void CCommandSet::ApplyDefaultKeybindings(KeyboardPreset preset, const Version o case KeyboardPreset::FT2: defaults = DefaultKeybindingsFT2; break; } + const bool onlyNewShortcuts = onlyCommandsAfterVersion != Version{}; CommandID lastAdded = kcNull; for(const auto &kb : defaults) { - if(onlyCommandsAfterVersion != Version{}) + if(onlyNewShortcuts) { if(kb.addedInVersion <= onlyCommandsAfterVersion) continue; @@ -2587,10 +2588,14 @@ void CCommandSet::ApplyDefaultKeybindings(KeyboardPreset preset, const Version o if(auto conflictCmd = IsConflicting(kc, kb.cmd, false); conflictCmd.first != kcNull) { + if(!onlyNewShortcuts && conflictCmd.second.Context() == kc.Context()) + continue; // Allow cross-context conflicts in case the newly added shortcut is in a more generic context // - unless the conflicting shortcut is the reserved dummy shortcut (which was used to prevent // default shortcuts from being added back before default key binding versioning was added). - if(conflictCmd.first == kcDummyShortcut || !m_isParentContext[kb.ctx][conflictCmd.second.Context()]) + if(conflictCmd.first == kcDummyShortcut) + continue; + if(onlyNewShortcuts && !m_isParentContext[kb.ctx][conflictCmd.second.Context()]) continue; } diff --git a/mptrack/InputHandler.cpp b/mptrack/InputHandler.cpp index e255a1d8aa8..e6d4c5f8def 100644 --- a/mptrack/InputHandler.cpp +++ b/mptrack/InputHandler.cpp @@ -94,12 +94,12 @@ CommandID CInputHandler::SendCommands(CWnd *wnd, const KeyMapRange &cmd) CommandID CInputHandler::KeyEvent(const InputTargetContext context, const KeyboardEvent &event, CWnd *pSourceWnd) { - if(InterceptSpecialKeys(event.key, event.flags, false)) - return kcDummyShortcut; if(IsKeyPressHandledByTextBox(event.key, ::GetFocus())) return kcNull; KeyMapRange cmd = m_keyMap.equal_range(KeyCombination(context, GetModifierMask(), event.key, event.keyEventType)); + if(cmd.first != cmd.second && InterceptSpecialKeys(event)) + return kcDummyShortcut; if(pSourceWnd == nullptr) pSourceWnd = m_pMainFrm; // By default, send command message to main frame. @@ -108,17 +108,16 @@ CommandID CInputHandler::KeyEvent(const InputTargetContext context, const Keyboa // Feature: use Windows keys as modifier keys, intercept special keys -bool CInputHandler::InterceptSpecialKeys(UINT nChar, UINT nFlags, bool generateMsg) +bool CInputHandler::InterceptSpecialKeys(const KeyboardEvent &event) { - KeyEventType keyEventType = GetKeyEventType(HIWORD(nFlags)); enum { VK_NonExistentKey = VK_F24+1 }; - if(nChar == VK_NonExistentKey) + if(event.key == VK_NonExistentKey) { return true; - } else if(m_bInterceptWindowsKeys && (nChar == VK_LWIN || nChar == VK_RWIN)) + } else if(m_bInterceptWindowsKeys && (event.key == VK_LWIN || event.key == VK_RWIN)) { - if(keyEventType == kKeyEventDown) + if(event.keyEventType == kKeyEventDown) { INPUT inp[2]; inp[0].type = inp[1].type = INPUT_KEYBOARD; @@ -132,22 +131,22 @@ bool CInputHandler::InterceptSpecialKeys(UINT nChar, UINT nFlags, bool generateM } } - if((nChar == VK_NUMLOCK && m_bInterceptNumLock) - || (nChar == VK_CAPITAL && m_bInterceptCapsLock) - || (nChar == VK_SCROLL && m_bInterceptScrollLock)) + if((event.key == VK_NUMLOCK && m_bInterceptNumLock) + || (event.key == VK_CAPITAL && m_bInterceptCapsLock) + || (event.key == VK_SCROLL && m_bInterceptScrollLock)) { if(GetMessageExtraInfo() == 0xC0FFEE) { SetMessageExtraInfo(0); return true; - } else if(keyEventType == kKeyEventDown && generateMsg) + } else if(event.keyEventType == kKeyEventDown) { // Prevent keys from lighting up by simulating a second press. INPUT inp[2]; inp[0].type = inp[1].type = INPUT_KEYBOARD; inp[0].ki.time = inp[1].ki.time = 0; inp[0].ki.dwExtraInfo = inp[1].ki.dwExtraInfo = 0xC0FFEE; - inp[0].ki.wVk = inp[1].ki.wVk = static_cast(nChar); + inp[0].ki.wVk = inp[1].ki.wVk = static_cast(event.key); inp[0].ki.wScan = inp[1].ki.wScan = 0; inp[0].ki.dwFlags = KEYEVENTF_KEYUP; inp[1].ki.dwFlags = 0; diff --git a/mptrack/InputHandler.h b/mptrack/InputHandler.h index 4cdb03e52be..c97da237696 100644 --- a/mptrack/InputHandler.h +++ b/mptrack/InputHandler.h @@ -52,7 +52,7 @@ class CInputHandler int GetKeyListSize(CommandID cmd) const; protected: - bool InterceptSpecialKeys(UINT nChar, UINT nFlags, bool generateMsg); + bool InterceptSpecialKeys(const KeyboardEvent &event); void SetupSpecialKeyInterception(); CommandID SendCommands(CWnd *wnd, const KeyMapRange &cmd);