diff --git a/.github/actions/spell-check/expect/expect.txt b/.github/actions/spell-check/expect/expect.txt index 01b64c42d78..73e9583499f 100644 --- a/.github/actions/spell-check/expect/expect.txt +++ b/.github/actions/spell-check/expect/expect.txt @@ -2053,6 +2053,7 @@ Scrollup Scrolluppage SCS scursor +sclose sddl sdeleted sdk diff --git a/doc/cascadia/SettingsSchema.md b/doc/cascadia/SettingsSchema.md index 9c58edc89f4..bd740bb1ee4 100644 --- a/doc/cascadia/SettingsSchema.md +++ b/doc/cascadia/SettingsSchema.md @@ -23,6 +23,7 @@ Properties listed below affect the entire window, regardless of the profile sett | `tabWidthMode` | Optional | String | `equal` | Sets the width of the tabs. Possible values:
| | `wordDelimiters` | Optional | String |  /\()"'-:,.;<>~!@#$%^&*|+=[]{}~?│
_(`│` is `U+2502 BOX DRAWINGS LIGHT VERTICAL`)_ | Determines the delimiters used in a double click selection. | | `confirmCloseAllTabs` | Optional | Boolean | `true` | When set to `true` closing a window with multiple tabs open WILL require confirmation. When set to `false` closing a window with multiple tabs open WILL NOT require confirmation. | +| `confirmCloseTab` | Optional | Boolean | `true`| When set to `true` closing a tab with multiple panes WILL require confirmation. When set to `false` closing a tab with multiple panes WILL NOT require confirmation. | | `startOnUserLogin` | Optional | Boolean | `false` | When set to `true` enables the launch of Windows Terminal at startup. Setting to `false` will disable the startup task entry. Note: if the Windows Terminal startup task entry is disabled either by org policy or by user action this setting will have no effect. | | `disabledProfileSources` | Optional | Array[String] | `[]` | Disables all the dynamic profile generators in this list, preventing them from adding their profiles to the list of profiles on startup. This array can contain any combination of `Windows.Terminal.Wsl`, `Windows.Terminal.Azure`, or `Windows.Terminal.PowershellCore`. For more information, see [UsingJsonSettings.md](https://github.com/microsoft/terminal/blob/master/doc/user-docs/UsingJsonSettings.md#dynamic-profiles) | | `experimental.rendering.forceFullRepaint` | Optional | Boolean | `false` | When set to true, we will redraw the entire screen each frame. When set to false, we will render only the updates to the screen between frames. | diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 0ca40b685bd..5401b7011dd 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -479,6 +479,11 @@ "default": true, "description": "When set to \"true\" closing a window with multiple tabs open will require confirmation. When set to \"false\", the confirmation dialog will not appear.", "type": "boolean" + }, + "confirmCloseTab": { + "default": true, + "description": "When set to \"true\" closing a tab with multiple panes open will require confirmation. When set to \"false\", the confirmation dialog will not appear.", + "type": "boolean" } }, "required": [ diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.cpp b/src/cascadia/TerminalApp/GlobalAppSettings.cpp index dd3b17ae723..a8e386f3fad 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalApp/GlobalAppSettings.cpp @@ -34,6 +34,7 @@ static constexpr std::string_view WarnAboutLargePasteKey{ "largePasteWarning" }; static constexpr std::string_view WarnAboutMultiLinePasteKey{ "multiLinePasteWarning" }; static constexpr std::string_view LaunchModeKey{ "launchMode" }; static constexpr std::string_view ConfirmCloseAllKey{ "confirmCloseAllTabs" }; +static constexpr std::string_view ConfirmCloseTabKey{ "confirmCloseTab" }; static constexpr std::string_view SnapToGridOnResizeKey{ "snapToGridOnResize" }; static constexpr std::string_view EnableStartupTaskKey{ "startOnUserLogin" }; static constexpr std::string_view AlwaysOnTopKey{ "alwaysOnTop" }; @@ -140,6 +141,8 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, ConfirmCloseAllKey, _ConfirmCloseAllTabs); + JsonUtils::GetValueForKey(json, ConfirmCloseTabKey, _ConfirmCloseTab); + JsonUtils::GetValueForKey(json, InitialRowsKey, _InitialRows); JsonUtils::GetValueForKey(json, InitialColsKey, _InitialCols); diff --git a/src/cascadia/TerminalApp/GlobalAppSettings.h b/src/cascadia/TerminalApp/GlobalAppSettings.h index 7491b433f41..822e413b4bc 100644 --- a/src/cascadia/TerminalApp/GlobalAppSettings.h +++ b/src/cascadia/TerminalApp/GlobalAppSettings.h @@ -63,6 +63,7 @@ class TerminalApp::GlobalAppSettings final GETSET_PROPERTY(bool, AlwaysShowTabs, true); GETSET_PROPERTY(bool, ShowTitleInTitlebar, true); GETSET_PROPERTY(bool, ConfirmCloseAllTabs, true); + GETSET_PROPERTY(bool, ConfirmCloseTab, true); GETSET_PROPERTY(winrt::Windows::UI::Xaml::ElementTheme, Theme, winrt::Windows::UI::Xaml::ElementTheme::Default); GETSET_PROPERTY(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal); GETSET_PROPERTY(bool, ShowTabsInTitlebar, true); diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 6ca22a39ff0..5244b60bfa2 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -595,4 +595,16 @@ Dark Gray - + + Cancel + Close button text for Close all pane warning + + + Close all panes + Primary button text for Close all pane warning + + + Do you want to close all panes? + Title for Close all pane warning + + \ No newline at end of file diff --git a/src/cascadia/TerminalApp/Tab.h b/src/cascadia/TerminalApp/Tab.h index a6752fe6bbe..8c69692d22e 100644 --- a/src/cascadia/TerminalApp/Tab.h +++ b/src/cascadia/TerminalApp/Tab.h @@ -49,6 +49,8 @@ namespace winrt::TerminalApp::implementation void UpdateSettings(const winrt::Microsoft::Terminal::Settings::TerminalSettings& settings, const GUID& profile); winrt::hstring GetActiveTitle() const; + int _GetLeafPaneCount() const noexcept; + void Shutdown(); void ClosePane(); @@ -95,7 +97,6 @@ namespace winrt::TerminalApp::implementation void _AttachEventHandlersToControl(const winrt::Microsoft::Terminal::TerminalControl::TermControl& control); void _AttachEventHandlersToPane(std::shared_ptr pane); - int _GetLeafPaneCount() const noexcept; void _UpdateActivePane(std::shared_ptr pane); void _UpdateTabHeader(); diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 81cfaf1735c..bf9d025e90f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -380,6 +380,21 @@ namespace winrt::TerminalApp::implementation co_return ContentDialogResult::None; } + // Method Description: + // - Displays a dialog for warnings found while closing a terminal tab + // with multiple panes opened. Display messages to warn user + // that more than 1 pane is opened, and once the user clicks the OK button, remove + // all the panes and sclose the tab. If cancel is clicked, the dialog will close + // - Only one dialog can be visible at a time. If another dialog is visible + // when this is called, nothing happens. See _ShowDialog for details + void TerminalPage::_ShowCloseTabDialog() + { + if (auto presenter{ _dialogPresenter.get() }) + { + presenter.ShowDialog(FindName(L"CloseTabDialog").try_as()); + } + } + // Method Description: // - Builds the flyout (dropdown) attached to the new tab button, and // attaches it to the button. Populates the flyout with one entry per @@ -1856,8 +1871,19 @@ namespace winrt::TerminalApp::implementation // - eventArgs: the event's constituent arguments void TerminalPage::_OnTabCloseRequested(const IInspectable& /*sender*/, const MUX::Controls::TabViewTabCloseRequestedEventArgs& eventArgs) { - const auto tabViewItem = eventArgs.Tab(); - _RemoveTabViewItem(tabViewItem); + if (auto index{ _GetFocusedTabIndex() }) + { + auto focusedTab{ _GetStrongTabImpl(*index) }; + if (focusedTab->_GetLeafPaneCount() == 1 || !_settings->GlobalSettings().ConfirmCloseTab()) + { + const auto tabViewItem = eventArgs.Tab(); + _RemoveTabViewItem(tabViewItem); + } + else if (focusedTab->_GetLeafPaneCount() > 1 && _settings->GlobalSettings().ConfirmCloseTab()) + { + _ShowCloseTabDialog(); + } + } } // Method Description: @@ -1874,6 +1900,12 @@ namespace winrt::TerminalApp::implementation _CloseAllTabs(); } + void TerminalPage::_CloseTabWarningPrimaryButtonOnClick(WUX::Controls::ContentDialog /* sender */, + WUX::Controls::ContentDialogButtonClickEventArgs /* eventArgs*/) + { + _CloseFocusedTab(); + } + // Method Description: // - Hook up keybindings, and refresh the UI of the terminal. // This includes update the settings of all the tabs according diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index f78cfe86f23..5394d58dc07 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -114,6 +114,7 @@ namespace winrt::TerminalApp::implementation void _ShowCloseWarningDialog(); winrt::Windows::Foundation::IAsyncOperation _ShowMultiLinePasteWarningDialog(); winrt::Windows::Foundation::IAsyncOperation _ShowLargePasteWarningDialog(); + void _ShowCloseTabDialog(); void _CreateNewTabFlyout(); void _OpenNewTabDropdown(); @@ -124,6 +125,7 @@ namespace winrt::TerminalApp::implementation void _SettingsButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); void _FeedbackButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); void _AboutButtonOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); + void _CloseTabWarningPrimaryButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs); void _CloseWarningPrimaryButtonOnClick(Windows::UI::Xaml::Controls::ContentDialog sender, Windows::UI::Xaml::Controls::ContentDialogButtonClickEventArgs eventArgs); void _ThirdPartyNoticesOnClick(const IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& eventArgs); diff --git a/src/cascadia/TerminalApp/TerminalPage.xaml b/src/cascadia/TerminalApp/TerminalPage.xaml index c872b325029..f6ae2e654b4 100644 --- a/src/cascadia/TerminalApp/TerminalPage.xaml +++ b/src/cascadia/TerminalApp/TerminalPage.xaml @@ -68,6 +68,14 @@ the MIT License. See LICENSE in the project root for license information. --> DefaultButton="Primary"> + + +