diff --git a/src/cascadia/TerminalApp/App.cpp b/src/cascadia/TerminalApp/App.cpp index 166e76658d4..a2743143f20 100644 --- a/src/cascadia/TerminalApp/App.cpp +++ b/src/cascadia/TerminalApp/App.cpp @@ -1395,6 +1395,33 @@ namespace winrt::TerminalApp::implementation }); } + // Method Description: + // - Handles the special case of providing a text override for the UI shortcut due to VK_OEM issue. + // Looks at the flags from the KeyChord modifiers and provides a concatenated string value of all + // in the same order that XAML would put them as well. + // Return Value: + // - a WinRT hstring representation of the key modifiers for the shortcut + //NOTE: This needs to be localized with https://github.com/microsoft/terminal/issues/794 if XAML framework issue not resolved before then + static std::wstring _FormatOverrideShortcutText(Settings::KeyModifiers modifiers) + { + std::wstring buffer{ L"" }; + + if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Ctrl)) + { + buffer += L"Ctrl+"; + } + if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Shift)) + { + buffer += L"Shift+"; + } + if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Alt)) + { + buffer += L"Alt+"; + } + + return buffer; + } + // Method Description: // - Takes a MenuFlyoutItem and a corresponding KeyChord value and creates the accelerator for UI display. // Takes into account a special case for an error condition for a comma @@ -1402,6 +1429,7 @@ namespace winrt::TerminalApp::implementation // - MenuFlyoutItem that will be displayed, and a KeyChord to map an accelerator void App::_SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::Settings::KeyChord& keyChord) { +#ifdef DEP_MICROSOFT_UI_XAML_708_FIXED // work around https://github.com/microsoft/microsoft-ui-xaml/issues/708 in case of VK_OEM_COMMA if (keyChord.Vkey() != VK_OEM_COMMA) { @@ -1421,10 +1449,15 @@ namespace winrt::TerminalApp::implementation menuItem.KeyboardAccelerators().Append(menuShortcut); } else // we've got a comma, so need to just use the alternate method +#endif { // extract the modifier and key to a nice format - auto overrideString = AppKeyBindings::FormatOverrideShortcutText(keyChord.Modifiers()); - menuItem.KeyboardAcceleratorTextOverride(overrideString + L" ,"); + auto overrideString = _FormatOverrideShortcutText(keyChord.Modifiers()); + auto mappedCh = MapVirtualKeyW(keyChord.Vkey(), MAPVK_VK_TO_CHAR); + if (mappedCh != 0) + { + menuItem.KeyboardAcceleratorTextOverride(overrideString + gsl::narrow_cast(mappedCh)); + } } } diff --git a/src/cascadia/TerminalApp/AppKeyBindings.cpp b/src/cascadia/TerminalApp/AppKeyBindings.cpp index 8d9469d58a3..916e086f268 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindings.cpp @@ -215,33 +215,6 @@ namespace winrt::TerminalApp::implementation return keyModifiers; } - // Method Description: - // - Handles the special case of providing a text override for the UI shortcut due to VK_OEM_COMMA issue. - // Looks at the flags from the KeyChord modifiers and provides a concatenated string value of all - // in the same order that XAML would put them as well. - // Return Value: - // - a WinRT hstring representation of the key modifiers for the shortcut - //NOTE: This needs to be localized with https://github.com/microsoft/terminal/issues/794 if XAML framework issue not resolved before then - winrt::hstring AppKeyBindings::FormatOverrideShortcutText(Settings::KeyModifiers modifiers) - { - std::wstring buffer{ L"" }; - - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Ctrl)) - { - buffer += L"Ctrl+"; - } - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Shift)) - { - buffer += L"Shift+"; - } - if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Alt)) - { - buffer += L"Alt+"; - } - - return winrt::hstring{ buffer }; - } - // -------------------------------- Events --------------------------------- // clang-format off DEFINE_EVENT(AppKeyBindings, CopyText, _CopyTextHandlers, TerminalApp::CopyTextEventArgs); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.h b/src/cascadia/TerminalApp/AppKeyBindings.h index 39d618105b6..0e178065ec8 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.h +++ b/src/cascadia/TerminalApp/AppKeyBindings.h @@ -37,7 +37,6 @@ namespace winrt::TerminalApp::implementation Microsoft::Terminal::Settings::KeyChord GetKeyBinding(TerminalApp::ShortcutAction const& action); static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers); - static winrt::hstring FormatOverrideShortcutText(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers); // clang-format off DECLARE_EVENT(CopyText, _CopyTextHandlers, TerminalApp::CopyTextEventArgs); diff --git a/src/cascadia/TerminalApp/KeyChordSerialization.cpp b/src/cascadia/TerminalApp/KeyChordSerialization.cpp index 9a94c4168d6..53c1932e03b 100644 --- a/src/cascadia/TerminalApp/KeyChordSerialization.cpp +++ b/src/cascadia/TerminalApp/KeyChordSerialization.cpp @@ -68,21 +68,7 @@ static const std::unordered_map vkeyNamePairs { { VK_F22 , L"f22" }, { VK_F23 , L"f23" }, { VK_F24 , L"f24" }, - { VK_OEM_PLUS , L"plus" }, - { VK_OEM_COMMA , L"," }, - { VK_OEM_MINUS , L"-" }, - { VK_OEM_PERIOD , L"." } -// TODO: -// These all look like they'd be good keybindings, but change based on keyboard -// layout. How do we deal with that? -// #define VK_OEM_NEC_EQUAL 0x92 // '=' key on numpad -// #define VK_OEM_1 0xBA // ';:' for US -// #define VK_OEM_2 0xBF // '/?' for US -// #define VK_OEM_3 0xC0 // '`~' for US -// #define VK_OEM_4 0xDB // '[{' for US -// #define VK_OEM_5 0xDC // '\|' for US -// #define VK_OEM_6 0xDD // ']}' for US -// #define VK_OEM_7 0xDE // ''"' for US + { VK_OEM_PLUS , L"plus" } }; // clang-format on @@ -178,6 +164,25 @@ winrt::Microsoft::Terminal::Settings::KeyChord KeyChordSerialization::FromString } } + // If we haven't found a key, attempt a keyboard mapping + if (!foundKey && part.size() == 1) + { + auto oemVk = VkKeyScanW(part[0]); + if (oemVk != -1) + { + vkey = oemVk & 0xFF; + auto oemModifiers = (oemVk & 0xFF00) >> 8; + // We're using WI_SetFlagIf instead of WI_UpdateFlag because we want to be strictly additive + // to the user's specified modifiers. ctrl+| should be the same as ctrl+shift+\, + // but if we used WI_UpdateFlag, ctrl+shift+\ would turn _off_ Shift because \ doesn't + // require it. + WI_SetFlagIf(modifiers, KeyModifiers::Shift, WI_IsFlagSet(oemModifiers, 1U)); + WI_SetFlagIf(modifiers, KeyModifiers::Ctrl, WI_IsFlagSet(oemModifiers, 2U)); + WI_SetFlagIf(modifiers, KeyModifiers::Alt, WI_IsFlagSet(oemModifiers, 4U)); + foundKey = true; + } + } + // If we weren't able to find a match, throw an exception. if (!foundKey) { @@ -240,6 +245,16 @@ winrt::hstring KeyChordSerialization::ToString(const KeyChord& chord) buffer += vkeyNamePairs.at(vkey); serializedSuccessfully = true; } + else + { + auto mappedChar = MapVirtualKeyW(vkey, MAPVK_VK_TO_CHAR); + if (mappedChar != 0) + { + wchar_t mappedWch = gsl::narrow_cast(mappedChar); + buffer += std::wstring_view{ &mappedWch, 1 }; + serializedSuccessfully = true; + } + } } if (!serializedSuccessfully)