Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,10 @@ namespace KeyboardEventHandlers

// 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);

// Function to check previous modifier key with state
bool CheckPreviousModifierKey(const ShortcutRemapTable::iterator it, std::vector<DWORD> previousKeys);

// Function to set previous modifier key to state
void SetPreviousModifierKey(const ShortcutRemapTable::iterator it, const DWORD key, State& state);
};
42 changes: 42 additions & 0 deletions src/modules/keyboardmanager/KeyboardManagerEngineLibrary/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,45 @@ std::wstring State::GetActivatedApp()
{
return activatedAppSpecificShortcutTarget;
}

// Sets the previous action key to use in another shortcut
void State::SetPreviousActionKey(const DWORD prevKey)
{
previousActionKey = prevKey;
}

// Gets the previous action key
DWORD State::GetPreviousActionKey()
{
return previousActionKey;
}

// Sets the previous modifier key to check in another shortcut
void State::SetPreviousModifierKey(const DWORD prevKey)
{
previousModifierKey.emplace_back(prevKey);
}

// Gets the previous modifier key
std::vector<DWORD> State::GetPreviousModifierKey()
{
return previousModifierKey;
}

// Check if a key exists in the previousModifierKey vector
bool State::FindPreviousModifierKey(const DWORD prevKey)
{
return std::find(previousModifierKey.begin(), previousModifierKey.end(), prevKey) != previousModifierKey.end();
}

// Resets the previous modifier key
void State::ResetPreviousModifierKey(const DWORD prevKey)
{
previousModifierKey.erase(std::remove(previousModifierKey.begin(), previousModifierKey.end(), prevKey), previousModifierKey.end());
}

// Clear all previous modifier key
void State::ClearPreviousModifierKey()
{
previousModifierKey.clear();
}
25 changes: 25 additions & 0 deletions src/modules/keyboardmanager/KeyboardManagerEngineLibrary/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ class State : public MappingConfiguration
private:
// Stores the activated target application in app-specific shortcut
std::wstring activatedAppSpecificShortcutTarget;
// Stores the previous action key
DWORD previousActionKey = {};
// Stores the previous modifier key
std::vector<DWORD> previousModifierKey;

public:
// Function to get the iterator of a single key remap given the source key. Returns nullopt if it isn't remapped
Expand All @@ -26,4 +30,25 @@ class State : public MappingConfiguration

// Gets the activated target application in app-specific shortcut
std::wstring GetActivatedApp();

// Sets the previous action key to use in another shortcut
void SetPreviousActionKey(const DWORD prevKey);

// Gets the previous action key
DWORD GetPreviousActionKey();

// Sets the previous modifier key to check in another shortcut
void SetPreviousModifierKey(const DWORD prevKey);

// Gets the previous modifier key
std::vector<DWORD> GetPreviousModifierKey();

// Check a key if exist in previous modifier key vector
bool FindPreviousModifierKey(const DWORD prevKey);

// Resets the previous modifier key
void ResetPreviousModifierKey(const DWORD prevKey);

// Clear all previous modifier key
void ClearPreviousModifierKey();
};
Original file line number Diff line number Diff line change
Expand Up @@ -1977,12 +1977,12 @@ namespace RemappingLogicTests

mockedInputHandler.SendVirtualInput(inputs2);

// Check that Ctrl+A+B was pressed
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), true);
// Check that Ctrl, A released and B was pressed
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false);
Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
// Shortcut invoked state should be false
Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
// Shortcut invoked state should be true
Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
}

// Test that shortcut is not disabled if the shortcut which was remapped to Disable is pressed and the action key is released, followed by pressing another key
Expand Down Expand Up @@ -2149,8 +2149,8 @@ namespace RemappingLogicTests
Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
}

// Test that the isOriginalActionKeyPressed flag is set to false on pressing another key
TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnPressingAnotherKey)
// Test that the isOriginalActionKeyPressed flag is set to true on pressing another key
TEST_METHOD (ShortcutDisable_ShouldNotResetIsOriginalActionKeyPressed_OnPressingAnotherKey)
{
Shortcut src;
src.SetKey(VK_CONTROL);
Expand Down Expand Up @@ -2178,8 +2178,8 @@ namespace RemappingLogicTests
// press B
mockedInputHandler.SendVirtualInput(inputs2);

// IsOriginalActionKeyPressed state should be false
Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
// IsOriginalActionKeyPressed state should be true
Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
}

// Tests for dummy key events in shortcut remaps
Expand Down
6 changes: 3 additions & 3 deletions src/modules/keyboardmanager/common/Shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,7 +746,7 @@ bool IgnoreKeyCode(DWORD key)
}

// Function to check if any keys are pressed down except those in the shortcut
bool Shortcut::IsKeyboardStateClearExceptShortcut(KeyboardManagerInput::InputInterface& ii) const
bool Shortcut::IsKeyboardStateClearExceptShortcut(KeyboardManagerInput::InputInterface& ii, int prevKey) const
{
// Iterate through all the virtual key codes - 0xFF is set to key down because of the Num Lock
for (int keyVal = 1; keyVal < 0xFF; keyVal++)
Expand Down Expand Up @@ -884,8 +884,8 @@ bool Shortcut::IsKeyboardStateClearExceptShortcut(KeyboardManagerInput::InputInt
continue;
}
}
// If any other key is pressed check if it is the action key
else if (keyVal != static_cast<int>(actionKey))
// If any other key is pressed check if it is the action key or check if it is previous action key
else if (keyVal != static_cast<int>(actionKey) && (prevKey != 0 && keyVal != prevKey))
{
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/keyboardmanager/common/Shortcut.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class Shortcut
bool CheckModifiersKeyboardState(KeyboardManagerInput::InputInterface& ii) const;

// Function to check if any keys are pressed down except those in the shortcut
bool IsKeyboardStateClearExceptShortcut(KeyboardManagerInput::InputInterface& ii) const;
bool IsKeyboardStateClearExceptShortcut(KeyboardManagerInput::InputInterface& ii, int prevKey) const;

// Function to get the number of modifiers that are common between the current shortcut and the shortcut in the argument
int GetCommonModifiersCount(const Shortcut& input) const;
Expand Down