diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 3db7df482ef..34e138ef62b 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -4,9 +4,9 @@ "title": "Microsoft's Windows Terminal Settings Profile Schema", "definitions": { "KeyChordSegment": { - "pattern": "^(?(ctrl|alt|shift)(?:\\+(ctrl|alt|shift)(?[^\\s+]|app|menu|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?(?ctrl|alt|shift|win)(?:\\+(?ctrl|alt|shift|win)(?))?(?:\\+(?ctrl|alt|shift|win)(?|\\k))?(?:\\+(?ctrl|alt|shift|win)(?|\\k|\\k))?\\+)?(?[^\\s+]|app|menu|backspace|tab|enter|esc|escape|space|pgup|pageup|pgdn|pagedown|end|home|left|up|right|down|insert|delete|(?\", 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+]\", 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": "#", diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 2ce671f309f..554e82bf2c4 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1360,6 +1360,11 @@ namespace winrt::TerminalApp::implementation buffer += L"Alt+"; } + if (WI_IsFlagSet(modifiers, KeyModifiers::Windows)) + { + buffer += L"Win+"; + } + return buffer; } diff --git a/src/cascadia/TerminalControl/KeyChord.cpp b/src/cascadia/TerminalControl/KeyChord.cpp index 4c068890e35..adf24d0aa4c 100644 --- a/src/cascadia/TerminalControl/KeyChord.cpp +++ b/src/cascadia/TerminalControl/KeyChord.cpp @@ -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 } diff --git a/src/cascadia/TerminalControl/KeyChord.h b/src/cascadia/TerminalControl/KeyChord.h index 9324a811321..2b5f0d80fb4 100644 --- a/src/cascadia/TerminalControl/KeyChord.h +++ b/src/cascadia/TerminalControl/KeyChord.h @@ -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; diff --git a/src/cascadia/TerminalControl/KeyChord.idl b/src/cascadia/TerminalControl/KeyChord.idl index 65107d8d9d3..25e10bd01b5 100644 --- a/src/cascadia/TerminalControl/KeyChord.idl +++ b/src/cascadia/TerminalControl/KeyChord.idl @@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Control None = 0x0000, Alt = 0x0001, Ctrl = 0x0002, - Shift = 0x0004 + Shift = 0x0004, + Windows = 0x0008 }; [default_interface] @@ -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; diff --git a/src/cascadia/TerminalControl/TermControl.cpp b/src/cascadia/TerminalControl/TermControl.cpp index f34d7013c02..79dab5af89b 100644 --- a/src/cascadia/TerminalControl/TermControl.cpp +++ b/src/cascadia/TerminalControl/TermControl.cpp @@ -1128,6 +1128,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation modifiers.IsCtrlPressed(), modifiers.IsAltPressed(), modifiers.IsShiftPressed(), + modifiers.IsWinPressed(), vkey, }); if (!success) @@ -3010,12 +3011,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation ControlKeyStates flags; }; - constexpr std::array modifiers{ { + constexpr std::array 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; diff --git a/src/cascadia/TerminalCore/ControlKeyStates.hpp b/src/cascadia/TerminalCore/ControlKeyStates.hpp index 16d6daa02cb..9b88c71a3eb 100644 --- a/src/cascadia/TerminalCore/ControlKeyStates.hpp +++ b/src/cascadia/TerminalCore/ControlKeyStates.hpp @@ -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; @@ -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) {} @@ -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(winrt::Windows::System::VirtualKeyModifiers::Menu)) ? LEFT_ALT_PRESSED : 0; _value |= WI_IsFlagSet(m, static_cast(winrt::Windows::System::VirtualKeyModifiers::Control)) ? LEFT_CTRL_PRESSED : 0; + _value |= WI_IsFlagSet(m, static_cast(winrt::Windows::System::VirtualKeyModifiers::Windows)) ? + LEFT_WIN_PRESSED : + 0; } #endif @@ -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); diff --git a/src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp b/src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp index 8c0fd632235..b240b8d2802 100644 --- a/src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp +++ b/src/cascadia/TerminalSettingsModel/KeyChordSerialization.cpp @@ -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 vkeyNamePairs { @@ -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; @@ -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; diff --git a/src/cascadia/TerminalSettingsModel/KeyMapping.cpp b/src/cascadia/TerminalSettingsModel/KeyMapping.cpp index a5dd04891c4..880a6b34d4a 100644 --- a/src/cascadia/TerminalSettingsModel/KeyMapping.cpp +++ b/src/cascadia/TerminalSettingsModel/KeyMapping.cpp @@ -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; }