diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 1543b7b3986..d740324b310 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -2106,14 +2106,15 @@ "$ref": "#/$defs/BellSound" }, "closeOnExit": { - "default": "graceful", - "description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.", + "default": "automatic", + "description": "Sets how the profile reacts to termination or failure to launch. Possible values:\n -\"graceful\" (close when exit is typed or the process exits normally)\n -\"always\" (always close)\n -\"automatic\" (behave as \"graceful\" only for processes launched by terminal, behave as \"always\" otherwise)\n -\"never\" (never close).\ntrue and false are accepted as synonyms for \"graceful\" and \"never\" respectively.", "oneOf": [ { "enum": [ "never", "graceful", - "always" + "always", + "automatic" ], "type": "string" }, diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp index b8c1d079ed2..19b09d5e9ce 100644 --- a/src/cascadia/TerminalApp/Pane.cpp +++ b/src/cascadia/TerminalApp/Pane.cpp @@ -1019,9 +1019,17 @@ void Pane::_ControlConnectionStateChangedHandler(const winrt::Windows::Foundatio if (_profile) { + if (_isDefTermSession && _profile.CloseOnExit() == CloseOnExitMode::Automatic) + { + // For 'automatic', we only care about the connection state if we were launched by Terminal + // Since we were launched via defterm, ignore the connection state (i.e. we treat the + // close on exit mode as 'always', see GH #13325 for discussion) + Close(); + } + const auto mode = _profile.CloseOnExit(); if ((mode == CloseOnExitMode::Always) || - (mode == CloseOnExitMode::Graceful && newConnectionState == ConnectionState::Closed)) + ((mode == CloseOnExitMode::Graceful || mode == CloseOnExitMode::Automatic) && newConnectionState == ConnectionState::Closed)) { Close(); } @@ -3108,6 +3116,15 @@ int Pane::GetLeafPaneCount() const noexcept return _IsLeaf() ? 1 : (_firstChild->GetLeafPaneCount() + _secondChild->GetLeafPaneCount()); } +// Method Description: +// - Should be called when this pane is created via a default terminal handoff +// - Finalizes our configuration given the information that we have been +// created via default handoff +void Pane::FinalizeConfigurationGivenDefault() +{ + _isDefTermSession = true; +} + // Method Description: // - Returns true if the pane or one of its descendants is read-only bool Pane::ContainsReadOnly() const diff --git a/src/cascadia/TerminalApp/Pane.h b/src/cascadia/TerminalApp/Pane.h index 2c1fec243d6..7094f3b3643 100644 --- a/src/cascadia/TerminalApp/Pane.h +++ b/src/cascadia/TerminalApp/Pane.h @@ -132,6 +132,8 @@ class Pane : public std::enable_shared_from_this bool FocusPane(const std::shared_ptr pane); std::shared_ptr FindPane(const uint32_t id); + void FinalizeConfigurationGivenDefault(); + bool ContainsReadOnly() const; // Method Description: @@ -241,6 +243,8 @@ class Pane : public std::enable_shared_from_this bool _zoomed{ false }; + bool _isDefTermSession{ false }; + winrt::Windows::Media::Playback::MediaPlayer _bellPlayer{ nullptr }; winrt::Windows::Media::Playback::MediaPlayer::MediaEnded_revoker _mediaEndedRevoker; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 769c40d1ae5..eb8f02f06b8 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -3264,7 +3264,11 @@ namespace winrt::TerminalApp::implementation // elevated version of the Terminal with that profile... that's a // recipe for disaster. We won't ever open up a tab in this window. newTerminalArgs.Elevate(false); - _CreateNewTabFromPane(_MakePane(newTerminalArgs, false, connection)); + const auto newPane = _MakePane(newTerminalArgs, false, connection); + newPane->WalkTree([](auto pane) { + pane->FinalizeConfigurationGivenDefault(); + }); + _CreateNewTabFromPane(newPane); // Request a summon of this window to the foreground _SummonWindowRequestedHandlers(*this, nullptr); diff --git a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw index f7a229ee0de..37f90414406 100644 --- a/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsEditor/Resources/en-US/Resources.resw @@ -714,6 +714,10 @@ Never close automatically An option to choose from for the "profile termination behavior" (or "close on exit") setting. When selected, the terminal never closes, even if the process exits in a controlled or uncontrolled scenario. The user would have to manually close the terminal. + + Automatic + An option to choose from for the "profile termination behavior" (or "close on exit") setting. When selected, the terminal closes if the process exits in a controlled scenario successfully and the process was launched by Windows Terminal. + Color scheme Header for a control to select the scheme (or set) of colors used in the session. This is selected from a list of options managed by the user. diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index aeb3872b399..d95dbdfe43e 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -74,7 +74,7 @@ Author(s): X(bool, SuppressApplicationTitle, "suppressApplicationTitle", false) \ X(guid, ConnectionType, "connectionType") \ X(hstring, Icon, "icon", L"\uE756") \ - X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Graceful) \ + X(CloseOnExitMode, CloseOnExit, "closeOnExit", CloseOnExitMode::Automatic) \ X(hstring, TabTitle, "tabTitle") \ X(Model::BellStyle, BellStyle, "bellStyle", BellStyle::Audible) \ X(bool, UseAtlasEngine, "experimental.useAtlasEngine", false) \ diff --git a/src/cascadia/TerminalSettingsModel/Profile.idl b/src/cascadia/TerminalSettingsModel/Profile.idl index 76357b65898..608dfc5f914 100644 --- a/src/cascadia/TerminalSettingsModel/Profile.idl +++ b/src/cascadia/TerminalSettingsModel/Profile.idl @@ -26,7 +26,8 @@ namespace Microsoft.Terminal.Settings.Model { Never = 0, Graceful, - Always + Always, + Automatic }; [flags] diff --git a/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h b/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h index de205f332ff..c3f3f1e1f5e 100644 --- a/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h +++ b/src/cascadia/TerminalSettingsModel/TerminalSettingsSerializationHelpers.h @@ -136,10 +136,11 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Control::TextAntialiasingMode) // - Helper for converting a user-specified closeOnExit value to its corresponding enum JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::CloseOnExitMode) { - JSON_MAPPINGS(3) = { + JSON_MAPPINGS(4) = { pair_type{ "always", ValueType::Always }, pair_type{ "graceful", ValueType::Graceful }, pair_type{ "never", ValueType::Never }, + pair_type{ "automatic", ValueType::Automatic }, }; // Override mapping parser to add boolean parsing diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 7a672723c33..76d5f4b3bd1 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -43,7 +43,7 @@ "icon": "ms-appx:///ProfileIcons/{61c54bbd-c2c6-5271-96e7-009a87ff44bf}.png", "colorScheme": "Campbell", "antialiasingMode": "grayscale", - "closeOnExit": "graceful", + "closeOnExit": "automatic", "cursorShape": "bar", "fontFace": "Cascadia Mono", "fontSize": 12, @@ -62,7 +62,7 @@ "icon": "ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png", "colorScheme": "Campbell", "antialiasingMode": "grayscale", - "closeOnExit": "graceful", + "closeOnExit": "automatic", "cursorShape": "bar", "fontFace": "Cascadia Mono", "fontSize": 12,