Skip to content

Commit 06a225c

Browse files
committed
PRE-MERGE #20055 Replace confirmCloseAllTabs with confirmOnClose
2 parents 10381d1 + fe8730a commit 06a225c

21 files changed

Lines changed: 352 additions & 71 deletions

doc/cascadia/profiles.schema.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2654,10 +2654,21 @@
26542654
"type": "string"
26552655
},
26562656
"warning.confirmCloseAllTabs": {
2657+
"deprecated": true,
2658+
"description": "[Deprecated] Use \"warning.confirmOnClose\" instead.",
26572659
"default": true,
2658-
"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.",
26592660
"type": "boolean"
26602661
},
2662+
"warning.confirmOnClose": {
2663+
"default": "automatic",
2664+
"description": "Controls when a confirmation dialog appears before closing tabs or windows.",
2665+
"enum": [
2666+
"never",
2667+
"automatic",
2668+
"always"
2669+
],
2670+
"type": "string"
2671+
},
26612672
"useTabSwitcher": {
26622673
"description": "[Deprecated] Replaced with the \"tabSwitcherMode\" setting.",
26632674
"default": true,

src/cascadia/TerminalApp/AppActionHandlers.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,7 +801,7 @@ namespace winrt::TerminalApp::implementation
801801

802802
_RemoveTabs(tabsToRemove);
803803

804-
actionArgs.Handled(true);
804+
actionArgs.Handled(!tabsToRemove.empty());
805805
}
806806
}
807807

@@ -837,7 +837,7 @@ namespace winrt::TerminalApp::implementation
837837
// tab row, until you mouse over them. Probably has something to do
838838
// with tabs not resizing down until there's a mouse exit event.
839839

840-
actionArgs.Handled(true);
840+
actionArgs.Handled(!tabsToRemove.empty());
841841
}
842842
}
843843

src/cascadia/TerminalApp/Resources/en-US/Resources.resw

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -496,24 +496,48 @@
496496
<value>Third-Party notices</value>
497497
<comment>A hyperlink name for the Terminal's third-party notices</comment>
498498
</data>
499-
<data name="QuitDialog.CloseButtonText" xml:space="preserve">
499+
<data name="ConfirmCloseDialog_Cancel" xml:space="preserve">
500500
<value>Cancel</value>
501501
</data>
502-
<data name="QuitDialog.PrimaryButtonText" xml:space="preserve">
503-
<value>Close all</value>
504-
</data>
505-
<data name="QuitDialog.Title" xml:space="preserve">
502+
<data name="ConfirmCloseDialog_CloseAllTitle" xml:space="preserve">
506503
<value>Do you want to close all windows?</value>
507504
</data>
508-
<data name="CloseAllDialog.CloseButtonText" xml:space="preserve">
509-
<value>Cancel</value>
510-
</data>
511-
<data name="CloseAllDialog.PrimaryButtonText" xml:space="preserve">
505+
<data name="ConfirmCloseDialog_CloseAllPrimary" xml:space="preserve">
512506
<value>Close all</value>
513507
</data>
514-
<data name="CloseAllDialog.Title" xml:space="preserve">
508+
<data name="ConfirmCloseDialog_WindowTitle" xml:space="preserve">
515509
<value>Do you want to close all tabs?</value>
516510
</data>
511+
<data name="ConfirmCloseDialog_WindowPrimary" xml:space="preserve">
512+
<value>Close all</value>
513+
</data>
514+
<data name="ConfirmCloseDialog_TabTitle" xml:space="preserve">
515+
<value>Do you want to close this tab?</value>
516+
</data>
517+
<data name="ConfirmCloseDialog_TabPrimary" xml:space="preserve">
518+
<value>Close tab</value>
519+
</data>
520+
<data name="ConfirmCloseDialog_PaneTitle" xml:space="preserve">
521+
<value>Do you want to close this pane?</value>
522+
</data>
523+
<data name="ConfirmCloseDialog_PanePrimary" xml:space="preserve">
524+
<value>Close pane</value>
525+
</data>
526+
<data name="ConfirmCloseDialog_MultipleTabsTitle" xml:space="preserve">
527+
<value>Do you want to close these tabs?</value>
528+
</data>
529+
<data name="ConfirmCloseDialog_MultipleTabsPrimary" xml:space="preserve">
530+
<value>Close tabs</value>
531+
</data>
532+
<data name="ConfirmCloseDialog_MultiplePanesTitle" xml:space="preserve">
533+
<value>Do you want to close these panes?</value>
534+
</data>
535+
<data name="ConfirmCloseDialog_MultiplePanesPrimary" xml:space="preserve">
536+
<value>Close panes</value>
537+
</data>
538+
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
539+
<value>Don't ask me again</value>
540+
</data>
517541
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
518542
<value>Cancel</value>
519543
</data>

src/cascadia/TerminalApp/TabManagement.cpp

Lines changed: 79 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,9 @@ namespace winrt::TerminalApp::implementation
394394
// - Removes the tab (both TerminalControl and XAML) after prompting for approval
395395
// Arguments:
396396
// - tab: the tab to remove
397-
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab)
397+
// - skipConfirmClose: if true, skip the confirmOnClose check. Used when
398+
// an aggregate confirmation has already been shown (i.e. close other tabs)
399+
winrt::Windows::Foundation::IAsyncAction TerminalPage::_HandleCloseTabRequested(winrt::TerminalApp::Tab tab, bool skipConfirmClose)
398400
{
399401
winrt::com_ptr<TerminalPage> strong;
400402

@@ -413,6 +415,24 @@ namespace winrt::TerminalApp::implementation
413415
}
414416
}
415417

418+
// Skip the per-tab confirmOnClose check when the caller has already
419+
// shown an aggregate confirmation dialog (e.g. _RemoveTabs).
420+
if (!skipConfirmClose)
421+
{
422+
const auto tabImpl = _GetTabImpl(tab);
423+
if (tabImpl && _ShouldWarnOnCloseTab(tabImpl))
424+
{
425+
const auto weak = get_weak();
426+
427+
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::Tab);
428+
strong = weak.get();
429+
if (!strong || warningResult != ContentDialogResult::Primary)
430+
{
431+
co_return;
432+
}
433+
}
434+
}
435+
416436
auto t = winrt::get_self<implementation::Tab>(tab);
417437
auto actions = t->BuildStartupActions(BuildStartupKind::None);
418438
_AddPreviouslyClosedPaneOrTab(std::move(actions));
@@ -782,6 +802,22 @@ namespace winrt::TerminalApp::implementation
782802
if (const auto pane{ activeTab->GetActivePane() })
783803
{
784804
const auto weak = get_weak();
805+
806+
// Check if we should warn before closing a single pane
807+
// (only triggers on Always — Automatic doesn't warn for single pane)
808+
const auto setting = _settings.GlobalSettings().ConfirmOnClose();
809+
if (setting == ConfirmOnClose::Always)
810+
{
811+
// If this is the last pane, closing it closes the tab,
812+
// so use the tab dialog text instead.
813+
const auto kind = activeTab->GetLeafPaneCount() == 1 ? ConfirmCloseDialogKind::Tab : ConfirmCloseDialogKind::Pane;
814+
auto warningResult = co_await _ShowConfirmCloseDialog(kind);
815+
if (!weak.get() || warningResult != ContentDialogResult::Primary)
816+
{
817+
co_return;
818+
}
819+
}
820+
785821
if (co_await _PaneConfirmCloseReadOnly(pane))
786822
{
787823
if (const auto strong = weak.get())
@@ -795,10 +831,33 @@ namespace winrt::TerminalApp::implementation
795831

796832
// Method Description:
797833
// - Close all panes with the given IDs sequentially.
834+
// - Shows a single aggregate confirmation dialog upfront if the confirmOnClose setting warrants it.
798835
// Arguments:
799-
// - weakTab: weak reference to the tab that the pane belongs to.
836+
// - weakTab: weak reference to the tab that the panes belong to.
800837
// - paneIds: collection of the IDs of the panes that are marked for removal.
801-
void TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
838+
safe_void_coroutine TerminalPage::_ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
839+
{
840+
// Show a single aggregate confirmation for closing multiple panes.
841+
if (_settings.GlobalSettings().ConfirmOnClose() != ConfirmOnClose::Never)
842+
{
843+
const auto weak = get_weak();
844+
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::MultiplePanes);
845+
if (!weak.get() || warningResult != ContentDialogResult::Primary)
846+
{
847+
co_return;
848+
}
849+
}
850+
_CloseRemainingPanes(weakTab, std::move(paneIds));
851+
}
852+
853+
// Method Description:
854+
// - Recursively closes panes by ID, chaining each close via the
855+
// ClosedByParent callback. Called after confirmation has already
856+
// been handled by _ClosePanes.
857+
// Arguments:
858+
// - weakTab: weak reference to the tab that the panes belong to
859+
// - paneIds: remaining pane IDs to close
860+
void TerminalPage::_CloseRemainingPanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds)
802861
{
803862
if (auto strongTab{ weakTab.get() })
804863
{
@@ -813,10 +872,9 @@ namespace winrt::TerminalApp::implementation
813872
pane->ClosedByParent([ids{ std::move(paneIds) }, weakThis{ get_weak() }, weakTab]() {
814873
if (auto strongThis{ weakThis.get() })
815874
{
816-
strongThis->_ClosePanes(weakTab, std::move(ids));
875+
strongThis->_CloseRemainingPanes(weakTab, std::move(ids));
817876
}
818877
});
819-
820878
// Close the pane which will eventually trigger the closed by parent event
821879
_HandleClosePaneRequested(pane);
822880
break;
@@ -841,18 +899,33 @@ namespace winrt::TerminalApp::implementation
841899

842900
// Method Description:
843901
// - Closes provided tabs one by one
902+
// - Shows a single aggregate confirmation dialog upfront if the confirmOnClose setting warrants it.
844903
// Arguments:
845904
// - tabs - tabs to remove
846905
safe_void_coroutine TerminalPage::_RemoveTabs(const std::vector<winrt::TerminalApp::Tab> tabs)
847906
{
907+
if (tabs.empty())
908+
{
909+
co_return;
910+
}
911+
912+
// Show a single aggregate confirmation instead of per-tab dialogs.
848913
const auto weak = get_weak();
914+
if (_settings.GlobalSettings().ConfirmOnClose() != ConfirmOnClose::Never)
915+
{
916+
auto warningResult = co_await _ShowConfirmCloseDialog(ConfirmCloseDialogKind::MultipleTabs);
917+
if (!weak.get() || warningResult != ContentDialogResult::Primary)
918+
{
919+
co_return;
920+
}
921+
}
849922

850923
for (auto& tab : tabs)
851924
{
852925
winrt::Windows::Foundation::IAsyncAction action{ nullptr };
853926
if (const auto strong = weak.get())
854927
{
855-
action = _HandleCloseTabRequested(tab);
928+
action = _HandleCloseTabRequested(tab, /*skipConfirmClose*/ true);
856929
}
857930

858931
if (!action)

0 commit comments

Comments
 (0)