terminal/src/cascadia/TerminalControl/KeyChord.cpp
Leonard Hecker d465a47bc5
Fix layering of sc() keybindings with vk() ones (#10917)
The quake mode keybinding is bound to a scancode. This made it
impossible to override it with a vkey-based one like "win+\`".
This commit fixes the issue by making sure that a `KeyChord` always has a vkey,
and leveraging this fact inside ActionMap, which now ignores the scan-code.

## PR Checklist
* [x] Closes #10875
* [x] I work here
* [x] Tests added/passed

## Validation Steps Performed

* quake mode and other keybinding still work ✔️
* Repro settings from #10875 work correctly ✔️
2021-08-11 23:09:25 +00:00

73 lines
2.1 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "KeyChord.h"
#include "KeyChord.g.cpp"
using VirtualKeyModifiers = winrt::Windows::System::VirtualKeyModifiers;
namespace winrt::Microsoft::Terminal::Control::implementation
{
static VirtualKeyModifiers modifiersFromBooleans(bool ctrl, bool alt, bool shift, bool win)
{
VirtualKeyModifiers modifiers = VirtualKeyModifiers::None;
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Control, ctrl);
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Menu, alt);
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Shift, shift);
WI_SetFlagIf(modifiers, VirtualKeyModifiers::Windows, win);
return modifiers;
}
KeyChord::KeyChord(bool ctrl, bool alt, bool shift, bool win, int32_t vkey, int32_t scanCode) noexcept :
KeyChord(modifiersFromBooleans(ctrl, alt, shift, win), vkey, scanCode)
{
}
KeyChord::KeyChord(const VirtualKeyModifiers modifiers, int32_t vkey, int32_t scanCode) noexcept :
_modifiers{ modifiers },
_vkey{ vkey },
_scanCode{ scanCode }
{
// ActionMap needs to identify KeyChords which should "layer" (overwrite) each other.
// For instance win+sc(41) and win+` both specify the same KeyChord on an US keyboard layout
// from the perspective of a user. Either of the two should correctly overwrite the other.
// We can help ActionMap with this by ensuring that Vkey() is always valid.
if (!_vkey)
{
_vkey = MapVirtualKeyW(scanCode, MAPVK_VSC_TO_VK_EX);
}
}
VirtualKeyModifiers KeyChord::Modifiers() noexcept
{
return _modifiers;
}
void KeyChord::Modifiers(VirtualKeyModifiers const& value) noexcept
{
_modifiers = value;
}
int32_t KeyChord::Vkey() noexcept
{
return _vkey;
}
void KeyChord::Vkey(int32_t value) noexcept
{
_vkey = value;
}
int32_t KeyChord::ScanCode() noexcept
{
return _scanCode;
}
void KeyChord::ScanCode(int32_t value) noexcept
{
_scanCode = value;
}
}