From 89d57e827e1694327435216c806e68eb796515d7 Mon Sep 17 00:00:00 2001 From: PankajBhojwani Date: Mon, 1 Aug 2022 14:11:18 -0700 Subject: [PATCH] [DxD] Add 'Automatic' as a mode for CloseOnExit (#13560) ## Summary of the Pull Request Adds a new mode to `CloseOnExit`: `Automatic`. In this mode, if a process handed off by defterm terminates for whatever reason, we always close (i.e. we treat the mode as `Always`), but for processes launched by Terminal we terminate as with the `Graceful` behaviour. ## PR Checklist * [x] Closes #13325 * [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA * [ ] Tests added/passed * [ ] Documentation updated. If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/terminal) and link it here: #xxx * [ ] Schema updated. * [x] I've discussed this with core contributors already. If not checked, I'm ready to accept this work might be rejected in favor of a different grand plan. Issue number where discussion took place: #xxx ## Detailed Description of the Pull Request / Additional comments - Adds a new enum value to `CloseOnExit` - Adds a new function to `Pane`: `FinalizeConfigurationGivenDefault`: this is a function that should be called when the pane is created via default terminal handoff, and can contain any special configurations we should set given that the pane was created via handoff ## Validation Steps Performed --- doc/cascadia/profiles.schema.json | 7 ++++--- src/cascadia/TerminalApp/Pane.cpp | 19 ++++++++++++++++++- src/cascadia/TerminalApp/Pane.h | 4 ++++ src/cascadia/TerminalApp/TerminalPage.cpp | 6 +++++- .../Resources/en-US/Resources.resw | 4 ++++ .../TerminalSettingsModel/MTSMSettings.h | 2 +- .../TerminalSettingsModel/Profile.idl | 3 ++- .../TerminalSettingsSerializationHelpers.h | 3 ++- .../TerminalSettingsModel/defaults.json | 4 ++-- 9 files changed, 42 insertions(+), 10 deletions(-) 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,