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);
@@ -399,7 +395,7 @@ namespace KeyboardEventHandlers
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)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
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
@@ -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)
{
@@ -486,15 +482,14 @@ namespace KeyboardEventHandlers
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)), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);
i++;
i++;
}
// Set original shortcut key down state except the action key and the released modifier
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;