mirror of
https://github.com/microsoft/terminal.git
synced 2025-12-11 04:38:24 -06:00
Adding auto-UI shortcuts to menu based on keymappings (#924)
* Adding vsconfig file for VS2019 help to prompt for missing components requried. * Adding a keybinding for launching the settings. Suggested fix for #683 * Modified to comma per PR feedback * Implements 791 for profile and settings shortcuts (most frequent and have shortcuts) * Quick change for consistency (missed in first checkin due to using ENUM) on using 'Ctrl' instead of 'Control' * Adding UI shortcut generation to new keybinding mappings. Resolving #791 * Making a few changes on reviewer feedback for shortcut UI. * Additional reviewer feedback on variable name change (not a member var)
This commit is contained in:
parent
83b139596f
commit
e9a3d16286
@ -215,11 +215,26 @@ namespace winrt::TerminalApp::implementation
|
||||
void App::_CreateNewTabFlyout()
|
||||
{
|
||||
auto newTabFlyout = Controls::MenuFlyout{};
|
||||
auto keyBindings = _settings->GetKeybindings();
|
||||
|
||||
for (int profileIndex = 0; profileIndex < _settings->GetProfiles().size(); profileIndex++)
|
||||
{
|
||||
const auto& profile = _settings->GetProfiles()[profileIndex];
|
||||
auto profileMenuItem = Controls::MenuFlyoutItem{};
|
||||
|
||||
// add the keyboard shortcuts for the first 9 profiles
|
||||
if (profileIndex < 9)
|
||||
{
|
||||
// enum value for ShortcutAction::NewTabProfileX; 0==NewTabProfile0
|
||||
auto profileKeyChord = keyBindings.GetKeyBinding(static_cast<ShortcutAction>(profileIndex + static_cast<int>(ShortcutAction::NewTabProfile0)));
|
||||
|
||||
// make sure we find one to display
|
||||
if (profileKeyChord)
|
||||
{
|
||||
_SetAcceleratorForMenuItem(profileMenuItem, profileKeyChord);
|
||||
}
|
||||
}
|
||||
|
||||
auto profileName = profile.GetName();
|
||||
winrt::hstring hName{ profileName };
|
||||
profileMenuItem.Text(hName);
|
||||
@ -254,6 +269,12 @@ namespace winrt::TerminalApp::implementation
|
||||
settingsItem.Click({ this, &App::_SettingsButtonOnClick });
|
||||
newTabFlyout.Items().Append(settingsItem);
|
||||
|
||||
auto settingsKeyChord = keyBindings.GetKeyBinding(ShortcutAction::OpenSettings);
|
||||
if (settingsKeyChord)
|
||||
{
|
||||
_SetAcceleratorForMenuItem(settingsItem, settingsKeyChord);
|
||||
}
|
||||
|
||||
// Create the feedback button.
|
||||
auto feedbackFlyout = Controls::MenuFlyoutItem{};
|
||||
feedbackFlyout.Text(L"Feedback");
|
||||
@ -899,6 +920,40 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
// Arguments:
|
||||
// - 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)
|
||||
{
|
||||
// work around https://github.com/microsoft/microsoft-ui-xaml/issues/708 in case of VK_OEM_COMMA
|
||||
if (keyChord.Vkey() != VK_OEM_COMMA)
|
||||
{
|
||||
// use the XAML shortcut to give us the automatic capabilities
|
||||
auto menuShortcut = Windows::UI::Xaml::Input::KeyboardAccelerator{};
|
||||
|
||||
// TODO: Modify this when https://github.com/microsoft/terminal/issues/877 is resolved
|
||||
menuShortcut.Key(static_cast<Windows::System::VirtualKey>(keyChord.Vkey()));
|
||||
|
||||
// inspect the modifiers from the KeyChord and set the flags int he XAML value
|
||||
auto modifiers = AppKeyBindings::ConvertVKModifiers(keyChord.Modifiers());
|
||||
|
||||
// add the modifiers to the shortcut
|
||||
menuShortcut.Modifiers(modifiers);
|
||||
|
||||
// add to the menu
|
||||
menuItem.KeyboardAccelerators().Append(menuShortcut);
|
||||
}
|
||||
else // we've got a comma, so need to just use the alternate method
|
||||
{
|
||||
// extract the modifier and key to a nice format
|
||||
auto overrideString = AppKeyBindings::FormatOverrideShortcutText(keyChord.Modifiers());
|
||||
menuItem.KeyboardAcceleratorTextOverride(overrideString + L" ,");
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------------- WinRT Events ---------------------------------
|
||||
// Winrt events need a method for adding a callback to the event and removing the callback.
|
||||
// These macros will define them both for you.
|
||||
|
||||
@ -64,6 +64,7 @@ namespace winrt::TerminalApp::implementation
|
||||
std::vector<std::shared_ptr<Tab>> _tabs;
|
||||
|
||||
std::unique_ptr<::TerminalApp::CascadiaSettings> _settings;
|
||||
std::unique_ptr<TerminalApp::AppKeyBindings> _keyBindings;
|
||||
|
||||
bool _loadedInitialSettings;
|
||||
|
||||
@ -111,6 +112,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _ApplyTheme(const Windows::UI::Xaml::ElementTheme& newTheme);
|
||||
|
||||
static Windows::UI::Xaml::Controls::IconElement _GetIconFromProfile(const ::TerminalApp::Profile& profile);
|
||||
static void _SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::Settings::KeyChord& keyChord);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -82,6 +82,7 @@ static const std::map<std::wstring_view, ShortcutAction> commandNames {
|
||||
{ SWITCHTOTAB6_KEY, ShortcutAction::SwitchToTab6 },
|
||||
{ SWITCHTOTAB7_KEY, ShortcutAction::SwitchToTab7 },
|
||||
{ SWITCHTOTAB8_KEY, ShortcutAction::SwitchToTab8 },
|
||||
{ OPENSETTINGS_KEY, ShortcutAction::OpenSettings },
|
||||
};
|
||||
|
||||
namespace winrt::TerminalApp::implementation
|
||||
@ -92,6 +93,15 @@ namespace winrt::TerminalApp::implementation
|
||||
_keyShortcuts[chord] = action;
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::KeyChord AppKeyBindings::GetKeyBinding(TerminalApp::ShortcutAction const& action)
|
||||
{
|
||||
for (auto& kv : _keyShortcuts)
|
||||
{
|
||||
if (kv.second == action) return kv.first;
|
||||
}
|
||||
return { nullptr };
|
||||
}
|
||||
|
||||
bool AppKeyBindings::TryKeyChord(const Settings::KeyChord& kc)
|
||||
{
|
||||
const auto keyIter = _keyShortcuts.find(kc);
|
||||
@ -344,4 +354,56 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return bindingsArray;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Takes the KeyModifier flags from Terminal and maps them to the WinRT types which are used by XAML
|
||||
// Return Value:
|
||||
// - a Windows::System::VirtualKeyModifiers object with the flags of which modifiers used.
|
||||
Windows::System::VirtualKeyModifiers AppKeyBindings::ConvertVKModifiers(Settings::KeyModifiers modifiers)
|
||||
{
|
||||
Windows::System::VirtualKeyModifiers keyModifiers = Windows::System::VirtualKeyModifiers::None;
|
||||
|
||||
if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Ctrl))
|
||||
{
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Control;
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Shift))
|
||||
{
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Shift;
|
||||
}
|
||||
if (WI_IsFlagSet(modifiers, Settings::KeyModifiers::Alt))
|
||||
{
|
||||
// note: Menu is the Alt VK_MENU
|
||||
keyModifiers |= Windows::System::VirtualKeyModifiers::Menu;
|
||||
}
|
||||
|
||||
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 };
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,9 +34,12 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
static TerminalApp::AppKeyBindings FromJson(Windows::Data::Json::JsonArray const& json);
|
||||
Windows::Data::Json::JsonArray ToJson();
|
||||
static Windows::System::VirtualKeyModifiers ConvertVKModifiers(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers);
|
||||
static winrt::hstring FormatOverrideShortcutText(winrt::Microsoft::Terminal::Settings::KeyModifiers modifiers);
|
||||
|
||||
bool TryKeyChord(winrt::Microsoft::Terminal::Settings::KeyChord const& kc);
|
||||
void SetKeyBinding(TerminalApp::ShortcutAction const& action, winrt::Microsoft::Terminal::Settings::KeyChord const& chord);
|
||||
Microsoft::Terminal::Settings::KeyChord GetKeyBinding(TerminalApp::ShortcutAction const& action);
|
||||
|
||||
DECLARE_EVENT(CopyText, _CopyTextHandlers, TerminalApp::CopyTextEventArgs);
|
||||
DECLARE_EVENT(PasteText, _PasteTextHandlers, TerminalApp::PasteTextEventArgs);
|
||||
|
||||
@ -67,6 +67,7 @@ namespace TerminalApp
|
||||
static AppKeyBindings FromJson(Windows.Data.Json.JsonArray json);
|
||||
|
||||
void SetKeyBinding(ShortcutAction action, Microsoft.Terminal.Settings.KeyChord chord);
|
||||
Microsoft.Terminal.Settings.KeyChord GetKeyBinding(ShortcutAction action);
|
||||
|
||||
event CopyTextEventArgs CopyText;
|
||||
event PasteTextEventArgs PasteText;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user