Skip to content

Commit

Permalink
Add support for Common Win key in KBM (#2308)
Browse files Browse the repository at this point in the history
* Added common win key to layoutmap

* Added common win key support for edit shortcuts

* Adjusted key names
  • Loading branch information
arjunbalgovind committed Apr 23, 2020
1 parent d941b31 commit 32ddf32
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 46 deletions.
19 changes: 11 additions & 8 deletions src/common/keyboard_layout.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "pch.h"
#include "keyboard_layout_impl.h"
#include "shared_constants.h"

LayoutMap::LayoutMap() :
impl(new LayoutMap::LayoutMapImpl())
Expand Down Expand Up @@ -127,8 +128,8 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
keyboardLayoutMap[VK_INSERT] = L"Insert";
keyboardLayoutMap[VK_DELETE] = L"Delete";
keyboardLayoutMap[VK_HELP] = L"Help";
keyboardLayoutMap[VK_LWIN] = L"LWin";
keyboardLayoutMap[VK_RWIN] = L"RWin";
keyboardLayoutMap[VK_LWIN] = L"Win (Left)";
keyboardLayoutMap[VK_RWIN] = L"Win (Right)";
keyboardLayoutMap[VK_APPS] = L"Menu";
keyboardLayoutMap[VK_SLEEP] = L"Sleep";
keyboardLayoutMap[VK_NUMPAD0] = L"NumPad 0";
Expand Down Expand Up @@ -168,12 +169,12 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
keyboardLayoutMap[VK_F24] = L"F24";
keyboardLayoutMap[VK_NUMLOCK] = L"Num Lock";
keyboardLayoutMap[VK_SCROLL] = L"Scroll Lock";
keyboardLayoutMap[VK_LSHIFT] = L"LShift";
keyboardLayoutMap[VK_RSHIFT] = L"RShift";
keyboardLayoutMap[VK_LCONTROL] = L"LCtrl";
keyboardLayoutMap[VK_RCONTROL] = L"RCtrl";
keyboardLayoutMap[VK_LMENU] = L"LAlt";
keyboardLayoutMap[VK_RMENU] = L"RAlt";
keyboardLayoutMap[VK_LSHIFT] = L"Shift (Left)";
keyboardLayoutMap[VK_RSHIFT] = L"Shift (Right)";
keyboardLayoutMap[VK_LCONTROL] = L"Ctrl (Left)";
keyboardLayoutMap[VK_RCONTROL] = L"Ctrl (Right)";
keyboardLayoutMap[VK_LMENU] = L"Alt (Left)";
keyboardLayoutMap[VK_RMENU] = L"Alt (Right)";
keyboardLayoutMap[VK_BROWSER_BACK] = L"Browser Back";
keyboardLayoutMap[VK_BROWSER_FORWARD] = L"Browser Forward";
keyboardLayoutMap[VK_BROWSER_REFRESH] = L"Browser Refresh";
Expand Down Expand Up @@ -202,6 +203,7 @@ void LayoutMap::LayoutMapImpl::UpdateLayout()
keyboardLayoutMap[VK_PA1] = L"PA1";
keyboardLayoutMap[VK_OEM_CLEAR] = L"Clear";
keyboardLayoutMap[0xFF] = L"Undefined";
keyboardLayoutMap[CommonSharedConstants::VK_WIN_BOTH] = L"Win";
// To do: Add IME key names
}

Expand All @@ -214,6 +216,7 @@ std::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcu
if (!isKeyCodeListGenerated)
{
// Add modifier keys
keyCodes.push_back(CommonSharedConstants::VK_WIN_BOTH);
keyCodes.push_back(VK_LWIN);
keyCodes.push_back(VK_RWIN);
keyCodes.push_back(VK_CONTROL);
Expand Down
3 changes: 3 additions & 0 deletions src/common/shared_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ namespace CommonSharedConstants
{
// Flag that can be set on an input event so that it is ignored by Keyboard Manager
const ULONG_PTR KEYBOARDMANAGER_INJECTED_FLAG = 0x1;

// Fake key code to represent VK_WIN.
inline const DWORD VK_WIN_BOTH = 0x104;
}
2 changes: 2 additions & 0 deletions src/modules/keyboardmanager/common/Helpers.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "pch.h"
#include "Helpers.h"
#include <sstream>
#include "../common/shared_constants.h"

using namespace winrt::Windows::Foundation;

Expand Down Expand Up @@ -42,6 +43,7 @@ namespace KeyboardManagerHelper
{
switch (key)
{
case CommonSharedConstants::VK_WIN_BOTH:
case VK_LWIN:
case VK_RWIN:
return KeyType::Win;
Expand Down
3 changes: 0 additions & 3 deletions src/modules/keyboardmanager/common/KeyboardManagerConstants.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,4 @@ namespace KeyboardManagerConstants

// Name of the dummy update file.
inline const std::wstring DummyUpdateFileName = L"settings-updated.json";

// Fake key code to represent VK_WIN.
inline const DWORD VK_WIN_BOTH = 0x104;
}
3 changes: 2 additions & 1 deletion src/modules/keyboardmanager/common/KeyboardManagerState.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once
#include "Helpers.h"
#include "..\common\keyboard_layout.h"
#include "../common/keyboard_layout.h"
#include "Shortcut.h"
#include "RemapShortcut.h"
#include "KeyDelay.h"
Expand All @@ -9,6 +9,7 @@
#include <mutex>
#include <winrt/Windows.UI.Xaml.Controls.h>
#include <../common/settings_helpers.h>

using namespace winrt::Windows::UI::Xaml::Controls;

// Enum type to store different states of the UI
Expand Down
30 changes: 15 additions & 15 deletions src/modules/keyboardmanager/common/Shortcut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,15 @@ DWORD Shortcut::GetWinKey(const ModifierKey& input) const
{
return VK_RWIN;
}
else
else if (input == ModifierKey::Left || input == ModifierKey::Disabled)
{
//return VK_LWIN by default
return VK_LWIN;
}
else if (input == ModifierKey::Both)
{
return CommonSharedConstants::VK_WIN_BOTH;
}
}
}

Expand Down Expand Up @@ -253,11 +257,11 @@ bool Shortcut::CheckShiftKey(const DWORD& input) const
}
}

// Function to set a key in the shortcut based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key. If isWinBoth is true then first arg is ignored. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
bool Shortcut::SetKey(const DWORD& input, const bool& isWinBoth)
// Function to set a key in the shortcut based on the passed key code argument. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
bool Shortcut::SetKey(const DWORD& input)
{
// Since there isn't a key for a common Win key this is handled with a separate argument
if (isWinBoth)
if (input == CommonSharedConstants::VK_WIN_BOTH)
{
if (winKey == ModifierKey::Both)
{
Expand Down Expand Up @@ -366,10 +370,10 @@ bool Shortcut::SetKey(const DWORD& input, const bool& isWinBoth)
}

// Function to reset the state of a shortcut key based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key.
void Shortcut::ResetKey(const DWORD& input, const bool& isWinBoth)
void Shortcut::ResetKey(const DWORD& input)
{
// Since there isn't a key for a common Win key this is handled with a separate argument.
if (isWinBoth || input == VK_LWIN || input == VK_RWIN)
if (input == CommonSharedConstants::VK_WIN_BOTH || input == VK_LWIN || input == VK_RWIN)
{
winKey = ModifierKey::Disabled;
}
Expand Down Expand Up @@ -397,7 +401,7 @@ std::vector<winrt::hstring> Shortcut::GetKeyVector(LayoutMap& keyboardMap) const
std::vector<winrt::hstring> keys;
if (winKey != ModifierKey::Disabled)
{
keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(GetWinKey(ModifierKey::Left)).c_str()));
keys.push_back(winrt::to_hstring(keyboardMap.GetKeyName(GetWinKey(ModifierKey::Both)).c_str()));
}
if (ctrlKey != ModifierKey::Disabled)
{
Expand All @@ -422,13 +426,9 @@ std::vector<winrt::hstring> Shortcut::GetKeyVector(LayoutMap& keyboardMap) const
winrt::hstring Shortcut::ToHstringVK() const
{
winrt::hstring output;
if (winKey != ModifierKey::Disabled && winKey != ModifierKey::Both)
{
output = output + winrt::to_hstring((unsigned int)GetWinKey(ModifierKey::Left)) + winrt::to_hstring(L";");
}
if (winKey == ModifierKey::Both)
if (winKey != ModifierKey::Disabled)
{
output = output + winrt::to_hstring((unsigned int)KeyboardManagerConstants::VK_WIN_BOTH) + winrt::to_hstring(L";");
output = output + winrt::to_hstring((unsigned int)GetWinKey(ModifierKey::Both)) + winrt::to_hstring(L";");
}
if (ctrlKey != ModifierKey::Disabled)
{
Expand All @@ -451,7 +451,7 @@ winrt::hstring Shortcut::ToHstringVK() const
{
output = winrt::hstring(output.c_str(), output.size() - 1);
}

return output;
}

Expand All @@ -461,7 +461,7 @@ std::vector<DWORD> Shortcut::GetKeyCodes()
std::vector<DWORD> keys;
if (winKey != ModifierKey::Disabled)
{
keys.push_back(GetWinKey(ModifierKey::Left));
keys.push_back(GetWinKey(ModifierKey::Both));
}
if (ctrlKey != ModifierKey::Disabled)
{
Expand Down
23 changes: 8 additions & 15 deletions src/modules/keyboardmanager/common/Shortcut.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include "Helpers.h"
#include "KeyboardManagerConstants.h"
#include "..\common\keyboard_layout.h"
#include "../common/keyboard_layout.h"
#include "../common/shared_constants.h"
#include <interface/lowlevel_keyboard_event_data.h>

// Enum type to store different states of the win key
Expand Down Expand Up @@ -37,14 +37,7 @@ class Shortcut
for (auto it : keys)
{
auto vkKeyCode = std::stoul(it);
if (vkKeyCode == KeyboardManagerConstants::VK_WIN_BOTH)
{
SetKey(vkKeyCode, true);
}
else
{
SetKey(vkKeyCode);
}
SetKey(vkKeyCode);
}
}

Expand Down Expand Up @@ -149,15 +142,15 @@ class Shortcut
// Function to check if the input key matches the shift key expected in the shortcut
bool CheckShiftKey(const DWORD& input) const;

// Function to set a key in the shortcut based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key. If isWinBoth is true then first arg is ignored. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
bool SetKey(const DWORD& input, const bool& isWinBoth = false);
// Function to set a key in the shortcut based on the passed key code argument. Returns false if it is already set to the same value. This can be used to avoid UI refreshing
bool SetKey(const DWORD& input);

// Function to reset the state of a shortcut key based on the passed key code argument. Since there is no VK_WIN code, use the second argument for setting common win key.
void ResetKey(const DWORD& input, const bool& isWinBoth = false);
// Function to reset the state of a shortcut key based on the passed key code argument
void ResetKey(const DWORD& input);

// Function to return the string representation of the shortcut in virtual key codes appended in a string by ";" separator.
winrt::hstring ToHstringVK() const;

// Function to return a vector of hstring for each key in the display order
std::vector<winrt::hstring> GetKeyVector(LayoutMap& keyboardMap) const;

Expand Down
15 changes: 12 additions & 3 deletions src/modules/keyboardmanager/dll/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class KeyboardManager : public PowertoyModuleIface
};

// Load config from the saved settings.
void load_config()
void load_config()
{
try
{
Expand Down Expand Up @@ -423,13 +423,22 @@ class KeyboardManager : public PowertoyModuleIface
int key_count = 1;
LPINPUT keyEventList = new INPUT[size_t(key_count)]();
memset(keyEventList, 0, sizeof(keyEventList));

// Handle remaps to VK_WIN_BOTH
DWORD target = it->second;
// If a key is remapped to VK_WIN_BOTH, we send VK_LWIN instead
if (target == CommonSharedConstants::VK_WIN_BOTH)
{
target = VK_LWIN;
}

if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)
{
SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)it->second, KEYEVENTF_KEYUP, KEYBOARDMANAGER_SINGLEKEY_FLAG);
SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, KEYEVENTF_KEYUP, KEYBOARDMANAGER_SINGLEKEY_FLAG);
}
else
{
SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)it->second, 0, KEYBOARDMANAGER_SINGLEKEY_FLAG);
SetKeyEvent(keyEventList, 0, INPUT_KEYBOARD, (WORD)target, 0, KEYBOARDMANAGER_SINGLEKEY_FLAG);
}

lock.unlock();
Expand Down
17 changes: 16 additions & 1 deletion src/modules/keyboardmanager/ui/EditKeyboardWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
std::unordered_map<DWORD, DWORD> singleKeyRemapCopy = keyboardManagerState.singleKeyReMap;
lock.unlock();

// Pre process the table to combine L and R versions of Ctrl/Alt/Shift that are mapped to the same key
// Pre process the table to combine L and R versions of Ctrl/Alt/Shift/Win that are mapped to the same key
if (singleKeyRemapCopy.find(VK_LCONTROL) != singleKeyRemapCopy.end() && singleKeyRemapCopy.find(VK_RCONTROL) != singleKeyRemapCopy.end())
{
// If they are mapped to the same key, delete those entries and set the common version
Expand Down Expand Up @@ -178,6 +178,16 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
singleKeyRemapCopy.erase(VK_RSHIFT);
}
}
if (singleKeyRemapCopy.find(VK_LWIN) != singleKeyRemapCopy.end() && singleKeyRemapCopy.find(VK_RWIN) != singleKeyRemapCopy.end())
{
// If they are mapped to the same key, delete those entries and set the common version
if (singleKeyRemapCopy[VK_LWIN] == singleKeyRemapCopy[VK_RWIN])
{
singleKeyRemapCopy[CommonSharedConstants::VK_WIN_BOTH] = singleKeyRemapCopy[VK_LWIN];
singleKeyRemapCopy.erase(VK_LWIN);
singleKeyRemapCopy.erase(VK_RWIN);
}
}

for (const auto& it : singleKeyRemapCopy)
{
Expand Down Expand Up @@ -220,6 +230,11 @@ void createEditKeyboardWindow(HINSTANCE hInst, KeyboardManagerState& keyboardMan
res2 = keyboardManagerState.AddSingleKeyRemap(VK_RSHIFT, newKey);
result = res1 && res2;
break;
case CommonSharedConstants::VK_WIN_BOTH:
res1 = keyboardManagerState.AddSingleKeyRemap(VK_LWIN, newKey);
res2 = keyboardManagerState.AddSingleKeyRemap(VK_RWIN, newKey);
result = res1 && res2;
break;
default:
result = keyboardManagerState.AddSingleKeyRemap(originalKey, newKey);
}
Expand Down

0 comments on commit 32ddf32

Please sign in to comment.