Skip to content

Commit a1aa435

Browse files
[KBM]Fix some chord repetition quirks(#31636)
1 parent 70d790c commit a1aa435

File tree

1 file changed

+46
-7
lines changed

1 file changed

+46
-7
lines changed

src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardEventHandlers.cpp

+46-7
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,18 @@ namespace KeyboardEventHandlers
271271
continue;
272272
}
273273

274-
if (data->lParam->vkCode == itShortcut.GetSecondKey() && itShortcut.IsChordStarted() && itShortcut.HasChord())
274+
if (itShortcut.IsChordStarted() && itShortcut.HasChord())
275275
{
276-
Logger::trace(L"ChordKeyboardHandler:found chord match {}, {}", itShortcut.GetActionKey(), itShortcut.GetSecondKey());
277-
isMatchOnChordEnd = true;
276+
if (data->lParam->vkCode == itShortcut.GetSecondKey())
277+
{
278+
Logger::trace(L"ChordKeyboardHandler:found chord match {}, {}", itShortcut.GetActionKey(), itShortcut.GetSecondKey());
279+
isMatchOnChordEnd = true;
280+
}
281+
// Resets chord status for the shortcut. A key was pressed and we registered if it was the end of the chord. We can reset it.
282+
if (data->lParam->vkCode != itShortcut.GetActionKey())
283+
{
284+
itShortcut.SetChordStarted(false);
285+
}
278286
}
279287

280288
if (resetChordsResults.AnyChordStarted && !isMatchOnChordEnd)
@@ -670,7 +678,7 @@ namespace KeyboardEventHandlers
670678
if (!remapToShortcut || (remapToShortcut && std::get<Shortcut>(it->second.targetShortcut).CheckModifiersKeyboardState(ii)))
671679
{
672680
// Case 2: If the original shortcut is still held down the keyboard will get a key down message of the action key in the original shortcut and the new shortcut's modifiers will be held down (keys held down send repeated keydown messages)
673-
if (data->lParam->vkCode == it->first.GetActionKey() && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))
681+
if (((data->lParam->vkCode == it->first.GetActionKey() && !it->first.HasChord())||(data->lParam->vkCode == it->first.GetSecondKey() && it->first.HasChord())) && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))
674682
{
675683
// In case of mapping to disable do not send anything
676684
if (remapToKey && std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
@@ -716,15 +724,46 @@ namespace KeyboardEventHandlers
716724
}
717725

718726
// Case 3: If the action key is released from the original shortcut, keep modifiers of the new shortcut until some other key event which doesn't apply to the original shortcut
719-
if (!remapToText && data->lParam->vkCode == it->first.GetActionKey() && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))
727+
if (!remapToText && ((!it->first.HasChord() && data->lParam->vkCode == it->first.GetActionKey()) || (it->first.HasChord() && data->lParam->vkCode==it->first.GetSecondKey())) && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))
720728
{
721729
size_t key_count = 1;
722730
LPINPUT keyEventList = nullptr;
723-
if (remapToShortcut)
731+
if (remapToShortcut && !it->first.HasChord())
724732
{
733+
// Just lift the action key for no chords.
725734
keyEventList = new INPUT[key_count]{};
726735
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
727736
}
737+
else if (remapToShortcut && it->first.HasChord())
738+
{
739+
// If it has a chord, we'll want a full clean contemplated in the else, since you can't really repeat chords by pressing the end key again.
740+
741+
// Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated
742+
key_count = (dest_size) + (src_size +1) - (2 * static_cast<size_t>(commonKeys));
743+
int i = 0;
744+
745+
keyEventList = new INPUT[key_count]{};
746+
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
747+
i++;
748+
749+
// Release new shortcut state (release in reverse order of shortcut to be accurate)
750+
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
751+
752+
// Set old shortcut key down state
753+
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
754+
755+
// Reset the remap state
756+
it->second.isShortcutInvoked = false;
757+
it->second.winKeyInvoked = ModifierKey::Disabled;
758+
it->second.isOriginalActionKeyPressed = false;
759+
760+
// If app specific shortcut has finished invoking, reset the target application
761+
if (activatedApp)
762+
{
763+
state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
764+
}
765+
766+
}
728767
else if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
729768
{
730769
// If remapped to disable, do nothing and suppress the key event
@@ -822,7 +861,7 @@ namespace KeyboardEventHandlers
822861
Shortcut currentlyPressed = it->first;
823862
currentlyPressed.actionKey = data->lParam->vkCode;
824863
auto newRemappingIter = reMap.find(currentlyPressed);
825-
if (newRemappingIter != reMap.end())
864+
if (newRemappingIter != reMap.end() && !newRemappingIter->first.HasChord())
826865
{
827866
auto& newRemapping = newRemappingIter->second;
828867
Shortcut from = std::get<Shortcut>(it->second.targetShortcut);

0 commit comments

Comments
 (0)