Support for navigating panes by MRU (#8183)

Adds a "move to previous pane" and "move to next pane" keybinding, which
navigates to the last/first focused pane

We assign pane IDs on creation and maintain a vector of active pane IDs
in MRU order. Navigating panes by MRU then requires specifying which
pane ID we want to focus. 

From our offline discussion (thanks @zadjii-msft for the concise
description):

> For the record, the full spec I'm imagining is:
> 
> { command": { "action": "focus(Next|Prev)Pane", "order": "inOrder"|"mru", "useSwitcher": true|false } },
> 
> and order defaults to mru, and useSwitcher will default to true, when
> there is a switcher. So 
> 
> { command": { "action": "focusNextPane" } },
> { command": { "action": "focusNextPane", "order": "mru" } },
> 
> these are the same action. (but right now we don't support the order
> param)
>  
> Then there'll be another PR for "focusPane(target=id)"
> 
> Then a third PR for "focus(Next|Prev)Pane(order=inOrder)"

> for the record, I prefer this approach over the "one action to rule
> them all" version with both target and order/direction as params,
> because I don't like the confusion of what happens if there's both
> target and order/direction provided. 

References #1000 
Closes #2871
This commit is contained in:
PankajBhojwani 2020-12-11 10:36:05 -08:00 committed by GitHub
parent eb2be374fd
commit 04309a2a49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 210 additions and 79 deletions

View file

@ -109,7 +109,17 @@
],
"type": "string"
},
"Direction": {
"FocusDirection": {
"enum": [
"left",
"right",
"up",
"down",
"previous"
],
"type": "string"
},
"ResizeDirection": {
"enum": [
"left",
"right",
@ -298,9 +308,9 @@
"properties": {
"action": { "type": "string", "pattern": "moveFocus" },
"direction": {
"$ref": "#/definitions/Direction",
"$ref": "#/definitions/FocusDirection",
"default": "left",
"description": "The direction to move focus in, between panes"
"description": "The direction to move focus in, between panes. Direction can be 'previous' to move to the most recently used pane."
}
}
}
@ -315,9 +325,9 @@
"properties": {
"action": { "type": "string", "pattern": "resizePane" },
"direction": {
"$ref": "#/definitions/Direction",
"$ref": "#/definitions/ResizeDirection",
"default": "left",
"description": "The direction to move the pane separator in"
"description": "The direction to move the pane separator in."
}
}
}
@ -332,10 +342,7 @@
},
{
"properties": {
"action": {
"type": "string",
"pattern": "sendInput"
},
"action": { "type": "string", "pattern": "sendInput" },
"input": {
"type": "string",
"default": "",
@ -375,10 +382,7 @@
},
{
"properties": {
"action": {
"type": "string",
"pattern": "openSettings"
},
"action": { "type": "string", "pattern": "openSettings" },
"target": {
"type": "string",
"default": "settingsFile",
@ -834,7 +838,8 @@
"desktopWallpaper"
]
}
]
],
"type": [ "string", "null" ]
},
"backgroundImageAlignment": {
"default": "center",

View file

@ -664,7 +664,7 @@ namespace TerminalAppLocalTests
Log::Comment(L"Move focus. This will cause us to un-zoom.");
result = RunOnUIThread([&page]() {
// Set up action
MoveFocusArgs args{ Direction::Left };
MoveFocusArgs args{ FocusDirection::Left };
ActionEventArgs eventArgs{ args };
page->_HandleMoveFocus(nullptr, eventArgs);

View file

@ -228,14 +228,14 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = args.ActionArgs().try_as<ResizePaneArgs>())
{
if (realArgs.Direction() == Direction::None)
if (realArgs.ResizeDirection() == ResizeDirection::None)
{
// Do nothing
args.Handled(false);
}
else
{
_ResizePane(realArgs.Direction());
_ResizePane(realArgs.ResizeDirection());
args.Handled(true);
}
}
@ -246,14 +246,14 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = args.ActionArgs().try_as<MoveFocusArgs>())
{
if (realArgs.Direction() == Direction::None)
if (realArgs.FocusDirection() == FocusDirection::None)
{
// Do nothing
args.Handled(false);
}
else
{
_MoveFocus(realArgs.Direction());
_MoveFocus(realArgs.FocusDirection());
args.Handled(true);
}
}

View file

@ -130,7 +130,7 @@ void Pane::Relayout()
// decreasing the size of our first child.
// Return Value:
// - false if we couldn't resize this pane in the given direction, else true.
bool Pane::_Resize(const Direction& direction)
bool Pane::_Resize(const ResizeDirection& direction)
{
if (!DirectionMatchesSplit(direction, _splitState))
{
@ -138,7 +138,7 @@ bool Pane::_Resize(const Direction& direction)
}
float amount = .05f;
if (direction == Direction::Right || direction == Direction::Down)
if (direction == ResizeDirection::Right || direction == ResizeDirection::Down)
{
amount = -amount;
}
@ -171,7 +171,7 @@ bool Pane::_Resize(const Direction& direction)
// - direction: The direction to move the separator in.
// Return Value:
// - true if we or a child handled this resize request.
bool Pane::ResizePane(const Direction& direction)
bool Pane::ResizePane(const ResizeDirection& direction)
{
// If we're a leaf, do nothing. We can't possibly have a descendant with a
// separator the correct direction.
@ -223,14 +223,14 @@ bool Pane::ResizePane(const Direction& direction)
// - direction: The direction to move the focus in.
// Return Value:
// - true if we handled this focus move request.
bool Pane::_NavigateFocus(const Direction& direction)
bool Pane::_NavigateFocus(const FocusDirection& direction)
{
if (!DirectionMatchesSplit(direction, _splitState))
{
return false;
}
const bool focusSecond = (direction == Direction::Right) || (direction == Direction::Down);
const bool focusSecond = (direction == FocusDirection::Right) || (direction == FocusDirection::Down);
const auto newlyFocusedChild = focusSecond ? _secondChild : _firstChild;
@ -261,7 +261,7 @@ bool Pane::_NavigateFocus(const Direction& direction)
// - direction: The direction to move the focus in.
// Return Value:
// - true if we or a child handled this focus move request.
bool Pane::NavigateFocus(const Direction& direction)
bool Pane::NavigateFocus(const FocusDirection& direction)
{
// If we're a leaf, do nothing. We can't possibly have a descendant with a
// separator the correct direction.
@ -655,9 +655,10 @@ void Pane::_CloseChild(const bool closeFirst)
// inherited from us, so the flag will be set for both children.
_borders = _firstChild->_borders & _secondChild->_borders;
// take the control and profile of the pane that _wasn't_ closed.
// take the control, profile and id of the pane that _wasn't_ closed.
_control = remainingChild->_control;
_profile = remainingChild->_profile;
_id = remainingChild->Id();
// Add our new event handler before revoking the old one.
_connectionStateChangedToken = _control.ConnectionStateChanged({ this, &Pane::_ControlConnectionStateChangedHandler });
@ -1493,6 +1494,9 @@ std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Pane::_Split(SplitState
_SetupEntranceAnimation();
// Clear out our ID, only leaves should have IDs
_id = {};
return { _firstChild, _secondChild };
}
@ -1566,6 +1570,47 @@ void Pane::Restore(std::shared_ptr<Pane> zoomedPane)
}
}
// Method Description:
// - Retrieves the ID of this pane
// - NOTE: The caller should make sure that this pane is a leaf,
// otherwise the ID value will not make sense (leaves have IDs, parents do not)
// Return Value:
// - The ID of this pane
uint16_t Pane::Id() noexcept
{
return _id.value();
}
// Method Description:
// - Sets this pane's ID
// - Panes are given IDs upon creation by TerminalTab
// Arguments:
// - The number to set this pane's ID to
void Pane::Id(uint16_t id) noexcept
{
_id = id;
}
// Method Description:
// - Recursive function that focuses a pane with the given ID
// Arguments:
// - The ID of the pane we want to focus
void Pane::FocusPane(const uint16_t id)
{
if (_IsLeaf() && id == _id)
{
_control.Focus(FocusState::Programmatic);
}
else
{
if (_firstChild && _secondChild)
{
_firstChild->FocusPane(id);
_secondChild->FocusPane(id);
}
}
}
// Method Description:
// - Gets the size in pixels of each of our children, given the full size they
// should fill. Since these children own their own separators (borders), this

View file

@ -55,8 +55,8 @@ public:
const GUID& profile);
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
void Relayout();
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
bool ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
bool NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
bool CanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType);
std::pair<std::shared_ptr<Pane>, std::shared_ptr<Pane>> Split(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType,
@ -75,6 +75,10 @@ public:
void Maximize(std::shared_ptr<Pane> zoomedPane);
void Restore(std::shared_ptr<Pane> zoomedPane);
uint16_t Id() noexcept;
void Id(uint16_t id) noexcept;
void FocusPane(const uint16_t id);
WINRT_CALLBACK(Closed, winrt::Windows::Foundation::EventHandler<winrt::Windows::Foundation::IInspectable>);
DECLARE_EVENT(GotFocus, _GotFocusHandlers, winrt::delegate<std::shared_ptr<Pane>>);
DECLARE_EVENT(PaneRaiseVisualBell, _PaneRaiseVisualBellHandlers, winrt::delegate<std::shared_ptr<Pane>>);
@ -95,6 +99,8 @@ private:
winrt::Microsoft::Terminal::Settings::Model::SplitState _splitState{ winrt::Microsoft::Terminal::Settings::Model::SplitState::None };
float _desiredSplitPosition;
std::optional<uint16_t> _id;
bool _lastActive{ false };
std::optional<GUID> _profile{ std::nullopt };
winrt::event_token _connectionStateChangedToken{ 0 };
@ -124,8 +130,8 @@ private:
void _SetupEntranceAnimation();
void _UpdateBorders();
bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
bool _NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
bool _Resize(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
bool _NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
void _CloseChild(const bool closeFirst);
winrt::fire_and_forget _CloseChildRoutine(const bool closeFirst);
@ -156,15 +162,15 @@ private:
// - This is used for pane resizing (which will need a pane separator
// that's perpendicular to the direction to be able to move the separator
// in that direction).
// - Additionally, it will be used for moving focus between panes, which
// again happens _across_ a separator.
// - Also used for moving focus between panes, which again happens _across_ a separator.
// Arguments:
// - direction: The Direction to compare
// - splitType: The winrt::TerminalApp::SplitState to compare
// Return Value:
// - true iff the direction is perpendicular to the splitType. False for
// winrt::TerminalApp::SplitState::None.
static constexpr bool DirectionMatchesSplit(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction,
template<typename T>
static constexpr bool DirectionMatchesSplit(const T& direction,
const winrt::Microsoft::Terminal::Settings::Model::SplitState& splitType)
{
if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::None)
@ -173,13 +179,13 @@ private:
}
else if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::Horizontal)
{
return direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Up ||
direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Down;
return direction == T::Up ||
direction == T::Down;
}
else if (splitType == winrt::Microsoft::Terminal::Settings::Model::SplitState::Vertical)
{
return direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Left ||
direction == winrt::Microsoft::Terminal::Settings::Model::Direction::Right;
return direction == T::Left ||
direction == T::Right;
}
return false;
}

View file

@ -1395,7 +1395,7 @@ namespace winrt::TerminalApp::implementation
// - direction: The direction to move the focus in.
// Return Value:
// - <none>
void TerminalPage::_MoveFocus(const Direction& direction)
void TerminalPage::_MoveFocus(const FocusDirection& direction)
{
if (auto index{ _GetFocusedTabIndex() })
{
@ -1669,7 +1669,7 @@ namespace winrt::TerminalApp::implementation
// - direction: The direction to move the separator in.
// Return Value:
// - <none>
void TerminalPage::_ResizePane(const Direction& direction)
void TerminalPage::_ResizePane(const ResizeDirection& direction)
{
if (auto index{ _GetFocusedTabIndex() })
{

View file

@ -175,7 +175,7 @@ namespace winrt::TerminalApp::implementation
void _SelectNextTab(const bool bMoveRight);
bool _SelectTab(const uint32_t tabIndex);
void _MoveFocus(const Microsoft::Terminal::Settings::Model::Direction& direction);
void _MoveFocus(const Microsoft::Terminal::Settings::Model::FocusDirection& direction);
winrt::Microsoft::Terminal::TerminalControl::TermControl _GetActiveControl();
std::optional<uint32_t> _GetFocusedTabIndex() const noexcept;
@ -191,7 +191,7 @@ namespace winrt::TerminalApp::implementation
// MSFT:20641986: Add keybindings for New Window
void _Scroll(ScrollDirection scrollDirection, const Windows::Foundation::IReference<uint32_t>& rowsToScroll);
void _SplitPane(const Microsoft::Terminal::Settings::Model::SplitState splitType, const Microsoft::Terminal::Settings::Model::SplitType splitMode = Microsoft::Terminal::Settings::Model::SplitType::Manual, const Microsoft::Terminal::Settings::Model::NewTerminalArgs& newTerminalArgs = nullptr);
void _ResizePane(const Microsoft::Terminal::Settings::Model::Direction& direction);
void _ResizePane(const Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void _ScrollPage(ScrollDirection scrollDirection);
void _ScrollToBufferEdge(ScrollDirection scrollDirection);
void _SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::TerminalControl::KeyChord& keyChord);

View file

@ -28,6 +28,10 @@ namespace winrt::TerminalApp::implementation
{
_rootPane = std::make_shared<Pane>(profile, control, true);
_rootPane->Id(_nextPaneId);
_mruPanes.insert(_mruPanes.begin(), _nextPaneId);
++_nextPaneId;
_rootPane->Closed([=](auto&& /*s*/, auto&& /*e*/) {
_ClosedHandlers(nullptr, nullptr);
});
@ -268,7 +272,12 @@ namespace winrt::TerminalApp::implementation
// - <none>
void TerminalTab::SplitPane(SplitState splitType, const GUID& profile, TermControl& control)
{
// Make sure to take the ID before calling Split() - Split() will clear out the active pane's ID
const auto activePaneId = _activePane->Id();
auto [first, second] = _activePane->Split(splitType, profile, control);
first->Id(activePaneId);
second->Id(_nextPaneId);
++_nextPaneId;
_activePane = first;
_AttachEventHandlersToControl(control);
@ -312,7 +321,7 @@ namespace winrt::TerminalApp::implementation
// - direction: The direction to move the separator in.
// Return Value:
// - <none>
void TerminalTab::ResizePane(const Direction& direction)
void TerminalTab::ResizePane(const ResizeDirection& direction)
{
// NOTE: This _must_ be called on the root pane, so that it can propagate
// throughout the entire tree.
@ -326,11 +335,19 @@ namespace winrt::TerminalApp::implementation
// - direction: The direction to move the focus in.
// Return Value:
// - <none>
void TerminalTab::NavigateFocus(const Direction& direction)
void TerminalTab::NavigateFocus(const FocusDirection& direction)
{
// NOTE: This _must_ be called on the root pane, so that it can propagate
// throughout the entire tree.
_rootPane->NavigateFocus(direction);
if (direction == FocusDirection::Previous)
{
// To get to the previous pane, get the id of the previous pane and focus to that
_rootPane->FocusPane(_mruPanes.at(1));
}
else
{
// NOTE: This _must_ be called on the root pane, so that it can propagate
// throughout the entire tree.
_rootPane->NavigateFocus(direction);
}
}
// Method Description:
@ -444,6 +461,18 @@ namespace winrt::TerminalApp::implementation
// Update our own title text to match the newly-active pane.
UpdateTitle();
// We need to move the pane to the top of our mru list
// If its already somewhere in the list, remove it first
const auto paneId = pane->Id();
for (auto i = _mruPanes.begin(); i != _mruPanes.end(); ++i)
{
if (*i == paneId)
{
_mruPanes.erase(i);
break;
}
}
_mruPanes.insert(_mruPanes.begin(), paneId);
// Raise our own ActivePaneChanged event.
_ActivePaneChangedHandlers();
}
@ -460,6 +489,7 @@ namespace winrt::TerminalApp::implementation
void TerminalTab::_AttachEventHandlersToPane(std::shared_ptr<Pane> pane)
{
auto weakThis{ get_weak() };
std::weak_ptr<Pane> weakPane{ pane };
pane->GotFocus([weakThis](std::shared_ptr<Pane> sender) {
// Do nothing if the Tab's lifetime is expired or pane isn't new.
@ -475,7 +505,7 @@ namespace winrt::TerminalApp::implementation
// Add a Closed event handler to the Pane. If the pane closes out from
// underneath us, and it's zoomed, we want to be able to make sure to
// update our state accordingly to un-zoom that pane. See GH#7252.
pane->Closed([weakThis](auto&& /*s*/, auto && /*e*/) -> winrt::fire_and_forget {
pane->Closed([weakThis, weakPane](auto&& /*s*/, auto && /*e*/) -> winrt::fire_and_forget {
if (auto tab{ weakThis.get() })
{
if (tab->_zoomedPane)
@ -485,6 +515,17 @@ namespace winrt::TerminalApp::implementation
tab->Content(tab->_rootPane->GetRootElement());
tab->ExitZoom();
}
if (auto pane = weakPane.lock())
{
for (auto i = tab->_mruPanes.begin(); i != tab->_mruPanes.end(); ++i)
{
if (*i == pane->Id())
{
tab->_mruPanes.erase(i);
break;
}
}
}
}
});

View file

@ -40,8 +40,8 @@ namespace winrt::TerminalApp::implementation
bool PreCalculateCanSplit(winrt::Microsoft::Terminal::Settings::Model::SplitState splitType, winrt::Windows::Foundation::Size availableSpace) const;
void ResizeContent(const winrt::Windows::Foundation::Size& newSize);
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
void NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::Direction& direction);
void ResizePane(const winrt::Microsoft::Terminal::Settings::Model::ResizeDirection& direction);
void NavigateFocus(const winrt::Microsoft::Terminal::Settings::Model::FocusDirection& direction);
void UpdateSettings(const winrt::TerminalApp::TerminalSettings& settings, const GUID& profile);
winrt::fire_and_forget UpdateTitle();
@ -83,6 +83,9 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::UI::Xaml::Controls::MenuFlyoutItem _closeTabsAfterMenuItem{};
winrt::TerminalApp::TabHeaderControl _headerControl{};
std::vector<uint16_t> _mruPanes;
uint16_t _nextPaneId{ 0 };
bool _receivedKeyDown{ false };
winrt::hstring _runtimeTabText{};

View file

@ -147,18 +147,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring ResizePaneArgs::GenerateName() const
{
winrt::hstring directionString;
switch (_Direction)
switch (_ResizeDirection)
{
case Direction::Left:
case ResizeDirection::Left:
directionString = RS_(L"DirectionLeft");
break;
case Direction::Right:
case ResizeDirection::Right:
directionString = RS_(L"DirectionRight");
break;
case Direction::Up:
case ResizeDirection::Up:
directionString = RS_(L"DirectionUp");
break;
case Direction::Down:
case ResizeDirection::Down:
directionString = RS_(L"DirectionDown");
break;
}
@ -171,20 +171,22 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
winrt::hstring MoveFocusArgs::GenerateName() const
{
winrt::hstring directionString;
switch (_Direction)
switch (_FocusDirection)
{
case Direction::Left:
case FocusDirection::Left:
directionString = RS_(L"DirectionLeft");
break;
case Direction::Right:
case FocusDirection::Right:
directionString = RS_(L"DirectionRight");
break;
case Direction::Up:
case FocusDirection::Up:
directionString = RS_(L"DirectionUp");
break;
case Direction::Down:
case FocusDirection::Down:
directionString = RS_(L"DirectionDown");
break;
case FocusDirection::Previous:
return RS_(L"MoveFocusToLastUsedPane");
}
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"MoveFocusWithArgCommandKey")),

View file

@ -223,7 +223,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
struct ResizePaneArgs : public ResizePaneArgsT<ResizePaneArgs>
{
ResizePaneArgs() = default;
GETSET_PROPERTY(Model::Direction, Direction, Direction::None);
GETSET_PROPERTY(Model::ResizeDirection, ResizeDirection, ResizeDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -235,7 +235,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
auto otherAsUs = other.try_as<ResizePaneArgs>();
if (otherAsUs)
{
return otherAsUs->_Direction == _Direction;
return otherAsUs->_ResizeDirection == _ResizeDirection;
}
return false;
};
@ -243,8 +243,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<ResizePaneArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
if (args->_Direction == Direction::None)
JsonUtils::GetValueForKey(json, DirectionKey, args->_ResizeDirection);
if (args->_ResizeDirection == ResizeDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -256,7 +256,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
IActionArgs Copy() const
{
auto copy{ winrt::make_self<ResizePaneArgs>() };
copy->_Direction = _Direction;
copy->_ResizeDirection = _ResizeDirection;
return *copy;
}
};
@ -264,10 +264,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
struct MoveFocusArgs : public MoveFocusArgsT<MoveFocusArgs>
{
MoveFocusArgs() = default;
MoveFocusArgs(Model::Direction direction) :
_Direction{ direction } {};
MoveFocusArgs(Model::FocusDirection direction) :
_FocusDirection{ direction } {};
GETSET_PROPERTY(Model::Direction, Direction, Direction::None);
GETSET_PROPERTY(Model::FocusDirection, FocusDirection, FocusDirection::None);
static constexpr std::string_view DirectionKey{ "direction" };
@ -279,7 +279,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
auto otherAsUs = other.try_as<MoveFocusArgs>();
if (otherAsUs)
{
return otherAsUs->_Direction == _Direction;
return otherAsUs->_FocusDirection == _FocusDirection;
}
return false;
};
@ -287,8 +287,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MoveFocusArgs>();
JsonUtils::GetValueForKey(json, DirectionKey, args->_Direction);
if (args->_Direction == Direction::None)
JsonUtils::GetValueForKey(json, DirectionKey, args->_FocusDirection);
if (args->_FocusDirection == FocusDirection::None)
{
return { nullptr, { SettingsLoadWarnings::MissingRequiredParameter } };
}
@ -300,7 +300,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
IActionArgs Copy() const
{
auto copy{ winrt::make_self<MoveFocusArgs>() };
copy->_Direction = _Direction;
copy->_FocusDirection = _FocusDirection;
return *copy;
}
};

View file

@ -16,7 +16,7 @@ namespace Microsoft.Terminal.Settings.Model
IActionArgs ActionArgs { get; };
};
enum Direction
enum ResizeDirection
{
None = 0,
Left,
@ -25,6 +25,16 @@ namespace Microsoft.Terminal.Settings.Model
Down
};
enum FocusDirection
{
None = 0,
Left,
Right,
Up,
Down,
Previous
};
enum SplitState
{
Automatic = -1,
@ -103,13 +113,13 @@ namespace Microsoft.Terminal.Settings.Model
[default_interface] runtimeclass ResizePaneArgs : IActionArgs
{
Direction Direction { get; };
ResizeDirection ResizeDirection { get; };
};
[default_interface] runtimeclass MoveFocusArgs : IActionArgs
{
MoveFocusArgs(Direction direction);
Direction Direction { get; };
MoveFocusArgs(FocusDirection direction);
FocusDirection FocusDirection { get; };
};
[default_interface] runtimeclass AdjustFontSizeArgs : IActionArgs

View file

@ -199,6 +199,9 @@
<data name="DirectionUp" xml:space="preserve">
<value>up</value>
</data>
<data name="DirectionPrevious" xml:space="preserve">
<value>previous</value>
</data>
<data name="DuplicatePaneCommandKey" xml:space="preserve">
<value>Duplicate pane</value>
</data>
@ -224,7 +227,10 @@
</data>
<data name="MoveFocusWithArgCommandKey" xml:space="preserve">
<value>Move focus {0}</value>
<comment>{0} will be replaced with one of the four directions "DirectionLeft", "DirectionRight", "DirectionUp", or "DirectionDown"</comment>
<comment>{0} will be replaced with one of the four directions "DirectionLeft", "DirectionRight", "DirectionUp", "DirectionDown"</comment>
</data>
<data name="MoveFocusToLastUsedPane" xml:space="preserve">
<value>Move focus to the last used pane</value>
</data>
<data name="NewTabCommandKey" xml:space="preserve">
<value>New tab</value>

View file

@ -328,14 +328,26 @@ struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<::winr
}
};
// Possible Direction values
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::Direction)
// Possible FocusDirection values
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FocusDirection)
{
JSON_MAPPINGS(5) = {
pair_type{ "left", ValueType::Left },
pair_type{ "right", ValueType::Right },
pair_type{ "up", ValueType::Up },
pair_type{ "down", ValueType::Down },
pair_type{ "previous", ValueType::Previous },
};
};
// Possible ResizeDirection values
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::ResizeDirection)
{
JSON_MAPPINGS(4) = {
pair_type{ "left", ValueType::Left },
pair_type{ "right", ValueType::Right },
pair_type{ "up", ValueType::Up },
pair_type{ "down", ValueType::Down },
pair_type{ "down", ValueType::Down }
};
};

View file

@ -333,6 +333,7 @@
{ "command": { "action": "moveFocus", "direction": "left" }, "keys": "alt+left" },
{ "command": { "action": "moveFocus", "direction": "right" }, "keys": "alt+right" },
{ "command": { "action": "moveFocus", "direction": "up" }, "keys": "alt+up" },
{ "command": { "action": "moveFocus", "direction": "previous" }, "keys": "ctrl+alt+left" },
{ "command": "togglePaneZoom" },
// Clipboard Integration