mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-19 21:41:15 +00:00
Compare commits
7 Commits
user/migri
...
dev/cazamo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
730a8eb3c5 | ||
|
|
1bcd2e4d4f | ||
|
|
1154428f9c | ||
|
|
197969255a | ||
|
|
34e973fd18 | ||
|
|
f990fc2fbb | ||
|
|
da1d3224a1 |
@@ -514,6 +514,27 @@
|
||||
<data name="CloseAllDialog.Title" xml:space="preserve">
|
||||
<value>Do you want to close all tabs?</value>
|
||||
</data>
|
||||
<data name="CloseTabDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="CloseTabDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Close tab</value>
|
||||
</data>
|
||||
<data name="CloseTabDialog.Title" xml:space="preserve">
|
||||
<value>Do you want to close this tab?</value>
|
||||
</data>
|
||||
<data name="ClosePaneDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
<data name="ClosePaneDialog.PrimaryButtonText" xml:space="preserve">
|
||||
<value>Close pane</value>
|
||||
</data>
|
||||
<data name="ClosePaneDialog.Title" xml:space="preserve">
|
||||
<value>Do you want to close this pane?</value>
|
||||
</data>
|
||||
<data name="DontAskAgainCheckBox.Content" xml:space="preserve">
|
||||
<value>Don't ask me again</value>
|
||||
</data>
|
||||
<data name="CloseReadOnlyDialog.CloseButtonText" xml:space="preserve">
|
||||
<value>Cancel</value>
|
||||
</data>
|
||||
|
||||
@@ -413,6 +413,51 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we should warn before closing this tab based on the
|
||||
// confirmCloseOn flags (e.g. multiple panes, always, etc.)
|
||||
{
|
||||
const auto tabImpl = _GetTabImpl(tab);
|
||||
const auto reason = tabImpl ? _ShouldWarnOnCloseTab(tabImpl) : ConfirmCloseOn::Never;
|
||||
if (reason != ConfirmCloseOn::Never)
|
||||
{
|
||||
const auto weak = get_weak();
|
||||
|
||||
// Show the "don't ask me again" checkbox only when the dialog
|
||||
// is triggered by conditional flags (not just Always).
|
||||
const auto conditionalFlags = reason & ~ConfirmCloseOn::Always;
|
||||
const auto showCheckbox = conditionalFlags != ConfirmCloseOn::Never;
|
||||
|
||||
// Load the dialog (triggers x:Load) so we can configure the
|
||||
// checkbox before showing it.
|
||||
const auto dialog = FindName(L"CloseTabDialog").try_as<ContentDialog>();
|
||||
const auto checkbox = dialog ? dialog.Content().try_as<CheckBox>() : nullptr;
|
||||
if (checkbox)
|
||||
{
|
||||
checkbox.IsChecked(false);
|
||||
checkbox.Visibility(showCheckbox ? Visibility::Visible : Visibility::Collapsed);
|
||||
}
|
||||
|
||||
auto warningResult = co_await _ShowCloseTabWarningDialog();
|
||||
|
||||
strong = weak.get();
|
||||
|
||||
if (!strong || warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Persist dismissal if the user checked "don't ask me again"
|
||||
if (showCheckbox && checkbox && checkbox.IsChecked().Value())
|
||||
{
|
||||
const auto state = ApplicationState::SharedInstance();
|
||||
if (WI_IsFlagSet(reason, ConfirmCloseOn::MultiplePanes))
|
||||
{
|
||||
state.DismissedConfirmCloseMultiplePanes(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto t = winrt::get_self<implementation::Tab>(tab);
|
||||
auto actions = t->BuildStartupActions(BuildStartupKind::None);
|
||||
_AddPreviouslyClosedPaneOrTab(std::move(actions));
|
||||
@@ -782,6 +827,32 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto pane{ activeTab->GetActivePane() })
|
||||
{
|
||||
const auto weak = get_weak();
|
||||
|
||||
// Check if we should warn before closing a single pane
|
||||
// (only triggers on Always — or MultipleProcesses in the future)
|
||||
const auto flags = _settings.GlobalSettings().ConfirmCloseOn();
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::Always))
|
||||
{
|
||||
// The "don't ask me again" checkbox stays collapsed for
|
||||
// Always-only triggers. It will become relevant when
|
||||
// MultipleProcesses is implemented.
|
||||
// Load the dialog (triggers x:Load) to configure the checkbox.
|
||||
const auto dialog = FindName(L"ClosePaneDialog").try_as<ContentDialog>();
|
||||
if (const auto checkbox = dialog ? dialog.Content().try_as<CheckBox>() : nullptr)
|
||||
{
|
||||
checkbox.IsChecked(false);
|
||||
checkbox.Visibility(Visibility::Collapsed);
|
||||
}
|
||||
|
||||
auto warningResult = co_await _ShowClosePaneWarningDialog();
|
||||
if (warningResult != ContentDialogResult::Primary)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
}
|
||||
// TODO GH#6549: ConfirmCloseOn::MultipleProcesses check here
|
||||
// When implemented, show the checkbox and persist dismissal state.
|
||||
|
||||
if (co_await _PaneConfirmCloseReadOnly(pane))
|
||||
{
|
||||
if (const auto strong = weak.get())
|
||||
|
||||
@@ -906,6 +906,22 @@ namespace winrt::TerminalApp::implementation
|
||||
return _ShowDialogHelper(L"CloseAllDialog");
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog for warnings found while closing a tab that has
|
||||
// multiple panes or other conditions that warrant a warning.
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowCloseTabWarningDialog()
|
||||
{
|
||||
return _ShowDialogHelper(L"CloseTabDialog");
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog for warnings found while closing a single pane
|
||||
// (e.g. when confirmCloseOn includes "always").
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowClosePaneWarningDialog()
|
||||
{
|
||||
return _ShowDialogHelper(L"ClosePaneDialog");
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Displays a dialog for warnings found while closing the terminal tab marked as read-only
|
||||
winrt::Windows::Foundation::IAsyncOperation<ContentDialogResult> TerminalPage::_ShowCloseReadOnlyDialog()
|
||||
@@ -2308,12 +2324,99 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the terminal app. If there is more
|
||||
// than one tab opened, show a warning dialog.
|
||||
// - Determines whether a close-window action should show a confirmation
|
||||
// dialog, based on the confirmCloseOn flags and the current window state.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - The ConfirmCloseOn flags that triggered the warning, or Never if no
|
||||
// warning is needed. Callers use this to determine checkbox visibility
|
||||
// and which dismissal state to persist.
|
||||
ConfirmCloseOn TerminalPage::_ShouldWarnOnClose() const
|
||||
{
|
||||
auto result = ConfirmCloseOn::Never;
|
||||
const auto flags = _settings.GlobalSettings().ConfirmCloseOn();
|
||||
|
||||
// Always flag means warn unconditionally.
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::Always))
|
||||
{
|
||||
WI_SetFlag(result, ConfirmCloseOn::Always);
|
||||
}
|
||||
|
||||
// MultipleTabs: warn if there's more than one tab and the user hasn't
|
||||
// dismissed this warning via "don't ask me again".
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::MultipleTabs) &&
|
||||
_HasMultipleTabs() &&
|
||||
!ApplicationState::SharedInstance().DismissedConfirmCloseMultipleTabs())
|
||||
{
|
||||
WI_SetFlag(result, ConfirmCloseOn::MultipleTabs);
|
||||
}
|
||||
|
||||
// MultiplePanes: warn if any tab has more than one pane and the user
|
||||
// hasn't dismissed this warning via "don't ask me again".
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::MultiplePanes) &&
|
||||
!ApplicationState::SharedInstance().DismissedConfirmCloseMultiplePanes())
|
||||
{
|
||||
for (const auto tab : _tabs)
|
||||
{
|
||||
if (const auto impl = _GetTabImpl(tab))
|
||||
{
|
||||
if (impl->GetLeafPaneCount() > 1)
|
||||
{
|
||||
WI_SetFlag(result, ConfirmCloseOn::MultiplePanes);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO GH#6549: ConfirmCloseOn::MultipleProcesses
|
||||
// Needs TermControl to expose whether >1 client process is connected.
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Determines whether closing a specific tab should show a confirmation
|
||||
// dialog, based on the confirmCloseOn flags and the tab's state.
|
||||
// Arguments:
|
||||
// - tab: The tab being closed.
|
||||
// Return Value:
|
||||
// - The ConfirmCloseOn flags that triggered the warning, or Never if no
|
||||
// warning is needed.
|
||||
ConfirmCloseOn TerminalPage::_ShouldWarnOnCloseTab(const winrt::com_ptr<Tab>& tab) const
|
||||
{
|
||||
auto result = ConfirmCloseOn::Never;
|
||||
const auto flags = _settings.GlobalSettings().ConfirmCloseOn();
|
||||
|
||||
// Always flag means warn unconditionally.
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::Always))
|
||||
{
|
||||
WI_SetFlag(result, ConfirmCloseOn::Always);
|
||||
}
|
||||
|
||||
// MultiplePanes: warn if this tab has more than one pane and the user
|
||||
// hasn't dismissed this warning via "don't ask me again".
|
||||
if (WI_IsFlagSet(flags, ConfirmCloseOn::MultiplePanes) &&
|
||||
tab->GetLeafPaneCount() > 1 &&
|
||||
!ApplicationState::SharedInstance().DismissedConfirmCloseMultiplePanes())
|
||||
{
|
||||
WI_SetFlag(result, ConfirmCloseOn::MultiplePanes);
|
||||
}
|
||||
|
||||
// TODO GH#6549: ConfirmCloseOn::MultipleProcesses
|
||||
// Needs TermControl to expose whether >1 client process is connected.
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Close the terminal app. If the confirmCloseOn flags indicate we should
|
||||
// warn for the current window state, show a warning dialog.
|
||||
safe_void_coroutine TerminalPage::CloseWindow()
|
||||
{
|
||||
if (_HasMultipleTabs() &&
|
||||
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
|
||||
const auto reason = _ShouldWarnOnClose();
|
||||
if (reason != ConfirmCloseOn::Never &&
|
||||
!_displayingCloseDialog)
|
||||
{
|
||||
if (_newTabButton && _newTabButton.Flyout())
|
||||
@@ -2322,6 +2425,22 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
_DismissTabContextMenus();
|
||||
_displayingCloseDialog = true;
|
||||
|
||||
// Show the "don't ask me again" checkbox only when the dialog is
|
||||
// triggered by conditional flags (not just Always).
|
||||
const auto conditionalFlags = reason & ~ConfirmCloseOn::Always;
|
||||
const auto showCheckbox = conditionalFlags != ConfirmCloseOn::Never;
|
||||
|
||||
// Load the dialog (triggers x:Load) so we can configure the checkbox
|
||||
// before showing it.
|
||||
const auto dialog = FindName(L"CloseAllDialog").try_as<WUX::Controls::ContentDialog>();
|
||||
const auto checkbox = dialog ? dialog.Content().try_as<WUX::Controls::CheckBox>() : nullptr;
|
||||
if (checkbox)
|
||||
{
|
||||
checkbox.IsChecked(false);
|
||||
checkbox.Visibility(showCheckbox ? WUX::Visibility::Visible : WUX::Visibility::Collapsed);
|
||||
}
|
||||
|
||||
auto warningResult = co_await _ShowCloseWarningDialog();
|
||||
_displayingCloseDialog = false;
|
||||
|
||||
@@ -2329,6 +2448,20 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
// Persist dismissal if the user checked "don't ask me again"
|
||||
if (showCheckbox && checkbox && checkbox.IsChecked().Value())
|
||||
{
|
||||
const auto state = ApplicationState::SharedInstance();
|
||||
if (WI_IsFlagSet(reason, ConfirmCloseOn::MultipleTabs))
|
||||
{
|
||||
state.DismissedConfirmCloseMultipleTabs(true);
|
||||
}
|
||||
if (WI_IsFlagSet(reason, ConfirmCloseOn::MultiplePanes))
|
||||
{
|
||||
state.DismissedConfirmCloseMultiplePanes(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseWindowRequested.raise(*this, nullptr);
|
||||
|
||||
@@ -303,6 +303,8 @@ namespace winrt::TerminalApp::implementation
|
||||
void _ShowAboutDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowQuitDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseTabWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowClosePaneWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowCloseReadOnlyDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowMultiLinePasteWarningDialog();
|
||||
winrt::Windows::Foundation::IAsyncOperation<winrt::Windows::UI::Xaml::Controls::ContentDialogResult> _ShowLargePasteWarningDialog();
|
||||
@@ -400,6 +402,8 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::Tab _GetTabByTabViewItem(const IInspectable& tabViewItem) const noexcept;
|
||||
|
||||
void _HandleClosePaneRequested(std::shared_ptr<Pane> pane);
|
||||
Microsoft::Terminal::Settings::Model::ConfirmCloseOn _ShouldWarnOnClose() const;
|
||||
Microsoft::Terminal::Settings::Model::ConfirmCloseOn _ShouldWarnOnCloseTab(const winrt::com_ptr<Tab>& tab) const;
|
||||
safe_void_coroutine _SetFocusedTab(const winrt::TerminalApp::Tab tab);
|
||||
safe_void_coroutine _CloseFocusedPane();
|
||||
void _ClosePanes(weak_ref<Tab> weakTab, std::vector<uint32_t> paneIds);
|
||||
|
||||
@@ -96,7 +96,31 @@
|
||||
x:Uid="CloseAllDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary" />
|
||||
DefaultButton="Primary">
|
||||
<CheckBox x:Name="CloseAllDontAskAgain"
|
||||
x:Uid="DontAskAgainCheckBox"
|
||||
Visibility="Collapsed" />
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CloseTabDialog"
|
||||
x:Uid="CloseTabDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
<CheckBox x:Name="CloseTabDontAskAgain"
|
||||
x:Uid="DontAskAgainCheckBox"
|
||||
Visibility="Collapsed" />
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="ClosePaneDialog"
|
||||
x:Uid="ClosePaneDialog"
|
||||
Grid.Row="2"
|
||||
x:Load="False"
|
||||
DefaultButton="Primary">
|
||||
<CheckBox x:Name="ClosePaneDontAskAgain"
|
||||
x:Uid="DontAskAgainCheckBox"
|
||||
Visibility="Collapsed" />
|
||||
</ContentDialog>
|
||||
|
||||
<ContentDialog x:Name="CloseReadOnlyDialog"
|
||||
x:Uid="CloseReadOnlyDialog"
|
||||
|
||||
@@ -135,11 +135,19 @@
|
||||
<TextBlock x:Uid="Globals_WarningsHeader"
|
||||
Style="{StaticResource TextBlockSubHeaderStyle}" />
|
||||
|
||||
<!-- Close All Tabs Warning -->
|
||||
<local:SettingContainer x:Name="ConfirmCloseAllTabs"
|
||||
x:Uid="Globals_ConfirmCloseAllTabs">
|
||||
<ToggleSwitch IsOn="{x:Bind ViewModel.ConfirmCloseAllTabs, Mode=TwoWay}"
|
||||
Style="{StaticResource ToggleSwitchInExpanderStyle}" />
|
||||
<!-- Confirm Close On -->
|
||||
<local:SettingContainer x:Name="ConfirmCloseOn"
|
||||
x:Uid="Globals_ConfirmCloseOn"
|
||||
CurrentValue="{x:Bind ViewModel.ConfirmCloseOnPreview, Mode=OneWay}"
|
||||
Style="{StaticResource ExpanderSettingContainerStyle}">
|
||||
<StackPanel>
|
||||
<CheckBox x:Uid="Globals_ConfirmCloseOnAlways"
|
||||
IsChecked="{x:Bind ViewModel.IsConfirmCloseOnFlagSet(1), BindBack=ViewModel.SetConfirmCloseOnAlways, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Globals_ConfirmCloseOnMultipleTabs"
|
||||
IsChecked="{x:Bind ViewModel.IsConfirmCloseOnFlagSet(2), BindBack=ViewModel.SetConfirmCloseOnMultipleTabs, Mode=TwoWay}" />
|
||||
<CheckBox x:Uid="Globals_ConfirmCloseOnMultiplePanes"
|
||||
IsChecked="{x:Bind ViewModel.IsConfirmCloseOnFlagSet(4), BindBack=ViewModel.SetConfirmCloseOnMultiplePanes, Mode=TwoWay}" />
|
||||
</StackPanel>
|
||||
</local:SettingContainer>
|
||||
|
||||
<!-- Input Service Warning -->
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "InteractionViewModel.g.cpp"
|
||||
#include "EnumEntry.h"
|
||||
|
||||
using namespace winrt::Windows::UI::Xaml::Data;
|
||||
using namespace winrt::Windows::UI::Xaml::Navigation;
|
||||
using namespace winrt::Windows::Foundation;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
@@ -17,5 +18,91 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(TabSwitcherMode, TabSwitcherMode, TabSwitcherMode, L"Globals_TabSwitcherMode", L"Content");
|
||||
INITIALIZE_BINDABLE_ENUM_SETTING(CopyFormat, CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, L"Globals_CopyFormat", L"Content");
|
||||
|
||||
PropertyChanged([this](auto&&, const PropertyChangedEventArgs& args) {
|
||||
const auto viewModelProperty{ args.PropertyName() };
|
||||
if (viewModelProperty == L"ConfirmCloseOn")
|
||||
{
|
||||
_NotifyChanges(L"ConfirmCloseOnPreview");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
hstring InteractionViewModel::ConfirmCloseOnPreview() const
|
||||
{
|
||||
const auto flags = ConfirmCloseOn();
|
||||
if (WI_IsFlagSet(flags, Model::ConfirmCloseOn::Always))
|
||||
{
|
||||
return RS_(L"Globals_ConfirmCloseOnAlways/Content");
|
||||
}
|
||||
else if (flags == Model::ConfirmCloseOn::Never)
|
||||
{
|
||||
return RS_(L"Globals_ConfirmCloseOnNever");
|
||||
}
|
||||
|
||||
std::vector<hstring> resultList;
|
||||
resultList.reserve(2);
|
||||
if (WI_IsFlagSet(flags, Model::ConfirmCloseOn::MultipleTabs))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Globals_ConfirmCloseOnMultipleTabs/Content"));
|
||||
}
|
||||
if (WI_IsFlagSet(flags, Model::ConfirmCloseOn::MultiplePanes))
|
||||
{
|
||||
resultList.emplace_back(RS_(L"Globals_ConfirmCloseOnMultiplePanes/Content"));
|
||||
}
|
||||
|
||||
hstring result{};
|
||||
for (auto&& entry : resultList)
|
||||
{
|
||||
if (result.empty())
|
||||
{
|
||||
result = entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = result + L", " + entry;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool InteractionViewModel::IsConfirmCloseOnFlagSet(const uint32_t flag)
|
||||
{
|
||||
return (WI_EnumValue(ConfirmCloseOn()) & flag) == flag;
|
||||
}
|
||||
|
||||
void InteractionViewModel::SetConfirmCloseOnAlways(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto current = ConfirmCloseOn();
|
||||
WI_UpdateFlag(current, Model::ConfirmCloseOn::Always, winrt::unbox_value<bool>(on));
|
||||
ConfirmCloseOn(current);
|
||||
}
|
||||
|
||||
void InteractionViewModel::SetConfirmCloseOnMultipleTabs(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto current = ConfirmCloseOn();
|
||||
const auto enabled = winrt::unbox_value<bool>(on);
|
||||
WI_UpdateFlag(current, Model::ConfirmCloseOn::MultipleTabs, enabled);
|
||||
ConfirmCloseOn(current);
|
||||
|
||||
// Reset the dismissed state so the user sees the warning again
|
||||
if (enabled)
|
||||
{
|
||||
ApplicationState::SharedInstance().DismissedConfirmCloseMultipleTabs(false);
|
||||
}
|
||||
}
|
||||
|
||||
void InteractionViewModel::SetConfirmCloseOnMultiplePanes(winrt::Windows::Foundation::IReference<bool> on)
|
||||
{
|
||||
auto current = ConfirmCloseOn();
|
||||
const auto enabled = winrt::unbox_value<bool>(on);
|
||||
WI_UpdateFlag(current, Model::ConfirmCloseOn::MultiplePanes, enabled);
|
||||
ConfirmCloseOn(current);
|
||||
|
||||
// Reset the dismissed state so the user sees the warning again
|
||||
if (enabled)
|
||||
{
|
||||
ApplicationState::SharedInstance().DismissedConfirmCloseMultiplePanes(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WordDelimiters);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ConfirmCloseAllTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ConfirmCloseOn);
|
||||
hstring ConfirmCloseOnPreview() const;
|
||||
bool IsConfirmCloseOnFlagSet(const uint32_t flag);
|
||||
void SetConfirmCloseOnAlways(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetConfirmCloseOnMultipleTabs(winrt::Windows::Foundation::IReference<bool> on);
|
||||
void SetConfirmCloseOnMultiplePanes(winrt::Windows::Foundation::IReference<bool> on);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, InputServiceWarning);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutMultiLinePaste);
|
||||
|
||||
@@ -27,7 +27,12 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(String, WordDelimiters);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Settings.Model.ConfirmCloseOn, ConfirmCloseOn);
|
||||
String ConfirmCloseOnPreview { get; };
|
||||
Boolean IsConfirmCloseOnFlagSet(UInt32 flag);
|
||||
void SetConfirmCloseOnAlways(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetConfirmCloseOnMultipleTabs(Windows.Foundation.IReference<Boolean> on);
|
||||
void SetConfirmCloseOnMultiplePanes(Windows.Foundation.IReference<Boolean> on);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, InputServiceWarning);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Boolean, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(Microsoft.Terminal.Control.WarnAboutMultiLinePaste, WarnAboutMultiLinePaste);
|
||||
|
||||
@@ -2197,6 +2197,26 @@
|
||||
<value>Warn when closing more than one tab</value>
|
||||
<comment>Header for a control to toggle whether to show a confirm dialog box when closing the application with multiple tabs open.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmCloseOn.Header" xml:space="preserve">
|
||||
<value>Confirm before closing</value>
|
||||
<comment>Header for a group of checkboxes controlling when to show a confirmation dialog before closing.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmCloseOnAlways.Content" xml:space="preserve">
|
||||
<value>Always</value>
|
||||
<comment>Checkbox label: always confirm before closing a window, tab, or pane.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmCloseOnMultipleTabs.Content" xml:space="preserve">
|
||||
<value>Multiple tabs</value>
|
||||
<comment>Checkbox label: confirm before closing a window with more than one tab.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmCloseOnMultiplePanes.Content" xml:space="preserve">
|
||||
<value>Multiple panes</value>
|
||||
<comment>Checkbox label: confirm before closing a tab with more than one pane.</comment>
|
||||
</data>
|
||||
<data name="Globals_ConfirmCloseOnNever" xml:space="preserve">
|
||||
<value>Never</value>
|
||||
<comment>Preview text shown when no confirm-close-on flags are set.</comment>
|
||||
</data>
|
||||
<data name="Globals_InputServiceWarning.Header" xml:space="preserve">
|
||||
<value>Warn when "Touch Keyboard and Handwriting Panel Service" is disabled</value>
|
||||
</data>
|
||||
|
||||
@@ -42,7 +42,9 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
X(FileSource::Shared, Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::InfoBarMessage>, DismissedMessages, "dismissedMessages") \
|
||||
X(FileSource::Local, Windows::Foundation::Collections::IVector<hstring>, AllowedCommandlines, "allowedCommandlines") \
|
||||
X(FileSource::Local, std::unordered_set<hstring>, DismissedBadges, "dismissedBadges") \
|
||||
X(FileSource::Shared, bool, SSHFolderGenerated, "sshFolderGenerated", false)
|
||||
X(FileSource::Shared, bool, SSHFolderGenerated, "sshFolderGenerated", false) \
|
||||
X(FileSource::Shared, bool, DismissedConfirmCloseMultipleTabs, "warning.confirmCloseMultipleTabs", false) \
|
||||
X(FileSource::Shared, bool, DismissedConfirmCloseMultiplePanes, "warning.confirmCloseMultiplePanes", false)
|
||||
|
||||
struct WindowLayout : WindowLayoutT<WindowLayout>
|
||||
{
|
||||
|
||||
@@ -41,5 +41,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.Foundation.Collections.IVector<String> RecentCommands;
|
||||
Windows.Foundation.Collections.IVector<InfoBarMessage> DismissedMessages;
|
||||
Windows.Foundation.Collections.IVector<String> AllowedCommandlines;
|
||||
Boolean DismissedConfirmCloseMultipleTabs;
|
||||
Boolean DismissedConfirmCloseMultiplePanes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +160,16 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyInputServiceWarningKey, _InputServiceWarning) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyWarnAboutLargePasteKey, _WarnAboutLargePaste) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyWarnAboutMultiLinePasteKey, _WarnAboutMultiLinePaste) || _fixupsAppliedDuringLoad;
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyConfirmCloseAllTabsKey, _ConfirmCloseAllTabs) || _fixupsAppliedDuringLoad;
|
||||
// GH#6549 - Migrate legacy "confirmCloseAllTabs" boolean to the new
|
||||
// "confirmCloseOn" flags enum. true -> MultipleTabs|MultiplePanes, false -> Never.
|
||||
{
|
||||
std::optional<bool> legacyConfirmClose;
|
||||
if (JsonUtils::GetValueForKey(json, LegacyConfirmCloseAllTabsKey, legacyConfirmClose))
|
||||
{
|
||||
_ConfirmCloseOn = legacyConfirmClose.value() ? winrt::Microsoft::Terminal::Settings::Model::ConfirmCloseOn::MultipleTabs | winrt::Microsoft::Terminal::Settings::Model::ConfirmCloseOn::MultiplePanes : winrt::Microsoft::Terminal::Settings::Model::ConfirmCloseOn::Never;
|
||||
_fixupsAppliedDuringLoad = true;
|
||||
}
|
||||
}
|
||||
|
||||
#define GLOBAL_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::GetValueForKey(json, jsonKey, _##name); \
|
||||
|
||||
@@ -50,6 +50,17 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
AfterCurrentTab,
|
||||
};
|
||||
|
||||
[flags]
|
||||
enum ConfirmCloseOn
|
||||
{
|
||||
Never = 0x0,
|
||||
Always = 0x1,
|
||||
MultipleTabs = 0x2,
|
||||
MultiplePanes = 0x4,
|
||||
// TODO GH#6549: Future - requires TermControl to expose client count
|
||||
// MultipleProcesses = 0x8,
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass GlobalAppSettings {
|
||||
Guid DefaultProfile;
|
||||
|
||||
@@ -61,7 +72,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
|
||||
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
|
||||
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
INHERITABLE_SETTING(ConfirmCloseOn, ConfirmCloseOn);
|
||||
INHERITABLE_SETTING(String, Language);
|
||||
INHERITABLE_SETTING(Microsoft.UI.Xaml.Controls.TabViewWidthMode, TabWidthMode);
|
||||
INHERITABLE_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
|
||||
@@ -38,7 +38,7 @@ Author(s):
|
||||
X(bool, AlwaysShowTabs, "alwaysShowTabs", true) \
|
||||
X(Model::NewTabPosition, NewTabPosition, "newTabPosition", Model::NewTabPosition::AfterLastTab) \
|
||||
X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \
|
||||
X(bool, ConfirmCloseAllTabs, "warning.confirmCloseAllTabs", true) \
|
||||
X(Model::ConfirmCloseOn, ConfirmCloseOn, "warning.confirmCloseOn", Model::ConfirmCloseOn::MultipleTabs | Model::ConfirmCloseOn::MultiplePanes) \
|
||||
X(Model::ThemePair, Theme, "theme") \
|
||||
X(hstring, Language, "language") \
|
||||
X(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, "tabWidthMode", winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal) \
|
||||
|
||||
@@ -88,6 +88,38 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Core::MatchMode)
|
||||
};
|
||||
};
|
||||
|
||||
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::ConfirmCloseOn)
|
||||
{
|
||||
static constexpr std::array<pair_type, 4> mappings = {
|
||||
pair_type{ "never", AllClear },
|
||||
pair_type{ "always", ValueType::Always },
|
||||
pair_type{ "multipleTabs", ValueType::MultipleTabs },
|
||||
pair_type{ "multiplePanes", ValueType::MultiplePanes },
|
||||
// TODO GH#6549: Future - requires TermControl to expose client count
|
||||
// pair_type{ "multipleProcesses", ValueType::MultipleProcesses },
|
||||
};
|
||||
|
||||
auto FromJson(const Json::Value& json)
|
||||
{
|
||||
// Support legacy boolean: true -> MultipleTabs|MultiplePanes, false -> Never
|
||||
if (json.isBool())
|
||||
{
|
||||
return json.asBool() ? ValueType::MultipleTabs | ValueType::MultiplePanes : AllClear;
|
||||
}
|
||||
return BaseFlagMapper::FromJson(json);
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
{
|
||||
return BaseFlagMapper::CanConvert(json) || json.isBool();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const ::winrt::Microsoft::Terminal::Settings::Model::ConfirmCloseOn& val)
|
||||
{
|
||||
return BaseFlagMapper::ToJson(val);
|
||||
}
|
||||
};
|
||||
|
||||
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::BellStyle)
|
||||
{
|
||||
static constexpr std::array<pair_type, 6> mappings = {
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"showAdminShield": true,
|
||||
|
||||
// Miscellaneous
|
||||
"confirmCloseAllTabs": true,
|
||||
"warning.confirmCloseOn": ["multipleTabs", "multiplePanes"],
|
||||
"theme": "dark",
|
||||
"snapToGridOnResize": true,
|
||||
"disableAnimations": false,
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
"trimPaste": true,
|
||||
|
||||
"warning.confirmCloseAllTabs" : true,
|
||||
"warning.confirmCloseOn": ["multipleTabs", "multiplePanes"],
|
||||
"warning.inputService" : true,
|
||||
"warning.largePaste" : true,
|
||||
"warning.multiLinePaste" : "automatic",
|
||||
|
||||
Reference in New Issue
Block a user