Allow the user to set multiple globalSummon keys, and quakeMode for summoning the _quake window

This commit is contained in:
Mike Griese 2021-04-12 14:15:28 -05:00
parent 10779ca310
commit 25b31ff854
16 changed files with 151 additions and 22 deletions

View file

@ -752,4 +752,15 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}
void TerminalPage::_HandleGlobalSummon(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
args.Handled(false);
}
void TerminalPage::_HandleQuakeMode(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
args.Handled(false);
}
}

View file

@ -1380,9 +1380,14 @@ namespace winrt::TerminalApp::implementation
return _root ? _root->AlwaysOnTop() : false;
}
KeyChord AppLogic::GlobalHotkey()
// KeyChord AppLogic::GlobalHotkey()
// {
// return _settings.GlobalSettings().GlobalHotkey();
// }
Windows::Foundation::Collections::IMap<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::ActionAndArgs> AppLogic::GlobalHotkeys()
{
return _settings.GlobalSettings().GlobalHotkey();
return _settings.GlobalSettings().KeyMap().FetchGlobalHotkeys();
}
void AppLogic::IdentifyWindow()

View file

@ -89,7 +89,8 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> ShowDialog(winrt::Windows::UI::Xaml::Controls::ContentDialog dialog);
winrt::Microsoft::Terminal::Control::KeyChord GlobalHotkey();
// winrt::Microsoft::Terminal::Control::KeyChord GlobalHotkey();
Windows::Foundation::Collections::IMap<Microsoft::Terminal::Control::KeyChord, Microsoft::Terminal::Settings::Model::ActionAndArgs> GlobalHotkeys();
// -------------------------------- WinRT Events ---------------------------------
TYPED_EVENT(RequestedThemeChanged, winrt::Windows::Foundation::IInspectable, winrt::Windows::UI::Xaml::ElementTheme);

View file

@ -70,7 +70,8 @@ namespace TerminalApp
FindTargetWindowResult FindTargetWindow(String[] args);
Microsoft.Terminal.Control.KeyChord GlobalHotkey();
// Microsoft.Terminal.Control.KeyChord GlobalHotkey();
Windows.Foundation.Collections.IMap<Microsoft.Terminal.Control.KeyChord, Microsoft.Terminal.Settings.Model.ActionAndArgs> GlobalHotkeys();
// See IDialogPresenter and TerminalPage's DialogPresenter for more
// information.

View file

@ -57,6 +57,8 @@ static constexpr std::string_view IdentifyWindowKey{ "identifyWindow" };
static constexpr std::string_view IdentifyWindowsKey{ "identifyWindows" };
static constexpr std::string_view RenameWindowKey{ "renameWindow" };
static constexpr std::string_view OpenWindowRenamerKey{ "openWindowRenamer" };
static constexpr std::string_view GlobalSummonKey{ "globalSummon" };
static constexpr std::string_view QuakeModeKey{ "quakeMode" };
static constexpr std::string_view ActionKey{ "action" };
@ -127,6 +129,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ IdentifyWindowsKey, ShortcutAction::IdentifyWindows },
{ RenameWindowKey, ShortcutAction::RenameWindow },
{ OpenWindowRenamerKey, ShortcutAction::OpenWindowRenamer },
{ GlobalSummonKey, ShortcutAction::GlobalSummon },
{ QuakeModeKey, ShortcutAction::QuakeMode },
};
using ParseResult = std::tuple<IActionArgs, std::vector<SettingsLoadWarnings>>;
@ -162,6 +166,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::PrevTab, PrevTabArgs::FromJson },
{ ShortcutAction::NextTab, NextTabArgs::FromJson },
{ ShortcutAction::RenameWindow, RenameWindowArgs::FromJson },
{ ShortcutAction::GlobalSummon, GlobalSummonArgs::FromJson },
{ ShortcutAction::Invalid, nullptr },
};
@ -337,6 +342,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::IdentifyWindows, RS_(L"IdentifyWindowsCommandKey") },
{ ShortcutAction::RenameWindow, RS_(L"ResetWindowNameCommandKey") },
{ ShortcutAction::OpenWindowRenamer, RS_(L"OpenWindowRenamerCommandKey") },
{ ShortcutAction::GlobalSummon, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::QuakeMode, L"" }, // Intentionally omitted, must be generated by GenerateName
};
}();

View file

@ -29,6 +29,7 @@
#include "PrevTabArgs.g.cpp"
#include "NextTabArgs.g.cpp"
#include "RenameWindowArgs.g.cpp"
#include "GlobalSummonArgs.g.cpp"
#include <LibraryResources.h>
@ -582,4 +583,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
return RS_(L"ResetWindowNameCommandKey");
}
winrt::hstring GlobalSummonArgs::GenerateName() const
{
return L"";
}
}

View file

@ -31,6 +31,7 @@
#include "PrevTabArgs.g.h"
#include "NextTabArgs.g.h"
#include "RenameWindowArgs.g.h"
#include "GlobalSummonArgs.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "JsonUtils.h"
@ -1035,6 +1036,40 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return *copy;
}
};
struct GlobalSummonArgs : public GlobalSummonArgsT<GlobalSummonArgs>
{
GlobalSummonArgs() = default;
WINRT_PROPERTY(winrt::hstring, Name, L"");
static constexpr std::string_view NameKey{ "name" };
public:
hstring GenerateName() const;
bool Equals(const IActionArgs& other)
{
if (auto otherAsUs = other.try_as<GlobalSummonArgs>(); otherAsUs)
{
return otherAsUs->_Name == _Name;
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<GlobalSummonArgs>();
JsonUtils::GetValueForKey(json, NameKey, args->_Name);
return { *args, {} };
}
IActionArgs Copy() const
{
auto copy{ winrt::make_self<GlobalSummonArgs>() };
copy->_Name = _Name;
return *copy;
}
};
}
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation

View file

@ -251,4 +251,9 @@ namespace Microsoft.Terminal.Settings.Model
{
String Name { get; };
};
[default_interface] runtimeclass GlobalSummonArgs : IActionArgs
{
String Name { get; };
};
}

View file

@ -72,4 +72,6 @@
ON_ALL_ACTIONS(IdentifyWindow) \
ON_ALL_ACTIONS(IdentifyWindows) \
ON_ALL_ACTIONS(RenameWindow) \
ON_ALL_ACTIONS(OpenWindowRenamer)
ON_ALL_ACTIONS(OpenWindowRenamer) \
ON_ALL_ACTIONS(GlobalSummon) \
ON_ALL_ACTIONS(QuakeMode)

View file

@ -137,4 +137,29 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return keyModifiers;
}
Windows::Foundation::Collections::IMap<Control::KeyChord, Model::ActionAndArgs> KeyMapping::FetchGlobalHotkeys()
{
std::unordered_map<Control::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> justGlobals;
for (const auto& [k, v] : _keyShortcuts)
{
if (v.Action() == ShortcutAction::GlobalSummon)
{
justGlobals[k] = v;
}
else if (v.Action() == ShortcutAction::QuakeMode)
{
// Manually replace the QuakeMode action with a globalSummon
// that has the appropriate action args.
auto args = winrt::make_self<GlobalSummonArgs>();
args->Name(L"_quake");
Model::ActionAndArgs actionAndArgs{ ShortcutAction::GlobalSummon, *args };
justGlobals[k] = actionAndArgs;
}
}
return winrt::single_threaded_map<Control::KeyChord, Model::ActionAndArgs>(std::move(justGlobals));
}
}

View file

@ -69,6 +69,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
std::vector<Model::SettingsLoadWarnings> LayerJson(const Json::Value& json);
Json::Value ToJson();
Windows::Foundation::Collections::IMap<Control::KeyChord, Model::ActionAndArgs> FetchGlobalHotkeys();
private:
std::unordered_map<Control::KeyChord, Model::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
std::vector<std::pair<Control::KeyChord, Model::ActionAndArgs>> _keyShortcutsByInsertionOrder;

View file

@ -35,5 +35,7 @@ namespace Microsoft.Terminal.Settings.Model
Microsoft.Terminal.Control.KeyChord GetKeyBindingForAction(ShortcutAction action);
Microsoft.Terminal.Control.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs);
Windows.Foundation.Collections.IMap<Microsoft.Terminal.Control.KeyChord, ActionAndArgs> FetchGlobalHotkeys();
}
}

View file

@ -612,22 +612,41 @@ winrt::fire_and_forget AppHost::_BecomeMonarch(const winrt::Windows::Foundation:
co_await winrt::resume_foreground(_logic.GetRoot().Dispatcher(),
winrt::Windows::UI::Core::CoreDispatcherPriority::Normal);
// TODO! This needs to be a list
auto hotkey{ _logic.GlobalHotkey() };
_window->SetGlobalHotkey(hotkey);
// auto hotkey{ _logic.GlobalHotkey() };
// _window->SetGlobalHotkey(hotkey);
_hotkeyActions = _logic.GlobalHotkeys();
_hotkeys.clear();
for (const auto& [k, v] : _hotkeyActions)
{
_hotkeys.push_back(k);
}
_window->SetGlobalHotkeys(_hotkeys);
}
void AppHost::_GlobalHotkeyPressed()
void AppHost::_GlobalHotkeyPressed(const long hotkeyIndex)
{
Remoting::SummonWindowSelectionArgs args;
args.WindowName(L"_quake");
_windowManager.SummonWindow(args);
if (args.FoundMatch())
if (hotkeyIndex < 0 || hotkeyIndex > _hotkeys.size())
{
// Excellent, the window was found.
return;
}
else
Control::KeyChord kc = _hotkeys.at(hotkeyIndex);
const auto& actionAndArgs = _hotkeyActions.Lookup(kc);
if (actionAndArgs)
{
// We should make the window ourselves.
if (const auto& summonArgs{ actionAndArgs.Args().try_as<Settings::Model::GlobalSummonArgs>() })
{
Remoting::SummonWindowSelectionArgs args;
args.WindowName(summonArgs.Name());
_windowManager.SummonWindow(args);
if (args.FoundMatch())
{
// Excellent, the window was found.
}
else
{
// We should make the window ourselves.
}
}
}
}

View file

@ -28,6 +28,9 @@ private:
bool _shouldCreateWindow{ false };
winrt::Microsoft::Terminal::Remoting::WindowManager _windowManager{ nullptr };
std::vector<winrt::Microsoft::Terminal::Control::KeyChord> _hotkeys{ nullptr };
winrt::Windows::Foundation::Collections::IMap<winrt::Microsoft::Terminal::Control::KeyChord, winrt::Microsoft::Terminal::Settings::Model::ActionAndArgs> _hotkeyActions{ nullptr };
void _HandleCommandlineArgs();
void _HandleCreateWindow(const HWND hwnd, RECT proposedRect, winrt::Microsoft::Terminal::Settings::Model::LaunchMode& launchMode);
@ -54,7 +57,7 @@ private:
winrt::fire_and_forget _BecomeMonarch(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);
void _GlobalHotkeyPressed();
void _GlobalHotkeyPressed(const long hotkeyIndex);
void _HandleSummon(const winrt::Windows::Foundation::IInspectable& sender,
const winrt::Windows::Foundation::IInspectable& args);

View file

@ -354,7 +354,7 @@ long IslandWindow::_calculateTotalSize(const bool isWidth, const long clientSize
{
case WM_HOTKEY:
{
_HotkeyPressedHandlers();
_HotkeyPressedHandlers(static_cast<long>(wparam));
return 0;
}
case WM_GETMINMAXINFO:
@ -851,9 +851,11 @@ void IslandWindow::_ApplyWindowSize()
SWP_FRAMECHANGED | SWP_NOACTIVATE));
}
void IslandWindow::SetGlobalHotkey(const winrt::Microsoft::Terminal::Control::KeyChord& hotkey)
// void IslandWindow::SetGlobalHotkey(const winrt::Microsoft::Terminal::Control::KeyChord& hotkey)
void IslandWindow::SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList)
{
if (hotkey)
int index = 0;
for (const auto& hotkey : hotkeyList)
{
const auto modifiers = hotkey.Modifiers();
const auto hotkeyFlags = MOD_NOREPEAT |
@ -868,9 +870,11 @@ void IslandWindow::SetGlobalHotkey(const winrt::Microsoft::Terminal::Control::Ke
// TODO!: (discussion) should we display a warning of some kind if this
// fails? This can fail if something else already bound this hotkey.
LOG_IF_WIN32_BOOL_FALSE(RegisterHotKey(_window.get(),
1,
index,
hotkeyFlags,
hotkey.Vkey()));
index++;
}
}

View file

@ -38,7 +38,8 @@ public:
void FlashTaskbar();
void SetTaskbarProgress(const size_t state, const size_t progress);
void SetGlobalHotkey(const winrt::Microsoft::Terminal::Control::KeyChord& hotkey);
// void SetGlobalHotkey(const winrt::Microsoft::Terminal::Control::KeyChord& hotkey);
void SetGlobalHotkeys(const std::vector<winrt::Microsoft::Terminal::Control::KeyChord>& hotkeyList);
winrt::fire_and_forget SummonWindow();
@ -48,7 +49,7 @@ public:
DECLARE_EVENT(WindowCloseButtonClicked, _windowCloseButtonClickedHandler, winrt::delegate<>);
WINRT_CALLBACK(MouseScrolled, winrt::delegate<void(til::point, int32_t)>);
WINRT_CALLBACK(WindowActivated, winrt::delegate<void()>);
WINRT_CALLBACK(HotkeyPressed, winrt::delegate<void()>);
WINRT_CALLBACK(HotkeyPressed, winrt::delegate<void(long)>);
protected:
void ForceResize()