Changed dummy key event to send key down and key up to improve compatibility with applications (#7166)

This commit is contained in:
Arjun Balgovind
2020-10-08 11:28:37 -07:00
committed by GitHub
parent e1d22c74b0
commit 42ebc42c98
4 changed files with 33 additions and 25 deletions

View File

@@ -6,6 +6,7 @@
#include "../../common/common.h"
#include "keyboardmanager/dll/Generated Files/resource.h"
#include "../common/keyboard_layout.h"
#include "KeyboardManagerConstants.h"
extern "C" IMAGE_DOS_HEADER __ImageBase;
using namespace winrt::Windows::Foundation;
@@ -193,6 +194,15 @@ namespace KeyboardManagerHelper
keyEventArray[index].ki.dwExtraInfo = extraInfo;
}
// Function to set the dummy key events used for remapping shortcuts, required to ensure releasing a modifier doesn't trigger another action (For example, Win->Start Menu or Alt->Menu bar)
void SetDummyKeyEvent(LPINPUT keyEventArray, int& index, ULONG_PTR extraInfo)
{
SetKeyEvent(keyEventArray, index, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, 0, extraInfo);
index++;
SetKeyEvent(keyEventArray, index, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, extraInfo);
index++;
}
// Function to return window handle for a full screen UWP app
HWND GetFullscreenUWPWindowHandle()
{

View File

@@ -87,6 +87,9 @@ namespace KeyboardManagerHelper
// Function to set the value of a key event based on the arguments
void SetKeyEvent(LPINPUT keyEventArray, int index, DWORD inputType, WORD keyCode, DWORD flags, ULONG_PTR extraInfo);
// Function to set the dummy key events used for remapping shortcuts, required to ensure releasing a modifier doesn't trigger another action (For example, Win->Start Menu or Alt->Menu bar)
void SetDummyKeyEvent(LPINPUT keyEventArray, int& index, ULONG_PTR extraInfo);
// Function to return window handle for a full screen UWP app
HWND GetFullscreenUWPWindowHandle();

View File

@@ -100,6 +100,9 @@ namespace KeyboardManagerConstants
// Dummy key event used in between key up and down events to prevent certain global events from happening
inline const DWORD DUMMY_KEY = 0xFF;
// Number of key messages required while sending a dummy key event
inline const size_t DUMMY_KEY_EVENT_SIZE = 2;
// String constant for the default app name in Remap shortcuts
inline const std::wstring DefaultAppName = GET_RESOURCE_STRING(IDS_EDITSHORTCUTS_ALLAPPS);

View File

@@ -40,7 +40,7 @@ namespace KeyboardEventHandlers
}
else
{
key_count = std::get<Shortcut>(it->second).Size() + 1;
key_count = std::get<Shortcut>(it->second).Size() + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE;
}
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));
@@ -82,13 +82,11 @@ namespace KeyboardEventHandlers
KeyboardManagerHelper::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);
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
}
else
{
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);
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);
i++;
@@ -246,14 +244,13 @@ namespace KeyboardEventHandlers
else
{
// Dummy key, key up for all the original shortcut modifier keys and key down for all the new shortcut keys but common keys in each are not repeated
key_count = 1 + (src_size - 1) + (dest_size) - (2 * (size_t)commonKeys);
key_count = KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE + (src_size - 1) + (dest_size) - (2 * (size_t)commonKeys);
keyEventList = new INPUT[key_count]();
memset(keyEventList, 0, sizeof(keyEventList));
// Send dummy key
int i = 0;
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::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));
@@ -277,7 +274,7 @@ namespace KeyboardEventHandlers
else
{
// Dummy key, key up for all the original shortcut modifier keys and key down for remapped key
key_count = 1 + (src_size - 1) + dest_size;
key_count = KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE + (src_size - 1) + dest_size;
// Do not send Disable key
if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
{
@@ -289,8 +286,7 @@ namespace KeyboardEventHandlers
// Send dummy key
int i = 0;
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::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);
@@ -470,7 +466,7 @@ namespace KeyboardEventHandlers
else
{
// 1 for releasing new key and original shortcut modifiers, and dummy key
key_count = dest_size + src_size;
key_count = dest_size + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE;
// Do not send Disable key
if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
{
@@ -493,8 +489,7 @@ namespace KeyboardEventHandlers
KeyboardManagerHelper::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, i, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
// Send dummy key
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
it->second.isShortcutInvoked = false;
it->second.winKeyInvoked = ModifierKey::Disabled;
@@ -547,7 +542,7 @@ namespace KeyboardEventHandlers
// If the original shortcut is a subset of the new shortcut
if (commonKeys == src_size - 1)
{
key_count = dest_size - commonKeys + 1;
key_count = dest_size - commonKeys + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE;
// 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;
@@ -580,13 +575,12 @@ namespace KeyboardEventHandlers
i++;
// Send dummy key since the current key pressed could be a modifier
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
else
{
// Key up for all new shortcut keys, key down for original shortcut modifiers, dummy key and current key press but common keys aren't repeated
key_count = (dest_size) + (src_size - 1) + 1 - (2 * (size_t)commonKeys);
key_count = (dest_size) + (src_size - 1) + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE - (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
bool isActionKeyPressed = false;
@@ -623,8 +617,7 @@ namespace KeyboardEventHandlers
i++;
// Send dummy key
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
}
it->second.isShortcutInvoked = false;
@@ -643,7 +636,7 @@ namespace KeyboardEventHandlers
else if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)
{
// Key down for original shortcut modifiers and action key, dummy key, and current key press
size_t key_count = src_size + 1 + 1;
size_t key_count = src_size + KeyboardManagerConstants::DUMMY_KEY_EVENT_SIZE + 1;
LPINPUT keyEventList = new INPUT[key_count]();
memset(keyEventList, 0, sizeof(keyEventList));
@@ -661,8 +654,7 @@ namespace KeyboardEventHandlers
i++;
// Send dummy key
KeyboardManagerHelper::SetKeyEvent(keyEventList, i, INPUT_KEYBOARD, (WORD)KeyboardManagerConstants::DUMMY_KEY, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
KeyboardManagerHelper::SetDummyKeyEvent(keyEventList, i, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
it->second.isShortcutInvoked = false;
it->second.winKeyInvoked = ModifierKey::Disabled;