mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-08 20:27:36 +02:00
[Keyboard Manager] Alt+Tab navigation with arrow keys i (#12986)
* Draft # Conflicts: # src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardEventHandlers.cpp * Handle key case * Fix key count * Remember if win key was pressed * Don't search twice, remove redundant assignment * spelling
This commit is contained in:
@@ -579,46 +579,90 @@ namespace KeyboardEventHandlers
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t key_count;
|
size_t key_count;
|
||||||
LPINPUT keyEventList;
|
LPINPUT keyEventList = nullptr;
|
||||||
|
|
||||||
|
// Check if a new remapping should be applied
|
||||||
|
Shortcut currentlyPressed = it->first;
|
||||||
|
currentlyPressed.actionKey = data->lParam->vkCode;
|
||||||
|
auto newRemappingIter = reMap.find(currentlyPressed);
|
||||||
|
if (newRemappingIter != reMap.end())
|
||||||
|
{
|
||||||
|
auto& newRemapping = newRemappingIter->second;
|
||||||
|
Shortcut from = std::get<Shortcut>(it->second.targetShortcut);
|
||||||
|
if (newRemapping.RemapToKey())
|
||||||
|
{
|
||||||
|
DWORD to = std::get<0>(newRemapping.targetShortcut);
|
||||||
|
key_count = from.Size() - 1 + 1;
|
||||||
|
keyEventList = new INPUT[key_count]();
|
||||||
|
memset(keyEventList, 0, sizeof(keyEventList));
|
||||||
|
int i = 0;
|
||||||
|
Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||||
|
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)to, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
Shortcut to = std::get<Shortcut>(newRemapping.targetShortcut);
|
||||||
|
key_count = from.Size() - 1 + to.Size() - 1 - 2* from.GetCommonModifiersCount(to) + 1;
|
||||||
|
keyEventList = new INPUT[key_count]();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, to);
|
||||||
|
Helpers::SetModifierKeyEvents(to, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, from);
|
||||||
|
|
||||||
|
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)to.actionKey, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||||
|
newRemapping.isShortcutInvoked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember which win key was pressed initially
|
||||||
|
if (ii.GetVirtualKeyState(VK_RWIN))
|
||||||
|
{
|
||||||
|
newRemapping.winKeyInvoked = ModifierKey::Right;
|
||||||
|
}
|
||||||
|
else if (ii.GetVirtualKeyState(VK_LWIN))
|
||||||
|
{
|
||||||
|
newRemapping.winKeyInvoked = ModifierKey::Left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated
|
// Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated
|
||||||
key_count = (dest_size) + (src_size - 1) - (2 * (size_t)commonKeys);
|
key_count = (dest_size) + (src_size - 1) - (2 * (size_t)commonKeys);
|
||||||
|
|
||||||
// If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set
|
// If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set
|
||||||
bool isActionKeyPressed = false;
|
bool isActionKeyPressed = false;
|
||||||
if (ii.GetVirtualKeyState((std::get<Shortcut>(it->second.targetShortcut).GetActionKey())))
|
if (ii.GetVirtualKeyState((std::get<Shortcut>(it->second.targetShortcut).GetActionKey())))
|
||||||
{
|
{
|
||||||
isActionKeyPressed = true;
|
isActionKeyPressed = true;
|
||||||
key_count += 2;
|
key_count += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
keyEventList = new INPUT[key_count]();
|
keyEventList = new INPUT[key_count]();
|
||||||
memset(keyEventList, 0, sizeof(keyEventList));
|
memset(keyEventList, 0, sizeof(keyEventList));
|
||||||
|
|
||||||
// Release new shortcut state (release in reverse order of shortcut to be accurate)
|
// Release new shortcut state (release in reverse order of shortcut to be accurate)
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (isActionKeyPressed)
|
if (isActionKeyPressed)
|
||||||
{
|
{
|
||||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
|
||||||
|
|
||||||
|
// Set old shortcut key down state
|
||||||
|
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
|
||||||
|
|
||||||
|
// key down for original shortcut action key with shortcut flag so that we don't invoke the same shortcut remap again
|
||||||
|
if (isActionKeyPressed)
|
||||||
|
{
|
||||||
|
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut
|
||||||
|
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
// Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after shortcut to shortcut is released to open start menu
|
||||||
}
|
}
|
||||||
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
|
|
||||||
|
|
||||||
// Set old shortcut key down state
|
|
||||||
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
|
|
||||||
|
|
||||||
// key down for original shortcut action key with shortcut flag so that we don't invoke the same shortcut remap again
|
|
||||||
if (isActionKeyPressed)
|
|
||||||
{
|
|
||||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut
|
|
||||||
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0);
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after shortcut to shortcut is released to open start menu
|
|
||||||
|
|
||||||
// Reset the remap state
|
// Reset the remap state
|
||||||
it->second.isShortcutInvoked = false;
|
it->second.isShortcutInvoked = false;
|
||||||
|
|||||||
@@ -26,4 +26,9 @@ public:
|
|||||||
{
|
{
|
||||||
return targetShortcut == sc.targetShortcut && isShortcutInvoked == sc.isShortcutInvoked && winKeyInvoked == sc.winKeyInvoked;
|
return targetShortcut == sc.targetShortcut && isShortcutInvoked == sc.isShortcutInvoked && winKeyInvoked == sc.winKeyInvoked;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RemapToKey()
|
||||||
|
{
|
||||||
|
return targetShortcut.index() == 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user