Encapsulate dispatching ShortcutActions in it's own class (#3658)

## Summary of the Pull Request

Moves all the code responsible for dispatching an `ActionAndArgs` to it's own class, `ShortcutActionDispatch`. Now, the `AppKeyBindings` just uses the single instance of a `ShortcutActionDispatch` that the `TerminalPage` owns to dispatch events, without the need to re-attach the event handlers every time we reload the settings.

## References

This is something I originally did as a part of #2046.

I need this now for #607.

It's also a part of work for #3475

## PR Checklist
* [x] This is a bullet point within #3475
* [x] I work here
* [ ] Tests added/passed
* [n/a] Requires documentation to be updated

## Detailed Description of the Pull Request / Additional comments

With this change, we'll be able to have other things dispatch `ShortcutAction`s easily, by constructing an `ActionAndArgs` and just passing it straight to the `ShortcutActionDispatch`.

## Validation Steps Performed

Ran the Terminal, tried out some keybindings, namely <kbd>Ctrl+c</kbd> for copy when there is a selection, or send `^C` when there isn't. That still works. 

Reloading settings also still works. 

-----------------------------------------------
* Move action handling to it's own class separate from AKB. This is the first checkbox in #3475

(cherry picked from commit 696726b571d3d1fdf1d59844c76e182fc72cb2ea)

* clean up doc comments
This commit is contained in:
Mike Griese 2019-11-27 15:51:38 -06:00 committed by GitHub
parent 7bcb06079e
commit 111b88c8a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 427 additions and 327 deletions

View file

@ -70,190 +70,14 @@ namespace winrt::TerminalApp::implementation
if (keyIter != _keyShortcuts.end())
{
const auto actionAndArgs = keyIter->second;
return _DoAction(actionAndArgs);
return _dispatch.DoAction(actionAndArgs);
}
return false;
}
bool AppKeyBindings::_DoAction(ActionAndArgs actionAndArgs)
void AppKeyBindings::SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch)
{
const auto& action = actionAndArgs.Action();
const auto& args = actionAndArgs.Args();
auto eventArgs = args ? winrt::make_self<ActionEventArgs>(args) :
winrt::make_self<ActionEventArgs>();
switch (action)
{
case ShortcutAction::CopyText:
{
_CopyTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CopyTextWithoutNewlines:
{
_CopyTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::PasteText:
{
_PasteTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::OpenNewTabDropdown:
{
_OpenNewTabDropdownHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::DuplicateTab:
{
_DuplicateTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::OpenSettings:
{
_OpenSettingsHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NewTab:
case ShortcutAction::NewTabProfile0:
case ShortcutAction::NewTabProfile1:
case ShortcutAction::NewTabProfile2:
case ShortcutAction::NewTabProfile3:
case ShortcutAction::NewTabProfile4:
case ShortcutAction::NewTabProfile5:
case ShortcutAction::NewTabProfile6:
case ShortcutAction::NewTabProfile7:
case ShortcutAction::NewTabProfile8:
{
_NewTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NewWindow:
{
_NewWindowHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseWindow:
{
_CloseWindowHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseTab:
{
_CloseTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ClosePane:
{
_ClosePaneHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollUp:
{
_ScrollUpHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollDown:
{
_ScrollDownHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollUpPage:
{
_ScrollUpPageHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollDownPage:
{
_ScrollDownPageHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NextTab:
{
_NextTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::PrevTab:
{
_PrevTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SplitVertical:
{
_SplitVerticalHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SplitHorizontal:
{
_SplitHorizontalHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SwitchToTab:
case ShortcutAction::SwitchToTab0:
case ShortcutAction::SwitchToTab1:
case ShortcutAction::SwitchToTab2:
case ShortcutAction::SwitchToTab3:
case ShortcutAction::SwitchToTab4:
case ShortcutAction::SwitchToTab5:
case ShortcutAction::SwitchToTab6:
case ShortcutAction::SwitchToTab7:
case ShortcutAction::SwitchToTab8:
{
_SwitchToTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ResizePane:
case ShortcutAction::ResizePaneLeft:
case ShortcutAction::ResizePaneRight:
case ShortcutAction::ResizePaneUp:
case ShortcutAction::ResizePaneDown:
{
_ResizePaneHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::MoveFocus:
case ShortcutAction::MoveFocusLeft:
case ShortcutAction::MoveFocusRight:
case ShortcutAction::MoveFocusUp:
case ShortcutAction::MoveFocusDown:
{
_MoveFocusHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::IncreaseFontSize:
{
_AdjustFontSizeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::DecreaseFontSize:
{
_AdjustFontSizeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ResetFontSize:
{
auto eventArgs = winrt::make_self<ActionEventArgs>();
_ResetFontSizeHandlers(*this, *eventArgs);
return eventArgs->Handled();
}
case ShortcutAction::ToggleFullscreen:
{
_ToggleFullscreenHandlers(*this, *eventArgs);
break;
}
default:
return false;
}
return eventArgs->Handled();
_dispatch = dispatch;
}
// Method Description:

View file

@ -5,6 +5,7 @@
#include "AppKeyBindings.g.h"
#include "ActionArgs.h"
#include "ShortcutActionDispatch.h"
#include "..\inc\cppwinrt_utils.h"
// fwdecl unittest classes
@ -54,36 +55,12 @@ namespace winrt::TerminalApp::implementation
void LayerJson(const Json::Value& json);
Json::Value ToJson();
// clang-format off
TYPED_EVENT(CopyText, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(PasteText, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(OpenNewTabDropdown,TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(DuplicateTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(NewTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(NewWindow, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseWindow, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ClosePane, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(SwitchToTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(NextTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(PrevTab, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(SplitVertical, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(SplitHorizontal, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(AdjustFontSize, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ResetFontSize, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollUp, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollDown, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollUpPage, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollDownPage, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(OpenSettings, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ResizePane, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(MoveFocus, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleFullscreen, TerminalApp::AppKeyBindings, TerminalApp::ActionEventArgs);
// clang-format on
void SetDispatch(const winrt::TerminalApp::ShortcutActionDispatch& dispatch);
private:
std::unordered_map<winrt::Microsoft::Terminal::Settings::KeyChord, TerminalApp::ActionAndArgs, KeyChordHash, KeyChordEquality> _keyShortcuts;
bool _DoAction(ActionAndArgs actionAndArgs);
winrt::TerminalApp::ShortcutActionDispatch _dispatch{ nullptr };
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::KeyBindingsTests;
@ -92,7 +69,5 @@ namespace winrt::TerminalApp::implementation
namespace winrt::TerminalApp::factory_implementation
{
struct AppKeyBindings : AppKeyBindingsT<AppKeyBindings, implementation::AppKeyBindings>
{
};
BASIC_FACTORY(AppKeyBindings);
}

View file

@ -1,75 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "../ActionArgs.idl";
import "../ShortcutActionDispatch.idl";
namespace TerminalApp
{
// TODO: GH#1069 - Many of these shortcut actions are "legacy" now that we
// have support for arbitrary args (#1142). We should remove them, and our
// legacy deserializers.
enum ShortcutAction
{
Invalid = 0,
CopyText,
CopyTextWithoutNewlines,
PasteText,
OpenNewTabDropdown,
DuplicateTab,
NewTab,
NewTabProfile0, // Legacy
NewTabProfile1, // Legacy
NewTabProfile2, // Legacy
NewTabProfile3, // Legacy
NewTabProfile4, // Legacy
NewTabProfile5, // Legacy
NewTabProfile6, // Legacy
NewTabProfile7, // Legacy
NewTabProfile8, // Legacy
NewWindow,
CloseWindow,
CloseTab,
ClosePane,
NextTab,
PrevTab,
SplitVertical,
SplitHorizontal,
SwitchToTab,
SwitchToTab0, // Legacy
SwitchToTab1, // Legacy
SwitchToTab2, // Legacy
SwitchToTab3, // Legacy
SwitchToTab4, // Legacy
SwitchToTab5, // Legacy
SwitchToTab6, // Legacy
SwitchToTab7, // Legacy
SwitchToTab8, // Legacy
IncreaseFontSize,
DecreaseFontSize,
ResetFontSize,
ScrollUp,
ScrollDown,
ScrollUpPage,
ScrollDownPage,
ResizePane,
ResizePaneLeft, // Legacy
ResizePaneRight, // Legacy
ResizePaneUp, // Legacy
ResizePaneDown, // Legacy
MoveFocus,
MoveFocusLeft, // Legacy
MoveFocusRight, // Legacy
MoveFocusUp, // Legacy
MoveFocusDown, // Legacy
ToggleFullscreen,
OpenSettings
};
[default_interface] runtimeclass ActionAndArgs {
ActionAndArgs();
IActionArgs Args;
ShortcutAction Action;
};
[default_interface] runtimeclass AppKeyBindings : Microsoft.Terminal.Settings.IKeyBindings
{
AppKeyBindings();
@ -80,29 +15,6 @@ namespace TerminalApp
Microsoft.Terminal.Settings.KeyChord GetKeyBindingForAction(ShortcutAction action);
Microsoft.Terminal.Settings.KeyChord GetKeyBindingForActionWithArgs(ActionAndArgs actionAndArgs);
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> CopyText;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> PasteText;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> NewTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> OpenNewTabDropdown;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> DuplicateTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> NewWindow;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> CloseWindow;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> CloseTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ClosePane;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> SwitchToTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> NextTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> PrevTab;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> SplitVertical;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> SplitHorizontal;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> AdjustFontSize;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ResetFontSize;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ScrollUp;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ScrollDown;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ScrollUpPage;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ScrollDownPage;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> OpenSettings;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ResizePane;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> MoveFocus;
event Windows.Foundation.TypedEventHandler<AppKeyBindings, ActionEventArgs> ToggleFullscreen;
void SetDispatch(ShortcutActionDispatch dispatch);
}
}

View file

@ -0,0 +1,202 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#include "pch.h"
#include "ShortcutActionDispatch.h"
#include "ShortcutActionDispatch.g.cpp"
using namespace winrt::Microsoft::Terminal;
using namespace winrt::TerminalApp;
namespace winrt::TerminalApp::implementation
{
// Method Description:
// - Dispatch the appropriate event for the given ActionAndArgs. Constructs
// an ActionEventArgs to hold the IActionArgs payload for the event, and
// calls the matching handlers for that event.
// Arguments:
// - actionAndArgs: the ShortcutAction and associated args to raise an event for.
// Return Value:
// - true if we handled the event was handled, else false.
bool ShortcutActionDispatch::DoAction(const ActionAndArgs& actionAndArgs)
{
const auto& action = actionAndArgs.Action();
const auto& args = actionAndArgs.Args();
auto eventArgs = args ? winrt::make_self<ActionEventArgs>(args) :
winrt::make_self<ActionEventArgs>();
switch (action)
{
case ShortcutAction::CopyText:
{
_CopyTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CopyTextWithoutNewlines:
{
_CopyTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::PasteText:
{
_PasteTextHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::OpenNewTabDropdown:
{
_OpenNewTabDropdownHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::DuplicateTab:
{
_DuplicateTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::OpenSettings:
{
_OpenSettingsHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NewTab:
case ShortcutAction::NewTabProfile0:
case ShortcutAction::NewTabProfile1:
case ShortcutAction::NewTabProfile2:
case ShortcutAction::NewTabProfile3:
case ShortcutAction::NewTabProfile4:
case ShortcutAction::NewTabProfile5:
case ShortcutAction::NewTabProfile6:
case ShortcutAction::NewTabProfile7:
case ShortcutAction::NewTabProfile8:
{
_NewTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NewWindow:
{
_NewWindowHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseWindow:
{
_CloseWindowHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseTab:
{
_CloseTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ClosePane:
{
_ClosePaneHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollUp:
{
_ScrollUpHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollDown:
{
_ScrollDownHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollUpPage:
{
_ScrollUpPageHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ScrollDownPage:
{
_ScrollDownPageHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::NextTab:
{
_NextTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::PrevTab:
{
_PrevTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SplitVertical:
{
_SplitVerticalHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SplitHorizontal:
{
_SplitHorizontalHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::SwitchToTab:
case ShortcutAction::SwitchToTab0:
case ShortcutAction::SwitchToTab1:
case ShortcutAction::SwitchToTab2:
case ShortcutAction::SwitchToTab3:
case ShortcutAction::SwitchToTab4:
case ShortcutAction::SwitchToTab5:
case ShortcutAction::SwitchToTab6:
case ShortcutAction::SwitchToTab7:
case ShortcutAction::SwitchToTab8:
{
_SwitchToTabHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ResizePane:
case ShortcutAction::ResizePaneLeft:
case ShortcutAction::ResizePaneRight:
case ShortcutAction::ResizePaneUp:
case ShortcutAction::ResizePaneDown:
{
_ResizePaneHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::MoveFocus:
case ShortcutAction::MoveFocusLeft:
case ShortcutAction::MoveFocusRight:
case ShortcutAction::MoveFocusUp:
case ShortcutAction::MoveFocusDown:
{
_MoveFocusHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::IncreaseFontSize:
{
_AdjustFontSizeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::DecreaseFontSize:
{
_AdjustFontSizeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ResetFontSize:
{
_ResetFontSizeHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::ToggleFullscreen:
{
_ToggleFullscreenHandlers(*this, *eventArgs);
break;
}
default:
return false;
}
return eventArgs->Handled();
}
}

View file

@ -0,0 +1,61 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "ShortcutActionDispatch.g.h"
#include "ActionArgs.h"
#include "..\inc\cppwinrt_utils.h"
// fwdecl unittest classes
namespace TerminalAppLocalTests
{
class SettingsTests;
class KeyBindingsTests;
}
namespace winrt::TerminalApp::implementation
{
struct ShortcutActionDispatch : ShortcutActionDispatchT<ShortcutActionDispatch>
{
ShortcutActionDispatch() = default;
bool DoAction(const ActionAndArgs& actionAndArgs);
// clang-format off
TYPED_EVENT(CopyText, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(PasteText, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(OpenNewTabDropdown,TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(DuplicateTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(NewTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(NewWindow, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseWindow, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ClosePane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(SwitchToTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(NextTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(PrevTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(SplitVertical, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(SplitHorizontal, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(AdjustFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ResetFontSize, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollUp, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollDown, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollUpPage, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ScrollDownPage, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(OpenSettings, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ResizePane, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(MoveFocus, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ToggleFullscreen, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
// clang-format on
private:
friend class TerminalAppLocalTests::SettingsTests;
friend class TerminalAppLocalTests::KeyBindingsTests;
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(ShortcutActionDispatch);
}

View file

@ -0,0 +1,103 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import "../ActionArgs.idl";
namespace TerminalApp
{
// TODO: GH#1069 - Many of these shortcut actions are "legacy" now that we
// have support for arbitrary args (#1142). We should remove them, and our
// legacy deserializers.
enum ShortcutAction
{
Invalid = 0,
CopyText,
CopyTextWithoutNewlines,
PasteText,
OpenNewTabDropdown,
DuplicateTab,
NewTab,
NewTabProfile0, // Legacy
NewTabProfile1, // Legacy
NewTabProfile2, // Legacy
NewTabProfile3, // Legacy
NewTabProfile4, // Legacy
NewTabProfile5, // Legacy
NewTabProfile6, // Legacy
NewTabProfile7, // Legacy
NewTabProfile8, // Legacy
NewWindow,
CloseWindow,
CloseTab,
ClosePane,
NextTab,
PrevTab,
SplitVertical,
SplitHorizontal,
SwitchToTab,
SwitchToTab0, // Legacy
SwitchToTab1, // Legacy
SwitchToTab2, // Legacy
SwitchToTab3, // Legacy
SwitchToTab4, // Legacy
SwitchToTab5, // Legacy
SwitchToTab6, // Legacy
SwitchToTab7, // Legacy
SwitchToTab8, // Legacy
IncreaseFontSize,
DecreaseFontSize,
ResetFontSize,
ScrollUp,
ScrollDown,
ScrollUpPage,
ScrollDownPage,
ResizePane,
ResizePaneLeft, // Legacy
ResizePaneRight, // Legacy
ResizePaneUp, // Legacy
ResizePaneDown, // Legacy
MoveFocus,
MoveFocusLeft, // Legacy
MoveFocusRight, // Legacy
MoveFocusUp, // Legacy
MoveFocusDown, // Legacy
ToggleFullscreen,
OpenSettings
};
[default_interface] runtimeclass ActionAndArgs {
ActionAndArgs();
IActionArgs Args;
ShortcutAction Action;
};
[default_interface] runtimeclass ShortcutActionDispatch {
ShortcutActionDispatch();
Boolean DoAction(ActionAndArgs actionAndArgs);
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> CopyText;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> PasteText;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> NewTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> OpenNewTabDropdown;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> DuplicateTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> NewWindow;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> CloseWindow;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> CloseTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ClosePane;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> SwitchToTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> NextTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> PrevTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> SplitVertical;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> SplitHorizontal;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> AdjustFontSize;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ResetFontSize;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ScrollUp;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ScrollDown;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ScrollUpPage;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ScrollDownPage;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> OpenSettings;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ResizePane;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> MoveFocus;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ToggleFullscreen;
}
}

View file

@ -96,6 +96,9 @@ namespace winrt::TerminalApp::implementation
_setTitleBarContentHandlers(*this, _tabRow);
}
// Hookup our event handlers to the ShortcutActionDispatch
_RegisterActionCallbacks();
//Event Bindings (Early)
_newTabButton.Click([this](auto&&, auto&&) {
this->_OpenNewTab(std::nullopt);
@ -576,41 +579,51 @@ namespace winrt::TerminalApp::implementation
}
// Method Description:
// - Register our event handlers with the given keybindings object. This
// should be done regardless of what the events are actually bound to -
// this simply ensures the AppKeyBindings object will call us correctly
// for each event.
// - Configure the AppKeyBindings to use our ShortcutActionDispatch as the
// object to handle dispatching ShortcutAction events.
// Arguments:
// - bindings: A AppKeyBindings object to wire up with our event handlers
void TerminalPage::_HookupKeyBindings(TerminalApp::AppKeyBindings bindings) noexcept
{
// Hook up the KeyBinding object's events to our handlers.
bindings.SetDispatch(_actionDispatch);
}
// Method Description:
// - Register our event handlers with our ShortcutActionDispatch. The
// ShortcutActionDispatch is responsible for raising the appropriate
// events for an ActionAndArgs. WE'll handle each possible event in our
// own way.
// Arguments:
// - <none>
void TerminalPage::_RegisterActionCallbacks()
{
// Hook up the ShortcutActionDispatch object's events to our handlers.
// They should all be hooked up here, regardless of whether or not
// there's an actual keychord for them.
bindings.OpenNewTabDropdown({ this, &TerminalPage::_HandleOpenNewTabDropdown });
bindings.DuplicateTab({ this, &TerminalPage::_HandleDuplicateTab });
bindings.CloseTab({ this, &TerminalPage::_HandleCloseTab });
bindings.ClosePane({ this, &TerminalPage::_HandleClosePane });
bindings.CloseWindow({ this, &TerminalPage::_HandleCloseWindow });
bindings.ScrollUp({ this, &TerminalPage::_HandleScrollUp });
bindings.ScrollDown({ this, &TerminalPage::_HandleScrollDown });
bindings.NextTab({ this, &TerminalPage::_HandleNextTab });
bindings.PrevTab({ this, &TerminalPage::_HandlePrevTab });
bindings.SplitVertical({ this, &TerminalPage::_HandleSplitVertical });
bindings.SplitHorizontal({ this, &TerminalPage::_HandleSplitHorizontal });
bindings.ScrollUpPage({ this, &TerminalPage::_HandleScrollUpPage });
bindings.ScrollDownPage({ this, &TerminalPage::_HandleScrollDownPage });
bindings.OpenSettings({ this, &TerminalPage::_HandleOpenSettings });
bindings.PasteText({ this, &TerminalPage::_HandlePasteText });
bindings.NewTab({ this, &TerminalPage::_HandleNewTab });
bindings.SwitchToTab({ this, &TerminalPage::_HandleSwitchToTab });
bindings.ResizePane({ this, &TerminalPage::_HandleResizePane });
bindings.MoveFocus({ this, &TerminalPage::_HandleMoveFocus });
bindings.CopyText({ this, &TerminalPage::_HandleCopyText });
bindings.AdjustFontSize({ this, &TerminalPage::_HandleAdjustFontSize });
bindings.ResetFontSize({ this, &TerminalPage::_HandleResetFontSize });
bindings.ToggleFullscreen({ this, &TerminalPage::_HandleToggleFullscreen });
_actionDispatch.OpenNewTabDropdown({ this, &TerminalPage::_HandleOpenNewTabDropdown });
_actionDispatch.DuplicateTab({ this, &TerminalPage::_HandleDuplicateTab });
_actionDispatch.CloseTab({ this, &TerminalPage::_HandleCloseTab });
_actionDispatch.ClosePane({ this, &TerminalPage::_HandleClosePane });
_actionDispatch.CloseWindow({ this, &TerminalPage::_HandleCloseWindow });
_actionDispatch.ScrollUp({ this, &TerminalPage::_HandleScrollUp });
_actionDispatch.ScrollDown({ this, &TerminalPage::_HandleScrollDown });
_actionDispatch.NextTab({ this, &TerminalPage::_HandleNextTab });
_actionDispatch.PrevTab({ this, &TerminalPage::_HandlePrevTab });
_actionDispatch.SplitVertical({ this, &TerminalPage::_HandleSplitVertical });
_actionDispatch.SplitHorizontal({ this, &TerminalPage::_HandleSplitHorizontal });
_actionDispatch.ScrollUpPage({ this, &TerminalPage::_HandleScrollUpPage });
_actionDispatch.ScrollDownPage({ this, &TerminalPage::_HandleScrollDownPage });
_actionDispatch.OpenSettings({ this, &TerminalPage::_HandleOpenSettings });
_actionDispatch.PasteText({ this, &TerminalPage::_HandlePasteText });
_actionDispatch.NewTab({ this, &TerminalPage::_HandleNewTab });
_actionDispatch.SwitchToTab({ this, &TerminalPage::_HandleSwitchToTab });
_actionDispatch.ResizePane({ this, &TerminalPage::_HandleResizePane });
_actionDispatch.MoveFocus({ this, &TerminalPage::_HandleMoveFocus });
_actionDispatch.CopyText({ this, &TerminalPage::_HandleCopyText });
_actionDispatch.AdjustFontSize({ this, &TerminalPage::_HandleAdjustFontSize });
_actionDispatch.ResetFontSize({ this, &TerminalPage::_HandleResetFontSize });
_actionDispatch.ToggleFullscreen({ this, &TerminalPage::_HandleToggleFullscreen });
}
// Method Description:

View file

@ -65,6 +65,8 @@ namespace winrt::TerminalApp::implementation
std::optional<int> _rearrangeFrom;
std::optional<int> _rearrangeTo;
ShortcutActionDispatch _actionDispatch{};
void _ShowAboutDialog();
void _ShowCloseWarningDialog();
@ -80,6 +82,7 @@ namespace winrt::TerminalApp::implementation
void _CloseWarningPrimaryButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs);
void _HookupKeyBindings(TerminalApp::AppKeyBindings bindings) noexcept;
void _RegisterActionCallbacks();
void _UpdateTitle(std::shared_ptr<Tab> tab);
void _UpdateTabIcon(std::shared_ptr<Tab> tab);

View file

@ -87,6 +87,9 @@
<ClInclude Include="../WslDistroGenerator.h" />
<ClInclude Include="../AzureCloudShellGenerator.h" />
<ClInclude Include="pch.h" />
<ClInclude Include="../ShortcutActionDispatch.h" >
<DependentUpon>../ShortcutActionDispatch.idl</DependentUpon>
</ClInclude>
<ClInclude Include="../ActionArgs.h" >
<DependentUpon>../ActionArgs.idl</DependentUpon>
</ClInclude>
@ -141,6 +144,9 @@
<ClCompile Include="../AppKeyBindings.cpp" >
<DependentUpon>../AppKeyBindings.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../ShortcutActionDispatch.cpp" >
<DependentUpon>../ShortcutActionDispatch.idl</DependentUpon>
</ClCompile>
<ClCompile Include="../ActionAndArgs.cpp" >
<DependentUpon>../ActionArgs.idl</DependentUpon>
</ClCompile>
@ -172,6 +178,7 @@
<Midl Include="../App.idl" >
<DependentUpon>../App.xaml</DependentUpon>
</Midl>
<Midl Include="../ShortcutActionDispatch.idl" />
<Midl Include="../AppKeyBindings.idl" />
<Midl Include="../AppLogic.idl" />
<Midl Include="../ActionArgs.idl" />