diff --git a/src/cascadia/TerminalApp/App.cpp b/src/cascadia/TerminalApp/App.cpp index 903b225ba79..166e76658d4 100644 --- a/src/cascadia/TerminalApp/App.cpp +++ b/src/cascadia/TerminalApp/App.cpp @@ -484,6 +484,7 @@ namespace winrt::TerminalApp::implementation bindings.NewTab([this]() { _OpenNewTab(std::nullopt); }); bindings.DuplicateTab([this]() { _DuplicateTabViewItem(); }); bindings.CloseTab([this]() { _CloseFocusedTab(); }); + bindings.ClosePane([this]() { _CloseFocusedPane(); }); bindings.NewTabWithProfile([this](const auto index) { _OpenNewTab({ index }); }); bindings.ScrollUp([this]() { _Scroll(-1); }); bindings.ScrollDown([this]() { _Scroll(1); }); @@ -984,6 +985,17 @@ namespace winrt::TerminalApp::implementation _RemoveTabViewItem(focusedTab->GetTabViewItem()); } + // Method Description: + // - Close the currently focused pane. If the pane is the last pane in the + // tab, the tab will also be closed. This will happen when we handle the + // tab's Closed event. + void App::_CloseFocusedPane() + { + int focusedTabIndex = _GetFocusedTabIndex(); + std::shared_ptr focusedTab{ _tabs[focusedTabIndex] }; + focusedTab->ClosePane(); + } + // Method Description: // - Move the viewport of the terminal of the currently focused tab up or // down a number of lines. Negative values of `delta` will move the diff --git a/src/cascadia/TerminalApp/App.h b/src/cascadia/TerminalApp/App.h index c5868322af0..20b34b2e289 100644 --- a/src/cascadia/TerminalApp/App.h +++ b/src/cascadia/TerminalApp/App.h @@ -102,6 +102,7 @@ namespace winrt::TerminalApp::implementation void _OpenNewTab(std::optional profileIndex); void _DuplicateTabViewItem(); void _CloseFocusedTab(); + void _CloseFocusedPane(); void _SelectNextTab(const bool bMoveRight); void _SelectTab(const int tabIndex); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.cpp b/src/cascadia/TerminalApp/AppKeyBindings.cpp index 8a71fe4f0ef..8d9469d58a3 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindings.cpp @@ -102,6 +102,9 @@ namespace winrt::TerminalApp::implementation case ShortcutAction::CloseTab: _CloseTabHandlers(); return true; + case ShortcutAction::ClosePane: + _ClosePaneHandlers(); + return true; case ShortcutAction::ScrollUp: _ScrollUpHandlers(); @@ -249,6 +252,7 @@ namespace winrt::TerminalApp::implementation DEFINE_EVENT(AppKeyBindings, NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs); DEFINE_EVENT(AppKeyBindings, CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs); DEFINE_EVENT(AppKeyBindings, CloseTab, _CloseTabHandlers, TerminalApp::CloseTabEventArgs); + DEFINE_EVENT(AppKeyBindings, ClosePane, _ClosePaneHandlers, TerminalApp::ClosePaneEventArgs); DEFINE_EVENT(AppKeyBindings, SwitchToTab, _SwitchToTabHandlers, TerminalApp::SwitchToTabEventArgs); DEFINE_EVENT(AppKeyBindings, NextTab, _NextTabHandlers, TerminalApp::NextTabEventArgs); DEFINE_EVENT(AppKeyBindings, PrevTab, _PrevTabHandlers, TerminalApp::PrevTabEventArgs); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.h b/src/cascadia/TerminalApp/AppKeyBindings.h index eeb1e0270f5..39d618105b6 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.h +++ b/src/cascadia/TerminalApp/AppKeyBindings.h @@ -48,6 +48,7 @@ namespace winrt::TerminalApp::implementation DECLARE_EVENT(NewWindow, _NewWindowHandlers, TerminalApp::NewWindowEventArgs); DECLARE_EVENT(CloseWindow, _CloseWindowHandlers, TerminalApp::CloseWindowEventArgs); DECLARE_EVENT(CloseTab, _CloseTabHandlers, TerminalApp::CloseTabEventArgs); + DECLARE_EVENT(ClosePane, _ClosePaneHandlers, TerminalApp::ClosePaneEventArgs); DECLARE_EVENT(SwitchToTab, _SwitchToTabHandlers, TerminalApp::SwitchToTabEventArgs); DECLARE_EVENT(NextTab, _NextTabHandlers, TerminalApp::NextTabEventArgs); DECLARE_EVENT(PrevTab, _PrevTabHandlers, TerminalApp::PrevTabEventArgs); diff --git a/src/cascadia/TerminalApp/AppKeyBindings.idl b/src/cascadia/TerminalApp/AppKeyBindings.idl index b17d2dc5415..de195214de9 100644 --- a/src/cascadia/TerminalApp/AppKeyBindings.idl +++ b/src/cascadia/TerminalApp/AppKeyBindings.idl @@ -30,6 +30,7 @@ namespace TerminalApp NewWindow, CloseWindow, CloseTab, + ClosePane, NextTab, PrevTab, SplitVertical, @@ -68,6 +69,7 @@ namespace TerminalApp delegate void NewWindowEventArgs(); delegate void CloseWindowEventArgs(); delegate void CloseTabEventArgs(); + delegate void ClosePaneEventArgs(); delegate void NextTabEventArgs(); delegate void PrevTabEventArgs(); delegate void SplitVerticalEventArgs(); @@ -98,6 +100,7 @@ namespace TerminalApp event NewWindowEventArgs NewWindow; event CloseWindowEventArgs CloseWindow; event CloseTabEventArgs CloseTab; + event ClosePaneEventArgs ClosePane; event SwitchToTabEventArgs SwitchToTab; event NextTabEventArgs NextTab; event PrevTabEventArgs PrevTab; diff --git a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp index 5d43ef422fb..796f5957edd 100644 --- a/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp +++ b/src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp @@ -30,6 +30,7 @@ static constexpr std::string_view NewTabWithProfile8Key{ "newTabProfile8" }; static constexpr std::string_view NewWindowKey{ "newWindow" }; static constexpr std::string_view CloseWindowKey{ "closeWindow" }; static constexpr std::string_view CloseTabKey{ "closeTab" }; +static constexpr std::string_view ClosePaneKey{ "closePane" }; static constexpr std::string_view SwitchtoTabKey{ "switchToTab" }; static constexpr std::string_view NextTabKey{ "nextTab" }; static constexpr std::string_view PrevTabKey{ "prevTab" }; @@ -86,6 +87,7 @@ static const std::map> commandName { NewWindowKey, ShortcutAction::NewWindow }, { CloseWindowKey, ShortcutAction::CloseWindow }, { CloseTabKey, ShortcutAction::CloseTab }, + { ClosePaneKey, ShortcutAction::ClosePane }, { NextTabKey, ShortcutAction::NextTab }, { PrevTabKey, ShortcutAction::PrevTab }, { IncreaseFontSizeKey, ShortcutAction::IncreaseFontSize }, diff --git a/src/cascadia/TerminalApp/CascadiaSettings.cpp b/src/cascadia/TerminalApp/CascadiaSettings.cpp index 4c4b0545e8e..8604f4ffb16 100644 --- a/src/cascadia/TerminalApp/CascadiaSettings.cpp +++ b/src/cascadia/TerminalApp/CascadiaSettings.cpp @@ -287,8 +287,8 @@ void CascadiaSettings::_CreateDefaultKeybindings() KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift, static_cast('D') }); - keyBindings.SetKeyBinding(ShortcutAction::CloseTab, - KeyChord{ KeyModifiers::Ctrl, + keyBindings.SetKeyBinding(ShortcutAction::ClosePane, + KeyChord{ KeyModifiers::Ctrl | KeyModifiers::Shift, static_cast('W') }); keyBindings.SetKeyBinding(ShortcutAction::CopyText, diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index d093fc68b3b..173d5ef14a1 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -308,6 +308,18 @@ void Pane::_ControlClosedHandler() } } +// Method Description: +// - Fire our Closed event to tell our parent that we should be removed. +// Arguments: +// - +// Return Value: +// - +void Pane::Close() +{ + // Fire our Closed event to tell our parent that we should be removed. + _closedHandlers(); +} + // Method Description: // - Get the root UIElement of this pane. There may be a single TermControl as a // child, or an entire tree of grids and panes as children of this element. diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index 5f84ae0518c..2fb4a2e499f 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -52,6 +52,8 @@ class Pane : public std::enable_shared_from_this void SplitHorizontal(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control); void SplitVertical(const GUID& profile, const winrt::Microsoft::Terminal::TerminalControl::TermControl& control); + void Close(); + DECLARE_EVENT(Closed, _closedHandlers, winrt::Microsoft::Terminal::TerminalControl::ConnectionClosedEventArgs); private: diff --git a/src/cascadia/TerminalApp/Tab.cpp b/src/cascadia/TerminalApp/Tab.cpp index 0c4ea0d26a9..94acf9feee1 100644 --- a/src/cascadia/TerminalApp/Tab.cpp +++ b/src/cascadia/TerminalApp/Tab.cpp @@ -249,4 +249,18 @@ void Tab::NavigateFocus(const winrt::TerminalApp::Direction& direction) _rootPane->NavigateFocus(direction); } +// Method Description: +// - Closes the currently focused pane in this tab. If it's the last pane in +// this tab, our Closed event will be fired (at a later time) for anyone +// registered as a handler of our close event. +// Arguments: +// - +// Return Value: +// - +void Tab::ClosePane() +{ + auto focused = _rootPane->GetFocusedPane(); + focused->Close(); +} + DEFINE_EVENT(Tab, Closed, _closedHandlers, ConnectionClosedEventArgs); diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index ef796a28dc7..7e033ff323f 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -31,6 +31,8 @@ class Tab winrt::hstring GetFocusedTitle() const; void SetTabText(const winrt::hstring& text); + void ClosePane(); + DECLARE_EVENT(Closed, _closedHandlers, winrt::Microsoft::Terminal::TerminalControl::ConnectionClosedEventArgs); private: