diff --git a/src/cascadia/TerminalApp/ActionArgs.h b/src/cascadia/TerminalApp/ActionArgs.h index dde9622e5d6..c1b2e93a3f9 100644 --- a/src/cascadia/TerminalApp/ActionArgs.h +++ b/src/cascadia/TerminalApp/ActionArgs.h @@ -331,13 +331,26 @@ namespace winrt::TerminalApp::implementation return TerminalApp::SplitState::None; }; + // Possible SplitType values + static constexpr std::string_view DuplicateKey{ "duplicate" }; + static TerminalApp::SplitType ParseSplitModeState(const std::string& stateString) + { + if (stateString == DuplicateKey) + { + return TerminalApp::SplitType::Duplicate; + } + return TerminalApp::SplitType::Manual; + } + struct SplitPaneArgs : public SplitPaneArgsT { SplitPaneArgs() = default; GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::None); GETSET_PROPERTY(winrt::TerminalApp::NewTerminalArgs, TerminalArgs, nullptr); + GETSET_PROPERTY(winrt::TerminalApp::SplitType, SplitMode, winrt::TerminalApp::SplitType::Manual); static constexpr std::string_view SplitKey{ "split" }; + static constexpr std::string_view SplitModeKey{ "splitMode" }; public: bool Equals(const IActionArgs& other) @@ -346,7 +359,8 @@ namespace winrt::TerminalApp::implementation if (otherAsUs) { return otherAsUs->_SplitStyle == _SplitStyle && - otherAsUs->_TerminalArgs == _TerminalArgs; + otherAsUs->_TerminalArgs == _TerminalArgs && + otherAsUs->_SplitMode == _SplitMode; } return false; }; @@ -359,6 +373,10 @@ namespace winrt::TerminalApp::implementation { args->_SplitStyle = ParseSplitState(jsonStyle.asString()); } + if (auto jsonStyle{ json[JsonKey(SplitModeKey)] }) + { + args->_SplitMode = ParseSplitModeState(jsonStyle.asString()); + } return { *args, {} }; } }; diff --git a/src/cascadia/TerminalApp/ActionArgs.idl b/src/cascadia/TerminalApp/ActionArgs.idl index 88679099948..44984588f0a 100644 --- a/src/cascadia/TerminalApp/ActionArgs.idl +++ b/src/cascadia/TerminalApp/ActionArgs.idl @@ -31,6 +31,12 @@ namespace TerminalApp Horizontal = 2 }; + enum SplitType + { + Manual = 0, + Duplicate = 1 + }; + [default_interface] runtimeclass NewTerminalArgs { NewTerminalArgs(); String Commandline; @@ -82,5 +88,6 @@ namespace TerminalApp { SplitState SplitStyle { get; }; NewTerminalArgs TerminalArgs { get; }; + SplitType SplitMode { get; }; }; } diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 2c4b132d044..2b288cb1000 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -98,7 +98,7 @@ namespace winrt::TerminalApp::implementation } else if (const auto& realArgs = args.ActionArgs().try_as()) { - _SplitPane(realArgs.SplitStyle(), realArgs.TerminalArgs()); + _SplitPane(realArgs.SplitStyle(), realArgs.SplitMode(), realArgs.TerminalArgs()); args.Handled(true); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index e0e80261cae..5b5c6668820 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1045,10 +1045,12 @@ namespace winrt::TerminalApp::implementation // Arguments: // - splitType: one value from the TerminalApp::SplitState enum, indicating how the // new pane should be split from its parent. + // - splitMode: value from TerminalApp::SplitType enum, indicating the profile to be used in the newly split pane. // - newTerminalArgs: An object that may contain a blob of parameters to // control which profile is created and with possible other // configurations. See CascadiaSettings::BuildSettings for more details. void TerminalPage::_SplitPane(const TerminalApp::SplitState splitType, + const TerminalApp::SplitType splitMode, const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs) { // Do nothing if we're requesting no split. @@ -1067,7 +1069,24 @@ namespace winrt::TerminalApp::implementation auto focusedTab = _GetStrongTabImpl(*indexOpt); - const auto [realGuid, controlSettings] = _settings->BuildSettings(newTerminalArgs); + winrt::Microsoft::Terminal::Settings::TerminalSettings controlSettings; + GUID realGuid; + bool profileFound = false; + + if (splitMode == TerminalApp::SplitType::Duplicate) + { + std::optional current_guid = focusedTab->GetFocusedProfile(); + if (current_guid) + { + profileFound = true; + controlSettings = _settings->BuildSettings(current_guid.value()); + realGuid = current_guid.value(); + } + } + if (!profileFound) + { + std::tie(realGuid, controlSettings) = _settings->BuildSettings(newTerminalArgs); + } const auto controlConnection = _CreateConnectionFromSettings(realGuid, controlSettings); diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 3da62c5b03d..684d55495f1 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -122,7 +122,7 @@ namespace winrt::TerminalApp::implementation // Todo: add more event implementations here // MSFT:20641986: Add keybindings for New Window void _Scroll(int delta); - void _SplitPane(const winrt::TerminalApp::SplitState splitType, const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs = nullptr); + void _SplitPane(const winrt::TerminalApp::SplitState splitType, const winrt::TerminalApp::SplitType splitMode = winrt::TerminalApp::SplitType::Manual, const winrt::TerminalApp::NewTerminalArgs& newTerminalArgs = nullptr); void _ResizePane(const Direction& direction); void _ScrollPage(int delta); void _SetAcceleratorForMenuItem(Windows::UI::Xaml::Controls::MenuFlyoutItem& menuItem, const winrt::Microsoft::Terminal::Settings::KeyChord& keyChord);