Skip to content

Commit

Permalink
Add support for the win key in keybindings (#9783)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request

Does what it says on the can. People can now use `win` in a keybinding to
indicate that the chord needs <kbd>win</kbd>.

## References
* Done for #653
* See also #8888

## PR Checklist
* [x] Closes #3184
* [x] I work here
* [ ] Tests added/passed
* [ ] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

For the record, I hate this. But it's great for quake mode, so _meh_. There's
shockingly more win keys claimed then you think - many more than the shortcut
guide even shows.

* `win+b`: Focus the tray?
* `win+t`: Focus the taskbar
* `win+p`: Project...
* `win+c`: The powertoys color picker
* `win+v`: cloud clipboard

So the list of valid combos is vanishingly small. It's all about that <kbd>win+~</kbd>

## Validation Steps Performed

Bound
```json
        { "keys": [ "win+`" ], "command": "commandPalette" },
```

and yea, it works as expected
  • Loading branch information
zadjii-msft authored Apr 15, 2021
1 parent 3113d2e commit eddb99e
Show file tree
Hide file tree
Showing 9 changed files with 59 additions and 6 deletions.
4 changes: 2 additions & 2 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
"title": "Microsoft's Windows Terminal Settings Profile Schema",
"definitions": {
"KeyChordSegment": {
"pattern": "^(?<modifier>(ctrl|alt|shift)(?:\\+(ctrl|alt|shift)(?<!\\2))?(?:\\+(ctrl|alt|shift)(?<!\\2|\\3))?\\+)?(?<key>[^\\s+]|app|menu|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?<!shift.+)(?:numpad_?[0-9]|numpad_(?:period|decimal))|numpad_(?:multiply|plus|add|minus|subtract|divide)|f[1-9]|f1[0-9]|f2[0-4]|plus)$",
"pattern": "^(?<modifier>(?<mod1>ctrl|alt|shift|win)(?:\\+(?<mod2>ctrl|alt|shift|win)(?<!\\k<mod1>))?(?:\\+(?<mod3>ctrl|alt|shift|win)(?<!\\k<mod1>|\\k<mod2>))?(?:\\+(?<mod4>ctrl|alt|shift|win)(?<!\\k<mod1>|\\k<mod2>|\\k<mod3>))?\\+)?(?<key>[^\\s+]|app|menu|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?<!shift.+)(?:numpad_?[0-9]|numpad_(?:period|decimal))|numpad_(?:multiply|plus|add|minus|subtract|divide)|f[1-9]|f1[0-9]|f2[0-4]|plus)$",
"type": "string",
"description": "The string should fit the format \"[ctrl+][alt+][shift+]<keyName>\", where each modifier is optional, separated by + symbols, and keyName is either one of the names listed in the table below, or any single key character. The string should be written in full lowercase.\napp, menu\tMENU key\nbackspace\tBACKSPACE key\ntab\tTAB key\nenter\tENTER key\nesc, escape\tESC key\nspace\tSPACEBAR\npgup, pageup\tPAGE UP key\npgdn, pagedown\tPAGE DOWN key\nend\tEND key\nhome\tHOME key\nleft\tLEFT ARROW key\nup\tUP ARROW key\nright\tRIGHT ARROW key\ndown\tDOWN ARROW key\ninsert\tINS key\ndelete\tDEL key\nnumpad_0-numpad_9, numpad0-numpad9\tNumeric keypad keys 0 to 9. Can't be combined with the shift modifier.\nnumpad_multiply\tNumeric keypad MULTIPLY key (*)\nnumpad_plus, numpad_add\tNumeric keypad ADD key (+)\nnumpad_minus, numpad_subtract\tNumeric keypad SUBTRACT key (-)\nnumpad_period, numpad_decimal\tNumeric keypad DECIMAL key (.). Can't be combined with the shift modifier.\nnumpad_divide\tNumeric keypad DIVIDE key (/)\nf1-f24\tF1 to F24 function keys\nplus\tADD key (+)"
"description": "The string should fit the format \"[ctrl+][alt+][shift+][win+]<keyName>\", where each modifier is optional, separated by + symbols, and keyName is either one of the names listed in the table below, or any single key character. The string should be written in full lowercase.\napp, menu\tMENU key\nbackspace\tBACKSPACE key\ntab\tTAB key\nenter\tENTER key\nesc, escape\tESC key\nspace\tSPACEBAR\npgup, pageup\tPAGE UP key\npgdn, pagedown\tPAGE DOWN key\nend\tEND key\nhome\tHOME key\nleft\tLEFT ARROW key\nup\tUP ARROW key\nright\tRIGHT ARROW key\ndown\tDOWN ARROW key\ninsert\tINS key\ndelete\tDEL key\nnumpad_0-numpad_9, numpad0-numpad9\tNumeric keypad keys 0 to 9. Can't be combined with the shift modifier.\nnumpad_multiply\tNumeric keypad MULTIPLY key (*)\nnumpad_plus, numpad_add\tNumeric keypad ADD key (+)\nnumpad_minus, numpad_subtract\tNumeric keypad SUBTRACT key (-)\nnumpad_period, numpad_decimal\tNumeric keypad DECIMAL key (.). Can't be combined with the shift modifier.\nnumpad_divide\tNumeric keypad DIVIDE key (/)\nf1-f24\tF1 to F24 function keys\nplus\tADD key (+)"
},
"Color": {
"default": "#",
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1360,6 +1360,11 @@ namespace winrt::TerminalApp::implementation
buffer += L"Alt+";
}

if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
{
buffer += L"Win+";
}

return buffer;
}

Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalControl/KeyChord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
{
}

KeyChord::KeyChord(bool ctrl, bool alt, bool shift, bool win, int32_t vkey) noexcept :
_modifiers{ (ctrl ? Control::KeyModifiers::Ctrl : Control::KeyModifiers::None) |
(alt ? Control::KeyModifiers::Alt : Control::KeyModifiers::None) |
(shift ? Control::KeyModifiers::Shift : Control::KeyModifiers::None) |
(win ? Control::KeyModifiers::Windows : Control::KeyModifiers::None) },
_vkey{ vkey }
{
}

KeyChord::KeyChord(Control::KeyModifiers const& modifiers, int32_t vkey) noexcept :
_modifiers{ modifiers },
_vkey{ vkey }
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/KeyChord.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
KeyChord() noexcept;
KeyChord(Control::KeyModifiers const& modifiers, int32_t vkey) noexcept;
KeyChord(bool ctrl, bool alt, bool shift, int32_t vkey) noexcept;
KeyChord(bool ctrl, bool alt, bool shift, bool win, int32_t vkey) noexcept;

Control::KeyModifiers Modifiers() noexcept;
void Modifiers(Control::KeyModifiers const& value) noexcept;
Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalControl/KeyChord.idl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Control
None = 0x0000,
Alt = 0x0001,
Ctrl = 0x0002,
Shift = 0x0004
Shift = 0x0004,
Windows = 0x0008
};

[default_interface]
Expand All @@ -18,6 +19,7 @@ namespace Microsoft.Terminal.Control
KeyChord();
KeyChord(KeyModifiers modifiers, Int32 vkey);
KeyChord(Boolean ctrl, Boolean alt, Boolean shift, Int32 vkey);
KeyChord(Boolean ctrl, Boolean alt, Boolean shift, Boolean win, Int32 vkey);

KeyModifiers Modifiers;
Int32 Vkey;
Expand Down
5 changes: 4 additions & 1 deletion src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1128,6 +1128,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
modifiers.IsCtrlPressed(),
modifiers.IsAltPressed(),
modifiers.IsShiftPressed(),
modifiers.IsWinPressed(),
vkey,
});
if (!success)
Expand Down Expand Up @@ -3010,12 +3011,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
ControlKeyStates flags;
};

constexpr std::array<KeyModifier, 5> modifiers{ {
constexpr std::array<KeyModifier, 7> modifiers{ {
{ VirtualKey::RightMenu, ControlKeyStates::RightAltPressed },
{ VirtualKey::LeftMenu, ControlKeyStates::LeftAltPressed },
{ VirtualKey::RightControl, ControlKeyStates::RightCtrlPressed },
{ VirtualKey::LeftControl, ControlKeyStates::LeftCtrlPressed },
{ VirtualKey::Shift, ControlKeyStates::ShiftPressed },
{ VirtualKey::RightWindows, ControlKeyStates::RightWinPressed },
{ VirtualKey::LeftWindows, ControlKeyStates::LeftWinPressed },
} };

ControlKeyStates flags;
Expand Down
21 changes: 20 additions & 1 deletion src/cascadia/TerminalCore/ControlKeyStates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@

#pragma once

// All the modifiers in this file EXCEPT the win key come from
// https://docs.microsoft.com/en-us/windows/console/key-event-record-str
//
// Since we also want to be able to encode win-key info in this structure, we'll
// add those values manually here
constexpr DWORD RIGHT_WIN_PRESSED = 0x0200;
constexpr DWORD LEFT_WIN_PRESSED = 0x0400;

namespace Microsoft::Terminal::Core
{
class ControlKeyStates;
Expand Down Expand Up @@ -31,6 +39,8 @@ class Microsoft::Terminal::Core::ControlKeyStates
static constexpr StaticValue ScrolllockOn{ SCROLLLOCK_ON };
static constexpr StaticValue CapslockOn{ CAPSLOCK_ON };
static constexpr StaticValue EnhancedKey{ ENHANCED_KEY };
static constexpr StaticValue RightWinPressed{ RIGHT_WIN_PRESSED };
static constexpr StaticValue LeftWinPressed{ LEFT_WIN_PRESSED };

constexpr ControlKeyStates() noexcept :
_value(0) {}
Expand Down Expand Up @@ -58,13 +68,17 @@ class Microsoft::Terminal::Core::ControlKeyStates
SHIFT_PRESSED :
0;

// Since we can't differentiate between the left & right versions of Ctrl & Alt in a VirtualKeyModifiers
// Since we can't differentiate between the left & right versions of
// Ctrl, Alt and Win in a VirtualKeyModifiers
_value |= WI_IsFlagSet(m, static_cast<uint32_t>(winrt::Windows::System::VirtualKeyModifiers::Menu)) ?
LEFT_ALT_PRESSED :
0;
_value |= WI_IsFlagSet(m, static_cast<uint32_t>(winrt::Windows::System::VirtualKeyModifiers::Control)) ?
LEFT_CTRL_PRESSED :
0;
_value |= WI_IsFlagSet(m, static_cast<uint32_t>(winrt::Windows::System::VirtualKeyModifiers::Windows)) ?
LEFT_WIN_PRESSED :
0;
}
#endif

Expand All @@ -88,6 +102,11 @@ class Microsoft::Terminal::Core::ControlKeyStates
return IsAnyFlagSet(RightCtrlPressed | LeftCtrlPressed);
}

constexpr bool IsWinPressed() const noexcept
{
return IsAnyFlagSet(RightWinPressed | LeftWinPressed);
}

constexpr bool IsAltGrPressed() const noexcept
{
return AreAllFlagsSet(RightAltPressed | LeftCtrlPressed);
Expand Down
12 changes: 11 additions & 1 deletion src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
static constexpr std::wstring_view CTRL_KEY{ L"ctrl" };
static constexpr std::wstring_view SHIFT_KEY{ L"shift" };
static constexpr std::wstring_view ALT_KEY{ L"alt" };
static constexpr std::wstring_view WIN_KEY{ L"win" };

static constexpr int MAX_CHORD_PARTS = 4;
static constexpr int MAX_CHORD_PARTS = 5; // win+ctrl+alt+shift+key

// clang-format off
static const std::unordered_map<std::wstring_view, int32_t> vkeyNamePairs {
Expand Down Expand Up @@ -143,6 +144,10 @@ KeyChord KeyChordSerialization::FromString(const winrt::hstring& hstr)
{
modifiers |= KeyModifiers::Shift;
}
else if (lowercase == WIN_KEY)
{
modifiers |= KeyModifiers::Windows;
}
else
{
bool foundKey = false;
Expand Down Expand Up @@ -224,6 +229,11 @@ winrt::hstring KeyChordSerialization::ToString(const KeyChord& chord)
std::wstring buffer{ L"" };

// Add modifiers
if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
{
buffer += WIN_KEY;
buffer += L"+";
}
if (WI_IsFlagSet(modifiers, KeyModifiers::Ctrl))
{
buffer += CTRL_KEY;
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalSettingsModel/KeyMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
// note: Menu is the Alt VK_MENU
keyModifiers |= Windows::System::VirtualKeyModifiers::Menu;
}
if (WI_IsFlagSet(modifiers, KeyModifiers::Windows))
{
keyModifiers |= Windows::System::VirtualKeyModifiers::Windows;
}

return keyModifiers;
}
Expand Down

0 comments on commit eddb99e

Please sign in to comment.