[KBM] decoupling editor and engine (#11133)

This commit is contained in:
Mykhailo Pylyp
2021-05-07 11:16:31 +03:00
committed by GitHub
parent 9461909321
commit 8785fca309
77 changed files with 2509 additions and 2775 deletions

View File

@@ -3,7 +3,6 @@
#include <common/interop/shared_constants.h>
#include <keyboardmanager/common/KeyboardManagerState.h>
#include <keyboardmanager/common/InputInterface.h>
#include <keyboardmanager/common/Helpers.h>
#include <keyboardmanager/KeyboardManagerEngineLibrary/trace.h>
@@ -11,12 +10,12 @@
namespace KeyboardEventHandlers
{
// Function to a handle a single key remap
intptr_t HandleSingleKeyRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept
intptr_t HandleSingleKeyRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept
{
// Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.
if (!(data->lParam->dwExtraInfo & CommonSharedConstants::KEYBOARDMANAGER_INJECTED_FLAG))
{
const auto remapping = keyboardManagerState.GetSingleKeyRemap(data->lParam->vkCode);
const auto remapping = state.GetSingleKeyRemap(data->lParam->vkCode);
if (remapping)
{
auto it = remapping.value();
@@ -50,11 +49,11 @@ namespace KeyboardEventHandlers
DWORD target;
if (remapToKey)
{
target = KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second));
target = Helpers::FilterArtificialKeys(std::get<DWORD>(it->second));
}
else
{
target = KeyboardManagerHelper::FilterArtificialKeys(std::get<Shortcut>(it->second).GetActionKey());
target = Helpers::FilterArtificialKeys(std::get<Shortcut>(it->second).GetActionKey());
}
// If Ctrl/Alt/Shift is being remapped to Caps Lock, then reset the modifier key state to fix issues in certain IME keyboards where the IME shortcut gets invoked since it detects that the modifier and Caps Lock is pressed even though it is suppressed by the hook - More information at the GitHub issue https://github.com/microsoft/PowerToys/issues/3397
@@ -67,11 +66,11 @@ namespace KeyboardEventHandlers
{
if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
}
else
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
}
}
else
@@ -80,16 +79,16 @@ namespace KeyboardEventHandlers
Shortcut targetShortcut = std::get<Shortcut>(it->second);
if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
i++;
KeyboardManagerHelper::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
// Dummy key is not required here since SetModifierKeyEvents will only add key-up events for the modifiers here, and the action key key-up is already sent before it
}
else
{
// Dummy key is not required here since SetModifierKeyEvents will only add key-down events for the modifiers here, and the action key key-down is already sent after it
KeyboardManagerHelper::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)targetShortcut.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
i++;
}
}
@@ -127,22 +126,22 @@ namespace KeyboardEventHandlers
/* This feature has not been enabled (code from proof of concept stage)
*
// Function to a change a key's behavior from toggle to modifier
__declspec(dllexport) intptr_t HandleSingleKeyToggleToModEvent(InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept
__declspec(dllexport) intptr_t HandleSingleKeyToggleToModEvent(InputInterface& ii, LowlevelKeyboardEvent* data, State& State) noexcept
{
// Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.
if (!(data->lParam->dwExtraInfo & CommonSharedConstants::KEYBOARDMANAGER_INJECTED_FLAG))
{
// The mutex should be unlocked before SendInput is called to avoid re-entry into the same mutex. More details can be found at https://github.com/microsoft/PowerToys/pull/1789#issuecomment-607555837
std::unique_lock<std::mutex> lock(keyboardManagerState.singleKeyToggleToMod_mutex);
auto it = keyboardManagerState.singleKeyToggleToMod.find(data->lParam->vkCode);
if (it != keyboardManagerState.singleKeyToggleToMod.end())
std::unique_lock<std::mutex> lock(State.singleKeyToggleToMod_mutex);
auto it = State.singleKeyToggleToMod.find(data->lParam->vkCode);
if (it != State.singleKeyToggleToMod.end())
{
// To avoid long presses (which leads to continuous keydown messages) from toggling the key on and off
if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)
{
if (it->second == false)
{
keyboardManagerState.singleKeyToggleToMod[data->lParam->vkCode] = true;
State.singleKeyToggleToMod[data->lParam->vkCode] = true;
}
else
{
@@ -153,8 +152,8 @@ namespace KeyboardEventHandlers
int key_count = 2;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
KeyboardManagerHelper::SetKeyEvent(keyEventList, 1, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
Helpers::SetKeyEvent(keyEventList, 1, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
lock.unlock();
UINT res = ii.SendVirtualInput(key_count, keyEventList, sizeof(INPUT));
@@ -164,7 +163,7 @@ namespace KeyboardEventHandlers
if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
lock.lock();
keyboardManagerState.singleKeyToggleToMod[data->lParam->vkCode] = false;
State.singleKeyToggleToMod[data->lParam->vkCode] = false;
lock.unlock();
}
@@ -177,16 +176,16 @@ namespace KeyboardEventHandlers
*/
// Function to a handle a shortcut remap
intptr_t HandleShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState, const std::optional<std::wstring>& activatedApp) noexcept
intptr_t HandleShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state, const std::optional<std::wstring>& activatedApp) noexcept
{
// Check if any shortcut is currently in the invoked state
bool isShortcutInvoked = keyboardManagerState.CheckShortcutRemapInvoked(activatedApp);
bool isShortcutInvoked = state.CheckShortcutRemapInvoked(activatedApp);
// Get shortcut table for given activatedApp
ShortcutRemapTable& reMap = keyboardManagerState.GetShortcutRemapTable(activatedApp);
ShortcutRemapTable& reMap = state.GetShortcutRemapTable(activatedApp);
// Iterate through the shortcut remaps and apply whichever has been pressed
for (auto& itShortcut : keyboardManagerState.GetSortedShortcutRemapVector(activatedApp))
for (auto& itShortcut : state.GetSortedShortcutRemapVector(activatedApp))
{
const auto it = reMap.find(itShortcut);
@@ -239,8 +238,8 @@ namespace KeyboardEventHandlers
keyEventList = new INPUT[key_count]();
memset(keyEventList, 0, sizeof(keyEventList));
int i = 0;
KeyboardManagerHelper::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
}
else
@@ -252,14 +251,14 @@ namespace KeyboardEventHandlers
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it
int i = 0;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Release original shortcut state (release in reverse order of shortcut to be accurate)
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
// Set new shortcut key down state
KeyboardManagerHelper::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
}
@@ -291,22 +290,22 @@ namespace KeyboardEventHandlers
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it
int i = 0;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Release original shortcut state (release in reverse order of shortcut to be accurate)
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Set target key down state
if (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
}
// Modifier state reset might be required for this key depending on the shortcut's action and target modifier - ex: Win+Caps -> Ctrl
if (it->first.GetCtrlKey() == NULL && it->first.GetAltKey() == NULL && it->first.GetShiftKey() == NULL)
{
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), data->lParam->vkCode);
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), data->lParam->vkCode);
}
}
@@ -314,7 +313,7 @@ namespace KeyboardEventHandlers
// If app specific shortcut is invoked, store the target application
if (activatedApp)
{
keyboardManagerState.SetActivatedApp(*activatedApp);
state.SetActivatedApp(*activatedApp);
}
UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT));
@@ -375,16 +374,16 @@ namespace KeyboardEventHandlers
int i = 0;
if (isActionKeyPressed)
{
KeyboardManagerHelper::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++;
}
KeyboardManagerHelper::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first, data->lParam->vkCode);
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first, data->lParam->vkCode);
// Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate it's own key message
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut), data->lParam->vkCode);
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut), data->lParam->vkCode);
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->Ctrl+V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
else
{
@@ -397,7 +396,7 @@ namespace KeyboardEventHandlers
{
key_count--;
}
else if (ii.GetVirtualKeyState(KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))))
else if (ii.GetVirtualKeyState(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))))
{
isTargetKeyPressed = true;
}
@@ -414,15 +413,15 @@ namespace KeyboardEventHandlers
int i = 0;
if (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED && isTargetKeyPressed)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
}
// Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate it's own key message
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, Shortcut(), data->lParam->vkCode);
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, Shortcut(), data->lParam->vkCode);
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
// Reset the remap state
@@ -433,7 +432,7 @@ namespace KeyboardEventHandlers
// If app specific shortcut has finished invoking, reset the target application
if (activatedApp)
{
keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
}
// key count can be 0 if both shortcuts have same modifiers and the action key is not held down. delete will throw an error if keyEventList is empty
@@ -464,11 +463,11 @@ namespace KeyboardEventHandlers
memset(keyEventList, 0, sizeof(keyEventList));
if (remapToShortcut)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
else
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT));
@@ -485,7 +484,7 @@ namespace KeyboardEventHandlers
{
keyEventList = new INPUT[key_count]();
memset(keyEventList, 0, sizeof(keyEventList));
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)std::get<Shortcut>(it->second.targetShortcut).GetActionKey(), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
else if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
{
@@ -497,14 +496,14 @@ namespace KeyboardEventHandlers
else
{
// Check if the keyboard state is clear apart from the target remap key (by creating a temp Shortcut object with the target key)
bool isKeyboardStateClear = Shortcut(std::vector<int32_t>({ KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii);
bool isKeyboardStateClear = Shortcut(std::vector<int32_t>({ Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii);
// If the keyboard state is clear, we release the target key but do not reset the remap state
if (isKeyboardStateClear)
{
keyEventList = new INPUT[key_count]();
memset(keyEventList, 0, sizeof(keyEventList));
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
else
{
@@ -519,14 +518,14 @@ namespace KeyboardEventHandlers
// Release new key state
int i = 0;
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
// Set original shortcut key down state except the action key
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Reset the remap state
it->second.isShortcutInvoked = false;
@@ -536,7 +535,7 @@ namespace KeyboardEventHandlers
// If app specific shortcut has finished invoking, reset the target application
if (activatedApp != KeyboardManagerConstants::NoActivatedApp)
{
keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
}
}
}
@@ -561,7 +560,7 @@ namespace KeyboardEventHandlers
{
// If it is not remapped to Disable
// Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));
}
// Suppress the modifier as it is already physically pressed
@@ -601,20 +600,20 @@ namespace KeyboardEventHandlers
int i = 0;
if (isActionKeyPressed)
{
KeyboardManagerHelper::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++;
}
KeyboardManagerHelper::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
// key down for original shortcut action key with shortcut flag so that we don't invoke the same shortcut remap again
if (isActionKeyPressed)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
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
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0);
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
@@ -639,23 +638,23 @@ namespace KeyboardEventHandlers
int i = 0;
if (isActionKeyPressed)
{
KeyboardManagerHelper::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++;
}
KeyboardManagerHelper::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, i, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);
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
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));
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)
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
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
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0);
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
@@ -669,7 +668,7 @@ namespace KeyboardEventHandlers
// If app specific shortcut has finished invoking, reset the target application
if (activatedApp)
{
keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
}
UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT));
@@ -681,7 +680,7 @@ namespace KeyboardEventHandlers
// For remap to key, if the original action key is not currently pressed, we should revert the keyboard state to the physical keys. If it is pressed we should not suppress the event so that shortcut to key remaps can be pressed with other keys. Example use-case: Alt+D->Win, allows Alt+D+A to perform Win+A
// Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps, Shift is pressed. System should not see Shift and Caps pressed together
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));
ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));
// If the shortcut is remapped to Disable then we have to revert the keyboard state to the physical keys
bool isRemapToDisable = (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED);
@@ -690,7 +689,7 @@ namespace KeyboardEventHandlers
if (!isRemapToDisable)
{
// If the remap target key is currently pressed, then we do not have to revert the keyboard state to the physical keys
if (ii.GetVirtualKeyState((KeyboardManagerHelper::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)))))
if (ii.GetVirtualKeyState((Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)))))
{
isOriginalActionKeyPressed = true;
}
@@ -710,13 +709,13 @@ namespace KeyboardEventHandlers
// Set original shortcut key down state
int i = 0;
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Send the original action key only if it is physically pressed. For remappings to keys other than disabled we already check earlier that it is not pressed in this scenario. For remap to disable
if (isRemapToDisable && isOriginalActionKeyPressed)
{
// Set original action key
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
Helpers::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)it->first.GetActionKey(), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
}
else
@@ -725,7 +724,7 @@ namespace KeyboardEventHandlers
}
// Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, 0);
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 another shortcut to key remap is released to open start menu
@@ -738,7 +737,7 @@ namespace KeyboardEventHandlers
// If app specific shortcut has finished invoking, reset the target application
if (activatedApp != KeyboardManagerConstants::NoActivatedApp)
{
keyboardManagerState.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);
}
UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT));
@@ -760,12 +759,12 @@ namespace KeyboardEventHandlers
}
// Function to a handle an os-level shortcut remap
intptr_t HandleOSLevelShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept
intptr_t HandleOSLevelShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept
{
// Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.
if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG)
{
bool result = HandleShortcutRemapEvent(ii, data, keyboardManagerState);
bool result = HandleShortcutRemapEvent(ii, data, state);
return result;
}
@@ -773,7 +772,7 @@ namespace KeyboardEventHandlers
}
// Function to a handle an app-specific shortcut remap
intptr_t HandleAppSpecificShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept
intptr_t HandleAppSpecificShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept
{
// Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.
if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG)
@@ -800,29 +799,29 @@ namespace KeyboardEventHandlers
AppSpecificShortcutRemapTable::iterator it;
// Check if an app-specific shortcut is already activated
if (keyboardManagerState.GetActivatedApp() == KeyboardManagerConstants::NoActivatedApp)
if (state.GetActivatedApp() == KeyboardManagerConstants::NoActivatedApp)
{
query_string = process_name;
it = keyboardManagerState.appSpecificShortcutReMap.find(query_string);
it = state.appSpecificShortcutReMap.find(query_string);
// If no entry is found, search for the process name without it's file extension
if (it == keyboardManagerState.appSpecificShortcutReMap.end())
if (it == state.appSpecificShortcutReMap.end())
{
// Find index of the file extension
size_t extensionIndex = process_name.find_last_of(L".");
query_string = process_name.substr(0, extensionIndex);
it = keyboardManagerState.appSpecificShortcutReMap.find(query_string);
it = state.appSpecificShortcutReMap.find(query_string);
}
}
else
{
query_string = keyboardManagerState.GetActivatedApp();
it = keyboardManagerState.appSpecificShortcutReMap.find(query_string);
query_string = state.GetActivatedApp();
it = state.appSpecificShortcutReMap.find(query_string);
}
if (it != keyboardManagerState.appSpecificShortcutReMap.end())
if (it != state.appSpecificShortcutReMap.end())
{
bool result = HandleShortcutRemapEvent(ii, data, keyboardManagerState, query_string);
bool result = HandleShortcutRemapEvent(ii, data, state, query_string);
return result;
}
}
@@ -837,14 +836,14 @@ namespace KeyboardEventHandlers
if (target == VK_CAPITAL)
{
// If the argument is either of the Ctrl/Shift/Alt modifier key codes
if (KeyboardManagerHelper::IsModifierKey(key) && !(key == VK_LWIN || key == VK_RWIN || key == CommonSharedConstants::VK_WIN_BOTH))
if (Helpers::IsModifierKey(key) && !(key == VK_LWIN || key == VK_RWIN || key == CommonSharedConstants::VK_WIN_BOTH))
{
int key_count = 1;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
// Use the suppress flag to ensure these are not intercepted by any remapped keys or shortcuts
KeyboardManagerHelper::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)key, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG);
Helpers::SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)key, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG);
UINT res = ii.SendVirtualInput((UINT)key_count, keyEventList, sizeof(INPUT));
delete[] keyEventList;
}

View File

@@ -1,32 +1,31 @@
#pragma once
#include <common/hooks/LowlevelKeyboardEvent.h>
#include "State.h"
namespace KeyboardManagerInput
{
class InputInterface;
}
class KeyboardManagerState;
namespace KeyboardEventHandlers
{
// Function to a handle a single key remap
intptr_t HandleSingleKeyRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept;
intptr_t HandleSingleKeyRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept;
/* This feature has not been enabled (code from proof of concept stage)
// Function to a change a key's behavior from toggle to modifier
__declspec(dllexport) intptr_t HandleSingleKeyToggleToModEvent(InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept;
__declspec(dllexport) intptr_t HandleSingleKeyToggleToModEvent(InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept;
*/
// Function to a handle a shortcut remap
intptr_t HandleShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState, const std::optional<std::wstring>& activatedApp = std::nullopt) noexcept;
intptr_t HandleShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state, const std::optional<std::wstring>& activatedApp = std::nullopt) noexcept;
// Function to a handle an os-level shortcut remap
intptr_t HandleOSLevelShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept;
intptr_t HandleOSLevelShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept;
// Function to a handle an app-specific shortcut remap
intptr_t HandleAppSpecificShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, KeyboardManagerState& keyboardManagerState) noexcept;
intptr_t HandleAppSpecificShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept;
// Function to ensure Ctrl/Shift/Alt modifier key state is not detected as pressed down by applications which detect keys at a lower level than hooks when it is remapped for scenarios where its required
void ResetIfModifierKeyForLowerLevelKeyHandlers(KeyboardManagerInput::InputInterface& ii, DWORD key, DWORD target);

View File

@@ -12,7 +12,6 @@
#include <keyboardmanager/common/KeyboardManagerConstants.h>
#include <keyboardmanager/common/Helpers.h>
#include <keyboardmanager/common/KeyboardEventHandlers.h>
#include <keyboardmanager/common/SettingsHelper.h>
#include <ctime>
#include "KeyboardEventHandlers.h"
@@ -56,13 +55,13 @@ KeyboardManager::KeyboardManager()
void KeyboardManager::LoadSettings()
{
bool loadedSuccessful = SettingsHelper::LoadSettings(keyboardManagerState);
bool loadedSuccessful = state.LoadSettings();
if (!loadedSuccessful)
{
std::this_thread::sleep_for(std::chrono::milliseconds(500));
// retry once
SettingsHelper::LoadSettings(keyboardManagerState);
state.LoadSettings();
}
}
@@ -140,7 +139,7 @@ intptr_t KeyboardManager::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) n
}
// Remap a key
intptr_t SingleKeyRemapResult = KeyboardEventHandlers::HandleSingleKeyRemapEvent(inputHandler, data, keyboardManagerState);
intptr_t SingleKeyRemapResult = KeyboardEventHandlers::HandleSingleKeyRemapEvent(inputHandler, data, state);
// Single key remaps have priority. If a key is remapped, only the remapped version should be visible to the shortcuts and hence the event should be suppressed here.
if (SingleKeyRemapResult == 1)
@@ -154,7 +153,7 @@ intptr_t KeyboardManager::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) n
*/
// Handle an app-specific shortcut remapping
intptr_t AppSpecificShortcutRemapResult = KeyboardEventHandlers::HandleAppSpecificShortcutRemapEvent(inputHandler, data, keyboardManagerState);
intptr_t AppSpecificShortcutRemapResult = KeyboardEventHandlers::HandleAppSpecificShortcutRemapEvent(inputHandler, data, state);
// If an app-specific shortcut is remapped then the os-level shortcut remapping should be suppressed.
if (AppSpecificShortcutRemapResult == 1)
@@ -163,5 +162,5 @@ intptr_t KeyboardManager::HandleKeyboardHookEvent(LowlevelKeyboardEvent* data) n
}
// Handle an os-level shortcut remapping
return KeyboardEventHandlers::HandleOSLevelShortcutRemapEvent(inputHandler, data, keyboardManagerState);
return KeyboardEventHandlers::HandleOSLevelShortcutRemapEvent(inputHandler, data, state);
}

View File

@@ -1,7 +1,8 @@
#pragma once
#include <common/hooks/LowlevelKeyboardEvent.h>
#include <common/utils/EventWaiter.h>
#include <keyboardmanager/common/KeyboardManagerState.h>
#include <keyboardmanager/common/Input.h>
#include "State.h"
class KeyboardManager
{
@@ -27,7 +28,7 @@ private:
static KeyboardManager* keyboardManagerObjectPtr;
// Variable which stores all the state information to be shared between the UI and back-end
KeyboardManagerState keyboardManagerState;
State state;
// Object of class which implements InputInterface. Required for calling library functions while enabling testing
KeyboardManagerInput::Input inputHandler;

View File

@@ -36,6 +36,7 @@
<ClInclude Include="KeyboardEventHandlers.h" />
<ClInclude Include="KeyboardManager.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="State.h" />
<ClInclude Include="trace.h" />
</ItemGroup>
<ItemGroup>
@@ -44,11 +45,17 @@
<ClCompile Include="pch.cpp">
<PrecompiledHeader>Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="State.cpp" />
<ClCompile Include="trace.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\common\KeyboardManagerCommon.vcxproj">
<Project>{8affa899-0b73-49ec-8c50-0fadda57b2fc}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="..\..\..\..\deps\spdlog.props" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -27,6 +27,9 @@
<ClInclude Include="KeyboardEventHandlers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="State.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">
@@ -41,6 +44,9 @@
<ClCompile Include="KeyboardEventHandlers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="State.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />

View File

@@ -0,0 +1,63 @@
#include "pch.h"
#include "State.h"
#include <optional>
// Function to get the iterator of a single key remap given the source key. Returns nullopt if it isn't remapped
std::optional<SingleKeyRemapTable::iterator> State::GetSingleKeyRemap(const DWORD& originalKey)
{
auto it = singleKeyReMap.find(originalKey);
if (it != singleKeyReMap.end())
{
return it;
}
return std::nullopt;
}
bool State::CheckShortcutRemapInvoked(const std::optional<std::wstring>& appName)
{
// Assumes appName exists in the app-specific remap table
ShortcutRemapTable& currentRemapTable = appName ? appSpecificShortcutReMap[*appName] : osLevelShortcutReMap;
for (auto& it : currentRemapTable)
{
if (it.second.isShortcutInvoked)
{
return true;
}
}
return false;
}
// Function to get the source and target of a shortcut remap given the source shortcut. Returns nullopt if it isn't remapped
ShortcutRemapTable& State::GetShortcutRemapTable(const std::optional<std::wstring>& appName)
{
if (appName)
{
auto itTable = appSpecificShortcutReMap.find(*appName);
if (itTable != appSpecificShortcutReMap.end())
{
return itTable->second;
}
}
return osLevelShortcutReMap;
}
std::vector<Shortcut>& State::GetSortedShortcutRemapVector(const std::optional<std::wstring>& appName)
{
// Assumes appName exists in the app-specific remap table
return appName ? appSpecificShortcutReMapSortedKeys[*appName] : osLevelShortcutReMapSortedKeys;
}
// Sets the activated target application in app-specific shortcut
void State::SetActivatedApp(const std::wstring& appName)
{
activatedAppSpecificShortcutTarget = appName;
}
// Gets the activated target application in app-specific shortcut
std::wstring State::GetActivatedApp()
{
return activatedAppSpecificShortcutTarget;
}

View File

@@ -0,0 +1,26 @@
#pragma once
#include <keyboardmanager/common/MappingConfiguration.h>
class State : public MappingConfiguration
{
private:
// Stores the activated target application in app-specific shortcut
std::wstring activatedAppSpecificShortcutTarget;
public:
// Function to get the iterator of a single key remap given the source key. Returns nullopt if it isn't remapped
std::optional<SingleKeyRemapTable::iterator> GetSingleKeyRemap(const DWORD& originalKey);
bool CheckShortcutRemapInvoked(const std::optional<std::wstring>& appName);
// Function to get the source and target of a shortcut remap given the source shortcut. Returns nullopt if it isn't remapped
ShortcutRemapTable& GetShortcutRemapTable(const std::optional<std::wstring>& appName);
std::vector<Shortcut>& GetSortedShortcutRemapVector(const std::optional<std::wstring>& appName);
// Sets the activated target application in app-specific shortcut
void SetActivatedApp(const std::wstring& appName);
// Gets the activated target application in app-specific shortcut
std::wstring GetActivatedApp();
};