mirror of
https://github.com/microsoft/terminal.git
synced 2026-05-18 01:00:00 +00:00
Compare commits
4 Commits
dev/cazamo
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25e7320940 | ||
|
|
45ddf94067 | ||
|
|
abb06e1918 | ||
|
|
eb2899e267 |
@@ -1421,7 +1421,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile0", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1444,7 +1444,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1467,7 +1467,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
VERIFY_IS_NULL(terminalArgs.Elevate());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1492,7 +1492,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1516,7 +1516,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1540,7 +1540,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_FALSE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(false, termSettings->Elevate());
|
||||
@@ -1565,7 +1565,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1588,7 +1588,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
@@ -1612,7 +1612,7 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_IS_NOT_NULL(terminalArgs.Elevate());
|
||||
VERIFY_IS_TRUE(terminalArgs.Elevate().Value());
|
||||
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs);
|
||||
const auto termSettingsResult = TerminalSettings::CreateWithNewTerminalArgs(settings, terminalArgs, settings.WindowSettingsDefaults());
|
||||
const auto termSettings = termSettingsResult.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
VERIFY_ARE_EQUAL(true, termSettings->Elevate());
|
||||
|
||||
@@ -1097,6 +1097,7 @@ namespace TerminalAppLocalTests
|
||||
// Verify the MRU list directly.
|
||||
Log::Comment(L"Verify MRU order: MRU[0]=Tab[1], MRU[1]=Tab[3]");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
VERIFY_ARE_EQUAL(4u, page->_mruTabs.Size());
|
||||
uint32_t mruIdx;
|
||||
page->_tabs.IndexOf(page->_mruTabs.GetAt(0), mruIdx);
|
||||
@@ -1133,7 +1134,7 @@ namespace TerminalAppLocalTests
|
||||
// The Disabled tab switcher mode uses direct index-based switching
|
||||
// without the command palette, so it works in the test environment.
|
||||
Log::Comment(L"Change the tab switch order to not use the tab switcher (which is in-order always)");
|
||||
page->_settings.GlobalSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::Disabled);
|
||||
|
||||
Log::Comment(L"Switch to the next in-order tab: Tab[2]");
|
||||
TestOnUIThread([&page]() {
|
||||
@@ -1204,6 +1205,11 @@ namespace TerminalAppLocalTests
|
||||
VERIFY_ARE_EQUAL(L"a", page->_mruTabs.GetAt(3).Title());
|
||||
});
|
||||
|
||||
Log::Comment(L"Change the tab switch order to MRU switching");
|
||||
TestOnUIThread([&page]() {
|
||||
page->_currentWindowSettings().TabSwitcherMode(TabSwitcherMode::MostRecentlyUsed);
|
||||
});
|
||||
|
||||
Log::Comment(L"Select Tab[0] through Tab[3] to establish MRU order");
|
||||
RunOnUIThread([&page]() {
|
||||
page->_UpdatedSelectedTab(page->_tabs.GetAt(0));
|
||||
|
||||
@@ -550,7 +550,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto& realArgs = args.ActionArgs().try_as<CopyTextArgs>())
|
||||
{
|
||||
const auto copyFormatting = realArgs.CopyFormatting();
|
||||
const auto format = copyFormatting ? copyFormatting.Value() : _settings.GlobalSettings().CopyFormatting();
|
||||
const auto format = copyFormatting ? copyFormatting.Value() : _currentWindowSettings().CopyFormatting();
|
||||
const auto handled = _CopyText(realArgs.DismissSelection(), realArgs.SingleLine(), realArgs.WithControlSequences(), format);
|
||||
args.Handled(handled);
|
||||
}
|
||||
@@ -961,7 +961,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (const auto& terminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
|
||||
{
|
||||
const auto profile{ _settings.GetProfileForArgs(terminalArgs) };
|
||||
const auto profile{ _settings.GetProfileForArgs(terminalArgs, _currentWindowSettings()) };
|
||||
terminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
|
||||
}
|
||||
|
||||
@@ -1118,7 +1118,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// use global default if query URL is unspecified
|
||||
if (queryUrl.empty())
|
||||
{
|
||||
queryUrl = std::wstring_view{ _settings.GlobalSettings().SearchWebDefaultQueryUrl() };
|
||||
queryUrl = std::wstring_view{ _currentWindowSettings().SearchWebDefaultQueryUrl() };
|
||||
}
|
||||
|
||||
constexpr std::wstring_view queryToken{ L"%s" };
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace winrt::TerminalApp::implementation
|
||||
g_hTerminalAppProvider,
|
||||
"AppCreated",
|
||||
TraceLoggingDescription("Event emitted when the application is started"),
|
||||
TraceLoggingBool(_settings.GlobalSettings().ShowTabsInTitlebar(), "TabsInTitlebar"),
|
||||
TraceLoggingBool(_settings.WindowSettingsDefaults().ShowTabsInTitlebar(), "TabsInTitlebar"),
|
||||
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
|
||||
TelemetryPrivacyDataTag(PDT_ProductAndServiceUsage));
|
||||
}
|
||||
@@ -229,12 +229,12 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
_hasSettingsStartupActions = false;
|
||||
const auto startupActions = newSettings.GlobalSettings().StartupActions();
|
||||
const auto startupActions = newSettings.WindowSettingsDefaults().StartupActions();
|
||||
if (!startupActions.empty())
|
||||
{
|
||||
_settingsAppArgs.FullResetState();
|
||||
|
||||
ExecuteCommandlineArgs args{ newSettings.GlobalSettings().StartupActions() };
|
||||
ExecuteCommandlineArgs args{ newSettings.WindowSettingsDefaults().StartupActions() };
|
||||
auto result = _settingsAppArgs.ParseArgs(args);
|
||||
if (result == 0)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Stash away the current requested theme of the app. We'll need that in
|
||||
// _BackgroundBrush() to do a theme-aware resource lookup
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
|
||||
}
|
||||
|
||||
void SettingsPaneContent::UpdateSettings(const CascadiaSettings& settings)
|
||||
@@ -27,7 +27,7 @@ namespace winrt::TerminalApp::implementation
|
||||
ASSERT_UI_THREAD();
|
||||
_sui.UpdateSettings(settings);
|
||||
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme().RequestedTheme();
|
||||
_requestedTheme = settings.GlobalSettings().CurrentTheme(settings.WindowSettingsDefaults()).RequestedTheme();
|
||||
}
|
||||
|
||||
winrt::Windows::UI::Xaml::FrameworkElement SettingsPaneContent::GetRoot()
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
static const auto key = winrt::box_value(L"SettingsUiTabBrush");
|
||||
return ThemeLookup(WUX::Application::Current().Resources(),
|
||||
_settings.GlobalSettings().CurrentTheme().RequestedTheme(),
|
||||
_settings.GlobalSettings().CurrentTheme(_settings.WindowSettingsDefaults()).RequestedTheme(),
|
||||
key)
|
||||
.try_as<winrt::WUX::Media::Brush>();
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Make sure to try/catch this, because the LocalTests won't be
|
||||
// able to use this helper.
|
||||
const auto settings{ winrt::TerminalApp::implementation::AppLogic::CurrentAppSettings() };
|
||||
if (settings.GlobalSettings().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
if (settings.WindowSettingsDefaults().TabWidthMode() == winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::SizeToContent)
|
||||
{
|
||||
_headerControl.RenamerMaxWidth(HeaderRenameBoxWidthTitleLength);
|
||||
}
|
||||
|
||||
@@ -66,14 +66,14 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (const auto& newTerminalArgs{ newContentArgs.try_as<NewTerminalArgs>() })
|
||||
{
|
||||
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs) };
|
||||
const auto profile{ _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings()) };
|
||||
// GH#11114: GetProfileForArgs can return null if the index is higher
|
||||
// than the number of available profiles.
|
||||
if (!profile)
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs) };
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings()) };
|
||||
|
||||
// Try to handle auto-elevation
|
||||
if (_maybeElevate(newTerminalArgs, settings, profile))
|
||||
@@ -105,7 +105,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (insertPosition == -1)
|
||||
{
|
||||
insertPosition = _tabs.Size();
|
||||
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
{
|
||||
auto currentTabIndex = _GetFocusedTabIndex();
|
||||
if (currentTabIndex.has_value())
|
||||
@@ -220,7 +220,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (const auto content{ tab.GetActiveContent() })
|
||||
{
|
||||
const auto& icon{ content.Icon() };
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default;
|
||||
|
||||
tab.UpdateIcon(icon, iconStyle);
|
||||
@@ -231,7 +231,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - Handle changes to the tab width set by the user
|
||||
void TerminalPage::_UpdateTabWidthMode()
|
||||
{
|
||||
_tabView.TabWidthMode(_settings.GlobalSettings().TabWidthMode());
|
||||
_tabView.TabWidthMode(_currentWindowSettings().TabWidthMode());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -244,9 +244,9 @@ namespace winrt::TerminalApp::implementation
|
||||
// - there is more than one tab, or the user has chosen to always show tabs
|
||||
const auto isVisible = !_isInFocusMode &&
|
||||
(!_isFullscreen || _showTabsFullscreen) &&
|
||||
(_settings.GlobalSettings().ShowTabsInTitlebar() ||
|
||||
(_currentWindowSettings().ShowTabsInTitlebar() ||
|
||||
(_tabs.Size() > 1) ||
|
||||
_settings.GlobalSettings().AlwaysShowTabs());
|
||||
_currentWindowSettings().AlwaysShowTabs());
|
||||
|
||||
if (_tabView)
|
||||
{
|
||||
@@ -286,7 +286,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// current control's live settings (which will include changes
|
||||
// made through VT).
|
||||
uint32_t insertPosition = _tabs.Size();
|
||||
if (_settings.GlobalSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
if (_currentWindowSettings().NewTabPosition() == NewTabPosition::AfterCurrentTab)
|
||||
{
|
||||
insertPosition = tab.TabViewIndex() + 1;
|
||||
}
|
||||
@@ -477,7 +477,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// 1. We want to customize this behavior (e.g., use MRU logic)
|
||||
// 2. In fullscreen (GH#5799) and focus (GH#7916) modes the _OnTabItemsChanged is not fired
|
||||
// 3. When rearranging tabs (GH#7916) _OnTabItemsChanged is suppressed
|
||||
const auto tabSwitchMode = _settings.GlobalSettings().TabSwitcherMode();
|
||||
const auto tabSwitchMode = _currentWindowSettings().TabSwitcherMode();
|
||||
|
||||
if (tabSwitchMode == TabSwitcherMode::MostRecentlyUsed)
|
||||
{
|
||||
@@ -528,7 +528,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_SelectNextTab(const bool bMoveRight, const Windows::Foundation::IReference<Microsoft::Terminal::Settings::Model::TabSwitcherMode>& customTabSwitcherMode)
|
||||
{
|
||||
const auto index{ _GetFocusedTabIndex().value_or(0) };
|
||||
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _settings.GlobalSettings().TabSwitcherMode();
|
||||
const auto tabSwitchMode = customTabSwitcherMode ? customTabSwitcherMode.Value() : _currentWindowSettings().TabSwitcherMode();
|
||||
if (tabSwitchMode == TabSwitcherMode::Disabled)
|
||||
{
|
||||
auto tabCount = _tabs.Size();
|
||||
@@ -1017,7 +1017,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalPage::_UpdateBackground(const winrt::Microsoft::Terminal::Settings::Model::Profile& profile)
|
||||
{
|
||||
if (profile && _settings.GlobalSettings().UseBackgroundImageForWindow())
|
||||
if (profile && _currentWindowSettings().UseBackgroundImageForWindow())
|
||||
{
|
||||
_SetBackgroundImage(profile.DefaultAppearance());
|
||||
}
|
||||
|
||||
@@ -226,6 +226,11 @@ namespace winrt::TerminalApp::implementation
|
||||
_WindowProperties.PropertyChanged({ get_weak(), &TerminalPage::_windowPropertyChanged });
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::WindowSettings TerminalPage::_currentWindowSettings() const
|
||||
{
|
||||
return _settings.WindowSettings(_WindowProperties.WindowName());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - implements the IInitializeWithWindow interface from shobjidl_core.
|
||||
// - We're going to use this HWND as the owner for the ConPTY windows, via
|
||||
@@ -268,12 +273,19 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::SetSettings(CascadiaSettings settings, bool needRefreshUI)
|
||||
{
|
||||
assert(Dispatcher().HasThreadAccess());
|
||||
if (_settings == nullptr)
|
||||
|
||||
// IMPORTANT: we must assign _settings FIRST, because many downstream
|
||||
// helpers (e.g. _currentWindowSettings()) dereference it. On the very
|
||||
// first call _settings is nullptr, so any access before this line would
|
||||
// crash.
|
||||
const auto firstLoad = _settings == nullptr;
|
||||
_settings = settings;
|
||||
|
||||
if (firstLoad)
|
||||
{
|
||||
// Create this only on the first time we load the settings.
|
||||
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings);
|
||||
_terminalSettingsCache = std::make_shared<TerminalSettingsCache>(settings, _currentWindowSettings());
|
||||
}
|
||||
_settings = settings;
|
||||
|
||||
// Make sure to call SetCommands before _RefreshUIForSettingsReload.
|
||||
// SetCommands will make sure the KeyChordText of Commands is updated, which needs
|
||||
@@ -335,7 +347,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto tabRowImpl = winrt::get_self<implementation::TabRowControl>(_tabRow);
|
||||
_newTabButton = tabRowImpl->NewTabButton();
|
||||
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
if (_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
// Remove the TabView from the page. We'll hang on to it, we need to
|
||||
// put it in the titlebar.
|
||||
@@ -370,7 +382,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// Initialize the state of the CloseButtonOverlayMode property of
|
||||
// our TabView, to match the tab.showCloseButton property in the theme.
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme())
|
||||
if (const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()))
|
||||
{
|
||||
const auto visibility = theme.Tab() ? theme.Tab().ShowCloseButton() : Settings::Model::TabCloseButtonVisibility::Always;
|
||||
|
||||
@@ -425,7 +437,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
|
||||
|
||||
// Once the page is actually laid out on the screen, trigger all our
|
||||
// startup actions. Things like Panes need to know at least how big the
|
||||
@@ -434,14 +446,14 @@ namespace winrt::TerminalApp::implementation
|
||||
// _OnFirstLayout will remove this handler so it doesn't get called more than once.
|
||||
_layoutUpdatedRevoker = _tabContent.LayoutUpdated(winrt::auto_revoke, { this, &TerminalPage::_OnFirstLayout });
|
||||
|
||||
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
|
||||
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
|
||||
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
|
||||
|
||||
// DON'T set up Toasts/TeachingTips here. They should be loaded and
|
||||
// initialized the first time they're opened, in whatever method opens
|
||||
// them.
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
|
||||
|
||||
_adjustProcessPriorityThrottled = std::make_shared<ThrottledFunc<>>(
|
||||
DispatcherQueue::GetForCurrentThread(),
|
||||
@@ -520,7 +532,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// It's possible that newTerminalArgs is null here.
|
||||
// GetProfileForArgs should be resilient to that.
|
||||
const auto profile{ settings.GetProfileForArgs(newTerminalArgs) };
|
||||
const auto profile{ settings.GetProfileForArgs(newTerminalArgs, settings.WindowSettingsDefaults()) };
|
||||
if (profile.Elevate())
|
||||
{
|
||||
continue;
|
||||
@@ -951,7 +963,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Create profile entries from the NewTabMenu configuration using a
|
||||
// recursive helper function. This returns a std::vector of FlyoutItemBases,
|
||||
// that we then add to our Flyout.
|
||||
auto entries = _settings.GlobalSettings().NewTabMenu();
|
||||
auto entries = _currentWindowSettings().NewTabMenu();
|
||||
auto items = _CreateNewTabFlyoutItems(entries);
|
||||
for (const auto& item : items)
|
||||
{
|
||||
@@ -1233,7 +1245,7 @@ namespace winrt::TerminalApp::implementation
|
||||
profileMenuItem.Icon(icon);
|
||||
}
|
||||
|
||||
if (profile.Guid() == _settings.GlobalSettings().DefaultProfile())
|
||||
if (profile.Guid() == _currentWindowSettings().DefaultProfile())
|
||||
{
|
||||
// Contrast the default profile with others in font weight.
|
||||
profileMenuItem.FontWeight(FontWeights::Bold());
|
||||
@@ -1399,7 +1411,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if (newTerminalArgs.ProfileIndex() != nullptr)
|
||||
{
|
||||
// We want to promote the index to a GUID because there is no "launch to profile index" command.
|
||||
const auto profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
const auto profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
if (profile)
|
||||
{
|
||||
newTerminalArgs.Profile(::Microsoft::Console::Utils::GuidToString(profile.Guid()));
|
||||
@@ -1470,7 +1482,7 @@ namespace winrt::TerminalApp::implementation
|
||||
const bool inheritCursor)
|
||||
{
|
||||
static const auto textMeasurement = [&]() -> std::wstring_view {
|
||||
switch (_settings.GlobalSettings().TextMeasurement())
|
||||
switch (_currentWindowSettings().TextMeasurement())
|
||||
{
|
||||
case TextMeasurement::Graphemes:
|
||||
return L"graphemes";
|
||||
@@ -1596,7 +1608,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
|
||||
|
||||
// Replace the Starting directory with the CWD, if given
|
||||
const auto workingDirectory = control.WorkingDirectory();
|
||||
@@ -2312,7 +2324,7 @@ namespace winrt::TerminalApp::implementation
|
||||
safe_void_coroutine TerminalPage::CloseWindow()
|
||||
{
|
||||
if (_HasMultipleTabs() &&
|
||||
_settings.GlobalSettings().ConfirmCloseAllTabs() &&
|
||||
_currentWindowSettings().ConfirmCloseAllTabs() &&
|
||||
!_displayingCloseDialog)
|
||||
{
|
||||
if (_newTabButton && _newTabButton.Flyout())
|
||||
@@ -2837,7 +2849,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - the title of the focused control if there is one, else "Terminal"
|
||||
hstring TerminalPage::Title()
|
||||
{
|
||||
if (_settings.GlobalSettings().ShowTitleInTitlebar())
|
||||
if (_currentWindowSettings().ShowTitleInTitlebar())
|
||||
{
|
||||
if (const auto tab{ _GetFocusedTab() })
|
||||
{
|
||||
@@ -2926,7 +2938,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float TerminalPage::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
{
|
||||
if (_settings && _settings.GlobalSettings().SnapToGridOnResize())
|
||||
if (_settings && _currentWindowSettings().SnapToGridOnResize())
|
||||
{
|
||||
if (const auto tabImpl{ _GetFocusedTabImpl() })
|
||||
{
|
||||
@@ -2954,7 +2966,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// the WinRT one on average, depending on CPU load. Don't use the WinRT clipboard API if you can.
|
||||
const auto weakThis = get_weak();
|
||||
const auto dispatcher = Dispatcher();
|
||||
const auto globalSettings = _settings.GlobalSettings();
|
||||
const auto windowSettings = _currentWindowSettings();
|
||||
const auto bracketedPaste = eventArgs.BracketedPasteEnabled();
|
||||
const auto sourceId = sender.try_as<ControlInteractivity>().Id();
|
||||
|
||||
@@ -2967,7 +2979,7 @@ namespace winrt::TerminalApp::implementation
|
||||
text = clipboard::read();
|
||||
}
|
||||
|
||||
if (!bracketedPaste && globalSettings.TrimPaste())
|
||||
if (!bracketedPaste && windowSettings.TrimPaste())
|
||||
{
|
||||
text = winrt::hstring{ Utils::TrimPaste(text) };
|
||||
}
|
||||
@@ -2982,7 +2994,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
bool warnMultiLine = false;
|
||||
switch (globalSettings.WarnAboutMultiLinePaste())
|
||||
switch (windowSettings.WarnAboutMultiLinePaste())
|
||||
{
|
||||
case WarnAboutMultiLinePaste::Automatic:
|
||||
// NOTE that this is unsafe, because a shell that doesn't support bracketed paste
|
||||
@@ -3005,7 +3017,7 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
|
||||
constexpr std::size_t minimumSizeForWarning = 1024 * 5; // 5 KiB
|
||||
const auto warnLargeText = text.size() > minimumSizeForWarning && globalSettings.WarnAboutLargePaste();
|
||||
const auto warnLargeText = text.size() > minimumSizeForWarning && windowSettings.WarnAboutLargePaste();
|
||||
|
||||
if (warnMultiLine || warnLargeText)
|
||||
{
|
||||
@@ -3399,13 +3411,13 @@ namespace winrt::TerminalApp::implementation
|
||||
void TerminalPage::_WindowSizeChanged(const IInspectable sender, const Microsoft::Terminal::Control::WindowSizeChangedEventArgs args)
|
||||
{
|
||||
// Raise if:
|
||||
// - Not in quake mode
|
||||
// - Not in docked mode
|
||||
// - Not in fullscreen
|
||||
// - Only one tab exists
|
||||
// - Only one pane exists
|
||||
// else:
|
||||
// - Reset conpty to its original size back
|
||||
if (!WindowProperties().IsQuakeWindow() && !Fullscreen() &&
|
||||
if (!_currentWindowSettings().DockWindow() && !Fullscreen() &&
|
||||
NumberOfTabs() == 1 && _GetFocusedTabImpl()->GetLeafPaneCount() == 1)
|
||||
{
|
||||
WindowSizeChanged.raise(*this, args);
|
||||
@@ -3589,7 +3601,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// Don't need to worry about duplicating or anything - we'll
|
||||
// serialize the actual profile's GUID along with the content guid.
|
||||
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
const auto& profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
const auto control = _AttachControlToContent(newTerminalArgs.ContentId());
|
||||
auto paneContent{ winrt::make<TerminalPaneContent>(profile, _terminalSettingsCache, control) };
|
||||
return std::make_shared<Pane>(paneContent);
|
||||
@@ -3605,7 +3617,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
// TODO GH#5047 If we cache the NewTerminalArgs, we no longer need to do this.
|
||||
profile = GetClosestProfileForDuplicationOfProfile(profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithProfile(_settings, profile, _currentWindowSettings());
|
||||
const auto workingDirectory = tabImpl->GetActiveTerminalControl().WorkingDirectory();
|
||||
if (Utils::IsValidDirectory(workingDirectory.c_str()))
|
||||
{
|
||||
@@ -3615,8 +3627,8 @@ namespace winrt::TerminalApp::implementation
|
||||
}
|
||||
if (!profile)
|
||||
{
|
||||
profile = _settings.GetProfileForArgs(newTerminalArgs);
|
||||
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs);
|
||||
profile = _settings.GetProfileForArgs(newTerminalArgs, _currentWindowSettings());
|
||||
controlSettings = Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, newTerminalArgs, _currentWindowSettings());
|
||||
}
|
||||
|
||||
// Try to handle auto-elevation
|
||||
@@ -3813,7 +3825,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_SetBackgroundImage(const winrt::Microsoft::Terminal::Settings::Model::IAppearanceConfig& newAppearance)
|
||||
{
|
||||
if (!_settings.GlobalSettings().UseBackgroundImageForWindow())
|
||||
if (!_currentWindowSettings().UseBackgroundImageForWindow())
|
||||
{
|
||||
_tabContent.Background(nullptr);
|
||||
return;
|
||||
@@ -3884,7 +3896,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// updating terminal panes, so that we don't have to build a _new_
|
||||
// TerminalSettings for every profile we update - we can just look them
|
||||
// up the previous ones we built.
|
||||
_terminalSettingsCache->Reset(_settings);
|
||||
_terminalSettingsCache->Reset(_settings, _currentWindowSettings());
|
||||
|
||||
for (const auto& tab : _tabs)
|
||||
{
|
||||
@@ -3922,17 +3934,17 @@ namespace winrt::TerminalApp::implementation
|
||||
// Reload the current value of alwaysOnTop from the settings file. This
|
||||
// will let the user hot-reload this setting, but any runtime changes to
|
||||
// the alwaysOnTop setting will be lost.
|
||||
_isAlwaysOnTop = _settings.GlobalSettings().AlwaysOnTop();
|
||||
_isAlwaysOnTop = _currentWindowSettings().AlwaysOnTop();
|
||||
AlwaysOnTopChanged.raise(*this, nullptr);
|
||||
|
||||
_showTabsFullscreen = _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
_showTabsFullscreen = _currentWindowSettings().ShowTabsFullscreen();
|
||||
|
||||
// Settings AllowDependentAnimations will affect whether animations are
|
||||
// enabled application-wide, so we don't need to check it each time we
|
||||
// want to create an animation.
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
|
||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_currentWindowSettings().DisableAnimations());
|
||||
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||
_tabRow.ShowElevationShield(IsRunningElevated() && _currentWindowSettings().ShowAdminShield());
|
||||
|
||||
Media::SolidColorBrush transparent{ Windows::UI::Colors::Transparent() };
|
||||
_tabView.Background(transparent);
|
||||
@@ -3953,7 +3965,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// our TabView, to match the tab.showCloseButton property in the theme.
|
||||
//
|
||||
// Also update every tab's individual IsClosable to match the same property.
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
const auto visibility = (theme && theme.Tab()) ?
|
||||
theme.Tab().ShowCloseButton() :
|
||||
Settings::Model::TabCloseButtonVisibility::Always;
|
||||
@@ -4567,7 +4579,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - <none>
|
||||
void TerminalPage::_UpdateTeachingTipTheme(winrt::Windows::UI::Xaml::FrameworkElement element)
|
||||
{
|
||||
auto theme{ _settings.GlobalSettings().CurrentTheme() };
|
||||
auto theme{ _settings.GlobalSettings().CurrentTheme(_currentWindowSettings()) };
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
while (element)
|
||||
{
|
||||
@@ -4720,7 +4732,7 @@ namespace winrt::TerminalApp::implementation
|
||||
{
|
||||
if (profile == _settings.ProfileDefaults())
|
||||
{
|
||||
return _settings.FindProfile(_settings.GlobalSettings().DefaultProfile());
|
||||
return _settings.FindProfile(_currentWindowSettings().DefaultProfile());
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
@@ -4941,7 +4953,7 @@ namespace winrt::TerminalApp::implementation
|
||||
return;
|
||||
}
|
||||
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
|
||||
{
|
||||
@@ -4985,7 +4997,7 @@ namespace winrt::TerminalApp::implementation
|
||||
theme.TabRow().UnfocusedBackground()) :
|
||||
ThemeColor{ nullptr } };
|
||||
|
||||
if (_settings.GlobalSettings().UseAcrylicInTabRow() && (_activated || _settings.GlobalSettings().EnableUnfocusedAcrylic()))
|
||||
if (_currentWindowSettings().UseAcrylicInTabRow() && (_activated || _currentWindowSettings().EnableUnfocusedAcrylic()))
|
||||
{
|
||||
if (tabRowBg)
|
||||
{
|
||||
@@ -5015,7 +5027,7 @@ namespace winrt::TerminalApp::implementation
|
||||
TitlebarBrush(backgroundSolidBrush);
|
||||
}
|
||||
|
||||
if (!_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
if (!_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
_tabRow.Background(TitlebarBrush());
|
||||
}
|
||||
@@ -5251,7 +5263,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// Feature_ShellCompletions::IsEnabled back in _RegisterTerminalEvents
|
||||
|
||||
// User must explicitly opt-in on Preview builds
|
||||
if (!_settings.GlobalSettings().EnableShellCompletionMenu())
|
||||
if (!_currentWindowSettings().EnableShellCompletionMenu())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
@@ -283,6 +283,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
|
||||
|
||||
std::shared_ptr<TerminalSettingsCache> _terminalSettingsCache{};
|
||||
|
||||
struct StashedDragData
|
||||
|
||||
@@ -41,8 +41,6 @@ namespace TerminalApp
|
||||
|
||||
String VirtualWorkingDirectory { get; set; };
|
||||
String VirtualEnvVars { get; set; };
|
||||
|
||||
Boolean IsQuakeWindow();
|
||||
};
|
||||
|
||||
runtimeclass LaunchPositionRequest
|
||||
|
||||
@@ -18,9 +18,9 @@ namespace winrt::TerminalApp::implementation
|
||||
result.UnfocusedSettings().try_as(_unfocusedSettings);
|
||||
}
|
||||
|
||||
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings)
|
||||
TerminalSettingsCache::TerminalSettingsCache(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
|
||||
{
|
||||
Reset(settings);
|
||||
Reset(settings, windowSettings);
|
||||
}
|
||||
|
||||
std::optional<TerminalSettingsPair> TerminalSettingsCache::TryLookup(const MTSM::Profile& profile)
|
||||
@@ -35,7 +35,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto& pair{ found->second };
|
||||
if (!pair.second)
|
||||
{
|
||||
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first);
|
||||
pair.second = winrt::Microsoft::Terminal::Settings::TerminalSettings::CreateWithProfile(_settings, pair.first, _windowSettings);
|
||||
}
|
||||
return std::optional{ TerminalSettingsPair{ *pair.second } };
|
||||
}
|
||||
@@ -43,9 +43,10 @@ namespace winrt::TerminalApp::implementation
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings)
|
||||
void TerminalSettingsCache::Reset(const MTSM::CascadiaSettings& settings, const MTSM::WindowSettings& windowSettings)
|
||||
{
|
||||
_settings = settings;
|
||||
_windowSettings = windowSettings;
|
||||
|
||||
// Mapping by GUID isn't _excellent_ because the defaults profile doesn't have a stable GUID; however,
|
||||
// when we stabilize its guid this will become fully safe.
|
||||
|
||||
@@ -38,12 +38,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
struct TerminalSettingsCache
|
||||
{
|
||||
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
TerminalSettingsCache(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
|
||||
std::optional<TerminalSettingsPair> TryLookup(const Microsoft::Terminal::Settings::Model::Profile& profile);
|
||||
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
|
||||
void Reset(const Microsoft::Terminal::Settings::Model::CascadiaSettings& settings, const Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
|
||||
|
||||
private:
|
||||
Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _windowSettings{ nullptr };
|
||||
std::unordered_map<winrt::guid, std::pair<Microsoft::Terminal::Settings::Model::Profile, std::optional<winrt::Microsoft::Terminal::Settings::TerminalSettingsCreateResult>>> profileGuidSettingsMap;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// that the window size is _first_ set up as something sensible, so
|
||||
// leaving fullscreen returns to a reasonable size.
|
||||
const auto launchMode = this->GetLaunchMode();
|
||||
if (_WindowProperties->IsQuakeWindow() || WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FocusMode))
|
||||
{
|
||||
_root->SetFocusMode(true);
|
||||
}
|
||||
@@ -244,7 +244,7 @@ namespace winrt::TerminalApp::implementation
|
||||
_root->Maximized(true);
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode) && !_WindowProperties->IsQuakeWindow())
|
||||
if (WI_IsFlagSet(launchMode, LaunchMode::FullscreenMode))
|
||||
{
|
||||
_root->SetFullscreen(true);
|
||||
}
|
||||
@@ -267,22 +267,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTabsInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsInTitlebar();
|
||||
return _currentWindowSettings().ShowTabsInTitlebar();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialAlwaysOnTop()
|
||||
{
|
||||
return _settings.GlobalSettings().AlwaysOnTop();
|
||||
return _currentWindowSettings().AlwaysOnTop();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetInitialShowTabsFullscreen()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTabsFullscreen();
|
||||
return _currentWindowSettings().ShowTabsFullscreen();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetMinimizeToNotificationArea()
|
||||
{
|
||||
return _settings.GlobalSettings().MinimizeToNotificationArea();
|
||||
return _currentWindowSettings().MinimizeToNotificationArea();
|
||||
}
|
||||
|
||||
bool TerminalWindow::GetAlwaysShowNotificationIcon()
|
||||
@@ -292,12 +292,12 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::GetShowTitleInTitlebar()
|
||||
{
|
||||
return _settings.GlobalSettings().ShowTitleInTitlebar();
|
||||
return _currentWindowSettings().ShowTitleInTitlebar();
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Theme TerminalWindow::Theme()
|
||||
{
|
||||
return _settings.GlobalSettings().CurrentTheme();
|
||||
return _settings.GlobalSettings().CurrentTheme(_currentWindowSettings());
|
||||
}
|
||||
|
||||
// WinUI can't show 2 dialogs simultaneously. Yes, really. If you do, you get an exception.
|
||||
@@ -374,7 +374,7 @@ namespace winrt::TerminalApp::implementation
|
||||
auto themingLambda{ [weak](const Windows::Foundation::IInspectable& sender, const RoutedEventArgs&) {
|
||||
if (const auto strong = weak.get())
|
||||
{
|
||||
auto theme{ strong->_settings.GlobalSettings().CurrentTheme() };
|
||||
auto theme{ strong->_settings.GlobalSettings().CurrentTheme(strong->_currentWindowSettings()) };
|
||||
auto requestedTheme{ theme.RequestedTheme() };
|
||||
auto element{ sender.try_as<winrt::Windows::UI::Xaml::FrameworkElement>() };
|
||||
while (element)
|
||||
@@ -598,7 +598,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// --focusMode on the commandline here, and the mode in the settings.
|
||||
// Below, we'll also account for if focus mode was persisted into the
|
||||
// session for restoration.
|
||||
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_settings.GlobalSettings().LaunchMode()) == LaunchMode::FocusMode;
|
||||
bool focusMode = _appArgs && _appArgs->ParsedArgs().GetLaunchMode().value_or(_currentWindowSettings().LaunchMode()) == LaunchMode::FocusMode;
|
||||
|
||||
const auto scale = static_cast<float>(dpi) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
@@ -621,7 +621,7 @@ namespace winrt::TerminalApp::implementation
|
||||
if ((_appArgs && _appArgs->ParsedArgs().GetSize().has_value()) || (proposedSize.Width == 0 && proposedSize.Height == 0))
|
||||
{
|
||||
// Use the default profile to determine how big of a window we need.
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr) };
|
||||
const auto settings{ Settings::TerminalSettings::CreateWithNewTerminalArgs(_settings, nullptr, _currentWindowSettings()) };
|
||||
|
||||
const til::size emptySize{};
|
||||
const auto commandlineSize = _appArgs ? _appArgs->ParsedArgs().GetSize().value_or(emptySize) : til::size{};
|
||||
@@ -645,7 +645,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// GH#2061 - If the global setting "Always show tab bar" is
|
||||
// set or if "Show tabs in title bar" is set, then we'll need to add
|
||||
// the height of the tab bar here.
|
||||
if (_settings.GlobalSettings().ShowTabsInTitlebar() && !focusMode)
|
||||
if (_currentWindowSettings().ShowTabsInTitlebar() && !focusMode)
|
||||
{
|
||||
// In the past, we used to actually instantiate a TitlebarControl
|
||||
// and use Measure() to determine the DesiredSize of the control, to
|
||||
@@ -663,7 +663,7 @@ namespace winrt::TerminalApp::implementation
|
||||
static constexpr auto titlebarHeight = 40;
|
||||
proposedSize.Height += (titlebarHeight)*scale;
|
||||
}
|
||||
else if (_settings.GlobalSettings().AlwaysShowTabs() && !focusMode)
|
||||
else if (_currentWindowSettings().AlwaysShowTabs() && !focusMode)
|
||||
{
|
||||
// Same comment as above, but with a TabRowControl.
|
||||
//
|
||||
@@ -696,7 +696,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
// GH#4620/#5801 - If the user passed --maximized or --fullscreen on the
|
||||
// commandline, then use that to override the value from the settings.
|
||||
const auto valueFromSettings = _settings.GlobalSettings().LaunchMode();
|
||||
const auto valueFromSettings = _currentWindowSettings().LaunchMode();
|
||||
const auto valueFromCommandlineArgs = _appArgs ? _appArgs->ParsedArgs().GetLaunchMode() : std::nullopt;
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
{
|
||||
@@ -722,7 +722,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// - a point containing the requested initial position in pixels.
|
||||
TerminalApp::InitialPosition TerminalWindow::GetInitialPosition(int64_t defaultInitialX, int64_t defaultInitialY)
|
||||
{
|
||||
auto initialPosition{ _settings.GlobalSettings().InitialPosition() };
|
||||
auto initialPosition{ _currentWindowSettings().InitialPosition() };
|
||||
|
||||
if (const auto layout = LoadPersistedLayout())
|
||||
{
|
||||
@@ -770,10 +770,15 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
return !_contentBounds &&
|
||||
!hadPersistedPosition &&
|
||||
_settings.GlobalSettings().CenterOnLaunch() &&
|
||||
_currentWindowSettings().CenterOnLaunch() &&
|
||||
(_appArgs && !_appArgs->ParsedArgs().GetPosition().has_value());
|
||||
}
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Docking TerminalWindow::Docking()
|
||||
{
|
||||
return _currentWindowSettings().DockWindow();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - See Pane::CalcSnappedDimension
|
||||
float TerminalWindow::CalcSnappedDimension(const bool widthOrHeight, const float dimension) const
|
||||
@@ -1188,7 +1193,7 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
bool TerminalWindow::AutoHideWindow()
|
||||
{
|
||||
return _settings.GlobalSettings().AutoHideWindow();
|
||||
return _currentWindowSettings().AutoHideWindow();
|
||||
}
|
||||
|
||||
void TerminalWindow::UpdateSettingsHandler(const winrt::IInspectable& /*sender*/,
|
||||
@@ -1207,21 +1212,22 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
void TerminalWindow::WindowName(const winrt::hstring& name)
|
||||
{
|
||||
const auto oldIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
const auto oldName = _WindowProperties->WindowName();
|
||||
_WindowProperties->WindowName(name);
|
||||
if (!_root)
|
||||
if (!_root || oldName == name)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const auto newIsQuakeMode = _WindowProperties->IsQuakeWindow();
|
||||
if (newIsQuakeMode != oldIsQuakeMode)
|
||||
{
|
||||
// If we're entering Quake Mode from ~Focus Mode, then this will enter Focus Mode
|
||||
// If we're entering Quake Mode from Focus Mode, then this will do nothing
|
||||
// If we're leaving Quake Mode (we're already in Focus Mode), then this will do nothing
|
||||
_root->SetFocusMode(true);
|
||||
IsQuakeWindowChanged.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
// The window name determines which WindowSettings we use
|
||||
// (via _currentWindowSettings()). Since it changed, refresh
|
||||
// all downstream consumers of per-window settings:
|
||||
// - TerminalPage (settings cache, tab/pane settings)
|
||||
// - Theme (may differ per window)
|
||||
// - Docking & host-level properties (via IsQuakeWindowChanged -> AppHost)
|
||||
_root->SetSettings(_settings, true);
|
||||
_RefreshThemeRoutine();
|
||||
IsQuakeWindowChanged.raise(*this, nullptr);
|
||||
}
|
||||
void TerminalWindow::WindowId(const uint64_t& id)
|
||||
{
|
||||
@@ -1332,13 +1338,13 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
if (!FocusMode())
|
||||
{
|
||||
if (!_settings.GlobalSettings().AlwaysShowTabs())
|
||||
if (!_currentWindowSettings().AlwaysShowTabs())
|
||||
{
|
||||
// Hide the title bar = off, Always show tabs = off.
|
||||
static constexpr auto titlebarHeight = 10;
|
||||
pixelSize.Height += (titlebarHeight)*scale;
|
||||
}
|
||||
else if (!_settings.GlobalSettings().ShowTabsInTitlebar())
|
||||
else if (!_currentWindowSettings().ShowTabsInTitlebar())
|
||||
{
|
||||
// Hide the title bar = off, Always show tabs = on.
|
||||
static constexpr auto titlebarAndTabBarHeight = 40;
|
||||
@@ -1419,9 +1425,9 @@ namespace winrt::TerminalApp::implementation
|
||||
return _WindowName.empty() ? til::hstring_format(FMT_COMPILE(L"<{}>"), RS_(L"UnnamedWindowName")) : _WindowName;
|
||||
}
|
||||
|
||||
bool WindowProperties::IsQuakeWindow() const noexcept
|
||||
WindowSettings TerminalWindow::_currentWindowSettings() const
|
||||
{
|
||||
return _WindowName == L"_quake";
|
||||
return _settings.WindowSettings(_WindowProperties->WindowName());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -44,7 +44,6 @@ namespace winrt::TerminalApp::implementation
|
||||
void WindowId(const uint64_t& value);
|
||||
winrt::hstring WindowIdForDisplay() const noexcept;
|
||||
winrt::hstring WindowNameForDisplay() const noexcept;
|
||||
bool IsQuakeWindow() const noexcept;
|
||||
|
||||
til::property_changed_event PropertyChanged;
|
||||
|
||||
@@ -134,12 +133,12 @@ namespace winrt::TerminalApp::implementation
|
||||
void DismissDialog();
|
||||
|
||||
Microsoft::Terminal::Settings::Model::Theme Theme();
|
||||
Microsoft::Terminal::Settings::Model::Docking Docking();
|
||||
void UpdateSettingsHandler(const winrt::Windows::Foundation::IInspectable& sender, const winrt::TerminalApp::SettingsLoadEventArgs& arg);
|
||||
|
||||
void WindowName(const winrt::hstring& value);
|
||||
void WindowId(const uint64_t& value);
|
||||
|
||||
bool IsQuakeWindow() const noexcept { return _WindowProperties->IsQuakeWindow(); }
|
||||
TerminalApp::WindowProperties WindowProperties() { return *_WindowProperties; }
|
||||
|
||||
void AttachContent(winrt::hstring content, uint32_t tabIndex);
|
||||
@@ -187,6 +186,8 @@ namespace winrt::TerminalApp::implementation
|
||||
TerminalApp::ContentManager _manager{ nullptr };
|
||||
std::vector<Microsoft::Terminal::Settings::Model::ActionAndArgs> _initialContentArgs;
|
||||
|
||||
Microsoft::Terminal::Settings::Model::WindowSettings _currentWindowSettings() const;
|
||||
|
||||
void _ShowLoadErrorsDialog(const winrt::hstring& titleKey,
|
||||
const winrt::hstring& contentKey,
|
||||
HRESULT settingsLoadedResult,
|
||||
|
||||
@@ -72,6 +72,8 @@ namespace TerminalApp
|
||||
Boolean AlwaysOnTop { get; };
|
||||
Boolean AutoHideWindow { get; };
|
||||
Boolean ShowTabsFullscreen { get; };
|
||||
Microsoft.Terminal.Settings.Model.Theme Theme { get; };
|
||||
Microsoft.Terminal.Settings.Model.Docking Docking { get; };
|
||||
|
||||
void IdentifyWindow();
|
||||
void SetPersistedLayoutIdx(UInt32 idx);
|
||||
@@ -105,7 +107,6 @@ namespace TerminalApp
|
||||
WindowProperties WindowProperties { get; };
|
||||
void WindowName(String name);
|
||||
void WindowId(UInt64 id);
|
||||
Boolean IsQuakeWindow();
|
||||
|
||||
// See IDialogPresenter and TerminalPage's DialogPresenter for more
|
||||
// information.
|
||||
|
||||
@@ -50,21 +50,21 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
return { horizAlign, vertAlign };
|
||||
}
|
||||
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::_CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
auto settings{ winrt::make_self<TerminalSettings>() };
|
||||
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
settings->_ApplyProfileSettings(profile);
|
||||
settings->_ApplyGlobalSettings(globals);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme());
|
||||
settings->_ApplyWindowSettings(windowSettings);
|
||||
settings->_ApplyAppearanceSettings(profile.DefaultAppearance(), globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
winrt::com_ptr<TerminalSettings> TerminalSettings::CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
|
||||
settings->_UseBackgroundImageForWindow = false;
|
||||
return settings;
|
||||
}
|
||||
@@ -80,9 +80,9 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
// Return Value:
|
||||
// - A TerminalSettingsCreateResult, which contains a pair of TerminalSettings objects,
|
||||
// one for when the terminal is focused and the other for when the terminal is unfocused
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile)
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithProfile(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile);
|
||||
const auto settings = _CreateWithProfileCommon(appSettings, profile, windowSettings);
|
||||
|
||||
winrt::com_ptr<TerminalSettings> child{ nullptr };
|
||||
if (const auto& unfocusedAppearance{ profile.UnfocusedAppearance() })
|
||||
@@ -90,7 +90,7 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
const auto globals = appSettings.GlobalSettings();
|
||||
child = winrt::make_self<TerminalSettings>();
|
||||
child->_parent = settings->get_strong();
|
||||
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme());
|
||||
child->_ApplyAppearanceSettings(unfocusedAppearance, globals.ColorSchemes(), globals.CurrentTheme(windowSettings));
|
||||
}
|
||||
|
||||
return TerminalSettingsCreateResult{ settings.get(), child.get() };
|
||||
@@ -114,10 +114,11 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
// - A TerminalSettingsCreateResult object, which contains a pair of TerminalSettings
|
||||
// objects. One for when the terminal is focused and one for when the terminal is unfocused.
|
||||
TerminalSettingsCreateResult TerminalSettings::CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
|
||||
const Model::NewTerminalArgs& newTerminalArgs)
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& windowSettings)
|
||||
{
|
||||
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs);
|
||||
auto settingsPair{ CreateWithProfile(appSettings, profile) };
|
||||
const auto profile = appSettings.GetProfileForArgs(newTerminalArgs, windowSettings);
|
||||
auto settingsPair{ CreateWithProfile(appSettings, profile, windowSettings) };
|
||||
auto defaultSettings = settingsPair.DefaultSettings();
|
||||
|
||||
if (newTerminalArgs)
|
||||
@@ -357,15 +358,15 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Applies appropriate settings from the globals into the TerminalSettings object.
|
||||
// - Applies appropriate settings from the window settings into the TerminalSettings object.
|
||||
// Arguments:
|
||||
// - globalSettings: the global property values we're applying.
|
||||
// - windowSettings: the per-window property values we're applying.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void TerminalSettings::_ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept
|
||||
void TerminalSettings::_ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept
|
||||
{
|
||||
_InitialRows = globalSettings.InitialRows();
|
||||
_InitialCols = globalSettings.InitialCols();
|
||||
_InitialRows = windowSettings.InitialRows();
|
||||
_InitialCols = windowSettings.InitialCols();
|
||||
|
||||
_WordDelimiters = globalSettings.WordDelimiters();
|
||||
_CopyOnSelect = globalSettings.CopyOnSelect();
|
||||
|
||||
@@ -57,13 +57,15 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
{
|
||||
TerminalSettings() = default;
|
||||
|
||||
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
static winrt::com_ptr<TerminalSettings> CreateForPreview(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
|
||||
|
||||
static TerminalSettingsCreateResult CreateWithProfile(const Model::CascadiaSettings& appSettings,
|
||||
const Model::Profile& profile);
|
||||
const Model::Profile& profile,
|
||||
const Model::WindowSettings& windowSettings);
|
||||
|
||||
static TerminalSettingsCreateResult CreateWithNewTerminalArgs(const Model::CascadiaSettings& appSettings,
|
||||
const Model::NewTerminalArgs& newTerminalArgs);
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& windowSettings);
|
||||
|
||||
void ApplyColorScheme(const Model::ColorScheme& scheme);
|
||||
|
||||
@@ -102,10 +104,10 @@ namespace winrt::Microsoft::Terminal::Settings
|
||||
std::optional<std::array<Microsoft::Terminal::Core::Color, COLOR_TABLE_SIZE>> _ColorTable;
|
||||
std::span<Microsoft::Terminal::Core::Color> _getColorTableImpl();
|
||||
|
||||
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile);
|
||||
static winrt::com_ptr<TerminalSettings> _CreateWithProfileCommon(const Model::CascadiaSettings& appSettings, const Model::Profile& profile, const Model::WindowSettings& windowSettings);
|
||||
void _ApplyProfileSettings(const Model::Profile& profile);
|
||||
|
||||
void _ApplyGlobalSettings(const Model::GlobalAppSettings& globalSettings) noexcept;
|
||||
void _ApplyWindowSettings(const Model::WindowSettings& windowSettings) noexcept;
|
||||
void _ApplyAppearanceSettings(const Microsoft::Terminal::Settings::Model::IAppearanceConfig& appearance,
|
||||
const Windows::Foundation::Collections::IMapView<hstring, Microsoft::Terminal::Settings::Model::ColorScheme>& schemes,
|
||||
const winrt::Microsoft::Terminal::Settings::Model::Theme currentTheme);
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), AllowHeadless);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DebugFeaturesEnabled);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.GlobalSettings().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.GlobalSettings().AmbiguousWidth);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TextMeasurement, winrt::Microsoft::Terminal::Control::TextMeasurement, _settings.WindowSettingsDefaults().TextMeasurement);
|
||||
GETSET_BINDABLE_ENUM_SETTING(AmbiguousWidth, winrt::Microsoft::Terminal::Control::AmbiguousWidth, _settings.WindowSettingsDefaults().AmbiguousWidth);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings;
|
||||
|
||||
@@ -22,7 +22,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
constexpr std::wstring_view legacyDarkThemeName{ L"legacyDark" };
|
||||
constexpr std::wstring_view legacyLightThemeName{ L"legacyLight" };
|
||||
|
||||
GlobalAppearanceViewModel::GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings) :
|
||||
GlobalAppearanceViewModel::GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings) :
|
||||
_windowSettings{ windowSettings },
|
||||
_GlobalSettings{ globalSettings },
|
||||
_ThemeList{ single_threaded_observable_vector<Model::Theme>() }
|
||||
{
|
||||
@@ -46,7 +47,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable GlobalAppearanceViewModel::CurrentTheme()
|
||||
{
|
||||
return _GlobalSettings.CurrentTheme();
|
||||
return _GlobalSettings.CurrentTheme(_windowSettings);
|
||||
}
|
||||
|
||||
// Get the name out of the newly selected item, stash that as the Theme name
|
||||
@@ -56,7 +57,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
if (const auto& theme{ tag.try_as<Model::Theme>() })
|
||||
{
|
||||
_GlobalSettings.Theme(Model::ThemePair{ theme.Name() });
|
||||
_windowSettings.Theme(Model::ThemePair{ theme.Name() });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +104,12 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
bool GlobalAppearanceViewModel::InvertedDisableAnimations()
|
||||
{
|
||||
return !_GlobalSettings.DisableAnimations();
|
||||
return !_windowSettings.DisableAnimations();
|
||||
}
|
||||
|
||||
void GlobalAppearanceViewModel::InvertedDisableAnimations(bool value)
|
||||
{
|
||||
_GlobalSettings.DisableAnimations(!value);
|
||||
_windowSettings.DisableAnimations(!value);
|
||||
}
|
||||
|
||||
void GlobalAppearanceViewModel::ShowTitlebarToggled(const winrt::Windows::Foundation::IInspectable& /* sender */, const RoutedEventArgs& /* args */)
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
struct GlobalAppearanceViewModel : GlobalAppearanceViewModelT<GlobalAppearanceViewModel>, ViewModelHelper<GlobalAppearanceViewModel>
|
||||
{
|
||||
public:
|
||||
GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings);
|
||||
GlobalAppearanceViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<GlobalAppearanceViewModel>::PropertyChanged;
|
||||
|
||||
WINRT_PROPERTY(Windows::Foundation::Collections::IObservableVector<Model::Theme>, ThemeList, nullptr);
|
||||
GETSET_BINDABLE_ENUM_SETTING(NewTabPosition, Model::NewTabPosition, _GlobalSettings.NewTabPosition);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, _GlobalSettings.TabWidthMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(NewTabPosition, Model::NewTabPosition, _windowSettings.NewTabPosition);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabWidthMode, winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, _windowSettings.TabWidthMode);
|
||||
|
||||
public:
|
||||
winrt::Windows::Foundation::IInspectable CurrentTheme();
|
||||
@@ -31,19 +31,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
void ShowTitlebarToggled(const winrt::Windows::Foundation::IInspectable& sender, const winrt::Windows::UI::Xaml::RoutedEventArgs& args);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowTitleInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysOnTop);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AutoHideWindow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AlwaysShowTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTabsFullscreen);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTabsInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, UseAcrylicInTabRow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowTitleInTitlebar);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AlwaysOnTop);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, AutoHideWindow);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, AlwaysShowNotificationIcon);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, MinimizeToNotificationArea);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ShowAdminShield);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, EnableUnfocusedAcrylic);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, MinimizeToNotificationArea);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ShowAdminShield);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, EnableUnfocusedAcrylic);
|
||||
|
||||
private:
|
||||
Model::WindowSettings _windowSettings;
|
||||
Model::GlobalAppSettings _GlobalSettings;
|
||||
winrt::Windows::Foundation::IInspectable _currentTheme;
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass GlobalAppearanceViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
GlobalAppearanceViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings);
|
||||
GlobalAppearanceViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings,
|
||||
Microsoft.Terminal.Settings.Model.WindowSettings windowSettings);
|
||||
|
||||
IInspectable CurrentTheme;
|
||||
static String ThemeNameConverter(Microsoft.Terminal.Settings.Model.Theme theme);
|
||||
|
||||
@@ -12,8 +12,9 @@ using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
InteractionViewModel::InteractionViewModel(Model::GlobalAppSettings globalSettings) :
|
||||
_GlobalSettings{ globalSettings }
|
||||
InteractionViewModel::InteractionViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings) :
|
||||
_GlobalSettings{ globalSettings },
|
||||
_windowSettings{ windowSettings }
|
||||
{
|
||||
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");
|
||||
|
||||
@@ -12,32 +12,33 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
struct InteractionViewModel : InteractionViewModelT<InteractionViewModel>, ViewModelHelper<InteractionViewModel>
|
||||
{
|
||||
public:
|
||||
InteractionViewModel(Model::GlobalAppSettings globalSettings);
|
||||
InteractionViewModel(Model::GlobalAppSettings globalSettings, Model::WindowSettings windowSettings);
|
||||
|
||||
// DON'T YOU DARE ADD A `WINRT_CALLBACK(PropertyChanged` TO A CLASS DERIVED FROM ViewModelHelper. Do this instead:
|
||||
using ViewModelHelper<InteractionViewModel>::PropertyChanged;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabSwitcherMode, Model::TabSwitcherMode, _GlobalSettings.TabSwitcherMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, _GlobalSettings.CopyFormatting);
|
||||
GETSET_BINDABLE_ENUM_SETTING(TabSwitcherMode, Model::TabSwitcherMode, _windowSettings.TabSwitcherMode);
|
||||
GETSET_BINDABLE_ENUM_SETTING(CopyFormat, winrt::Microsoft::Terminal::Control::CopyFormat, _windowSettings.CopyFormatting);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, CopyOnSelect);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, TrimBlockSelection);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, TrimPaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, SnapToGridOnResize);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, FocusFollowMouse);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ScrollToZoom);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, ScrollToChangeOpacity);
|
||||
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(_windowSettings, CopyOnSelect);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, TrimBlockSelection);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, TrimPaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, SnapToGridOnResize);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, FocusFollowMouse);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ScrollToZoom);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ScrollToChangeOpacity);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, DetectURLs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, SearchWebDefaultQueryUrl);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WordDelimiters);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, ConfirmCloseAllTabs);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, InputServiceWarning);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, WarnAboutMultiLinePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WarnAboutLargePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_windowSettings, WarnAboutMultiLinePaste);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_GlobalSettings, EnableColorSelection);
|
||||
|
||||
private:
|
||||
Model::GlobalAppSettings _GlobalSettings;
|
||||
Model::WindowSettings _windowSettings;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace Microsoft.Terminal.Settings.Editor
|
||||
{
|
||||
runtimeclass InteractionViewModel : Windows.UI.Xaml.Data.INotifyPropertyChanged
|
||||
{
|
||||
InteractionViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings);
|
||||
InteractionViewModel(Microsoft.Terminal.Settings.Model.GlobalAppSettings globalSettings,
|
||||
Microsoft.Terminal.Settings.Model.WindowSettings windowSettings);
|
||||
|
||||
IInspectable CurrentTabSwitcherMode;
|
||||
Windows.Foundation.Collections.IObservableVector<Microsoft.Terminal.Settings.Editor.EnumEntry> TabSwitcherModeList { get; };
|
||||
|
||||
@@ -231,7 +231,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
double LaunchViewModel::InitialPosX()
|
||||
{
|
||||
const auto x = _Settings.GlobalSettings().InitialPosition().X;
|
||||
const auto x = _Settings.WindowSettingsDefaults().InitialPosition().X;
|
||||
// If there's no value here, return NAN - XAML will ignore it and
|
||||
// put the placeholder text in the box instead
|
||||
const auto xCoord = x.try_as<int32_t>();
|
||||
@@ -240,7 +240,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
double LaunchViewModel::InitialPosY()
|
||||
{
|
||||
const auto y = _Settings.GlobalSettings().InitialPosition().Y;
|
||||
const auto y = _Settings.WindowSettingsDefaults().InitialPosition().Y;
|
||||
// If there's no value here, return NAN - XAML will ignore it and
|
||||
// put the placeholder text in the box instead
|
||||
const auto yCoord = y.try_as<int32_t>();
|
||||
@@ -255,8 +255,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
xCoordRef = gsl::narrow_cast<int32_t>(xCoord);
|
||||
}
|
||||
const LaunchPosition newPos{ xCoordRef, _Settings.GlobalSettings().InitialPosition().Y };
|
||||
_Settings.GlobalSettings().InitialPosition(newPos);
|
||||
const LaunchPosition newPos{ xCoordRef, _Settings.WindowSettingsDefaults().InitialPosition().Y };
|
||||
_Settings.WindowSettingsDefaults().InitialPosition(newPos);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
|
||||
@@ -268,8 +268,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
yCoordRef = gsl::narrow_cast<int32_t>(yCoord);
|
||||
}
|
||||
const LaunchPosition newPos{ _Settings.GlobalSettings().InitialPosition().X, yCoordRef };
|
||||
_Settings.GlobalSettings().InitialPosition(newPos);
|
||||
const LaunchPosition newPos{ _Settings.WindowSettingsDefaults().InitialPosition().X, yCoordRef };
|
||||
_Settings.WindowSettingsDefaults().InitialPosition(newPos);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentLaunchMode()
|
||||
{
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_LaunchModeMap.Lookup(_Settings.GlobalSettings().LaunchMode()));
|
||||
return winrt::box_value<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>(_LaunchModeMap.Lookup(_Settings.WindowSettingsDefaults().LaunchMode()));
|
||||
}
|
||||
|
||||
void LaunchViewModel::CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry)
|
||||
@@ -299,7 +299,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
if (const auto ee = enumEntry.try_as<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry>())
|
||||
{
|
||||
const auto setting = winrt::unbox_value<LaunchMode>(ee.EnumValue());
|
||||
_Settings.GlobalSettings().LaunchMode(setting);
|
||||
_Settings.WindowSettingsDefaults().LaunchMode(setting);
|
||||
_NotifyChanges(L"LaunchParametersCurrentValue");
|
||||
}
|
||||
}
|
||||
@@ -311,14 +311,14 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
winrt::Windows::Foundation::IInspectable LaunchViewModel::CurrentDefaultProfile()
|
||||
{
|
||||
const auto defaultProfileGuid{ _Settings.GlobalSettings().DefaultProfile() };
|
||||
const auto defaultProfileGuid{ _Settings.WindowSettingsDefaults().DefaultProfile() };
|
||||
return winrt::box_value(_Settings.FindProfile(defaultProfileGuid));
|
||||
}
|
||||
|
||||
void LaunchViewModel::CurrentDefaultProfile(const IInspectable& value)
|
||||
{
|
||||
const auto profile{ winrt::unbox_value<Model::Profile>(value) };
|
||||
_Settings.GlobalSettings().DefaultProfile(profile.Guid());
|
||||
_Settings.WindowSettingsDefaults().DefaultProfile(profile.Guid());
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> LaunchViewModel::DefaultProfiles() const
|
||||
|
||||
@@ -46,13 +46,13 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
void CurrentLaunchMode(const winrt::Windows::Foundation::IInspectable& enumEntry);
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<winrt::Microsoft::Terminal::Settings::Editor::EnumEntry> LaunchModeList();
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(DefaultInputScope, winrt::Microsoft::Terminal::Control::DefaultInputScope, _Settings.GlobalSettings().DefaultInputScope);
|
||||
GETSET_BINDABLE_ENUM_SETTING(DefaultInputScope, winrt::Microsoft::Terminal::Control::DefaultInputScope, _Settings.WindowSettingsDefaults().DefaultInputScope);
|
||||
GETSET_BINDABLE_ENUM_SETTING(FirstWindowPreference, Model::FirstWindowPreference, _Settings.GlobalSettings().FirstWindowPreference);
|
||||
GETSET_BINDABLE_ENUM_SETTING(WindowingBehavior, Model::WindowingMode, _Settings.GlobalSettings().WindowingBehavior);
|
||||
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), CenterOnLaunch);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialRows);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.GlobalSettings(), InitialCols);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), CenterOnLaunch);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), InitialRows);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_Settings.WindowSettingsDefaults(), InitialCols);
|
||||
|
||||
bool StartOnUserLoginAvailable();
|
||||
safe_void_coroutine PrepareStartOnUserLoginSettings();
|
||||
|
||||
@@ -1127,7 +1127,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
}
|
||||
}
|
||||
|
||||
const auto theme = _settingsSource.GlobalSettings().CurrentTheme();
|
||||
const auto theme = _settingsSource.GlobalSettings().CurrentTheme(_settingsSource.WindowSettingsDefaults());
|
||||
const auto hasThemeForSettings{ theme.Settings() != nullptr };
|
||||
const auto appTheme = theme.RequestedTheme();
|
||||
const auto requestedTheme = (hasThemeForSettings) ? theme.Settings().RequestedTheme() : appTheme;
|
||||
@@ -1145,7 +1145,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
//
|
||||
// To mitigate this, don't set the transparent background in the case
|
||||
// that our theme is different than the app's.
|
||||
const bool actuallyUseMica = isMicaAvailable && (appTheme == requestedTheme);
|
||||
const bool actuallyUseMica = isMicaAvailable;
|
||||
|
||||
const auto bgKey = (theme.Window() != nullptr && theme.Window().UseMica()) && actuallyUseMica ?
|
||||
L"SettingsPageMicaBackground" :
|
||||
|
||||
@@ -325,7 +325,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
SelectedProfile(AvailableProfiles().GetAt(0));
|
||||
|
||||
_rootEntries = _ConvertToViewModelEntries(_Settings.GlobalSettings().NewTabMenu(), _Settings);
|
||||
_rootEntries = _ConvertToViewModelEntries(_Settings.WindowSettingsDefaults().NewTabMenu(), _Settings);
|
||||
_rootEntriesChangedRevoker = _rootEntries.VectorChanged(winrt::auto_revoke, [this](auto&&, const IVectorChangedEventArgs& args) {
|
||||
switch (args.CollectionChange())
|
||||
{
|
||||
@@ -337,25 +337,25 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
modelEntries.push_back(NewTabMenuEntryViewModel::GetModel(entry));
|
||||
}
|
||||
_Settings.GlobalSettings().NewTabMenu(single_threaded_vector<Model::NewTabMenuEntry>(std::move(modelEntries)));
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu(single_threaded_vector<Model::NewTabMenuEntry>(std::move(modelEntries)));
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemInserted:
|
||||
{
|
||||
const auto& insertedEntryVM = _rootEntries.GetAt(args.Index());
|
||||
const auto& insertedEntry = NewTabMenuEntryViewModel::GetModel(insertedEntryVM);
|
||||
_Settings.GlobalSettings().NewTabMenu().InsertAt(args.Index(), insertedEntry);
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().InsertAt(args.Index(), insertedEntry);
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemRemoved:
|
||||
{
|
||||
_Settings.GlobalSettings().NewTabMenu().RemoveAt(args.Index());
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().RemoveAt(args.Index());
|
||||
return;
|
||||
}
|
||||
case CollectionChange::ItemChanged:
|
||||
{
|
||||
const auto& modifiedEntry = _rootEntries.GetAt(args.Index());
|
||||
_Settings.GlobalSettings().NewTabMenu().SetAt(args.Index(), NewTabMenuEntryViewModel::GetModel(modifiedEntry));
|
||||
_Settings.WindowSettingsDefaults().NewTabMenu().SetAt(args.Index(), NewTabMenuEntryViewModel::GetModel(modifiedEntry));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
// This may look pricey, but it only resolves resources that have not been visited
|
||||
// and the preview update is debounced.
|
||||
_appSettings.ResolveMediaResources();
|
||||
return *Settings::TerminalSettings::CreateForPreview(_appSettings, _profile);
|
||||
return *Settings::TerminalSettings::CreateForPreview(_appSettings, _profile, _appSettings.WindowSettingsDefaults());
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -385,7 +385,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
|
||||
Windows::UI::Color ProfileViewModel::TabThemeColorPreview() const
|
||||
{
|
||||
const auto currentTheme = _appSettings.GlobalSettings().CurrentTheme();
|
||||
const auto currentTheme = _appSettings.GlobalSettings().CurrentTheme(_appSettings.WindowSettingsDefaults());
|
||||
if (const auto tabTheme = currentTheme.Tab())
|
||||
{
|
||||
// theme.tab.background: theme color must be evaluated
|
||||
|
||||
@@ -13,9 +13,9 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation
|
||||
{
|
||||
explicit RenderingViewModel(Model::CascadiaSettings settings) noexcept;
|
||||
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.GlobalSettings().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.GlobalSettings(), SoftwareRendering);
|
||||
GETSET_BINDABLE_ENUM_SETTING(GraphicsAPI, winrt::Microsoft::Terminal::Control::GraphicsAPI, _settings.WindowSettingsDefaults().GraphicsAPI);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.WindowSettingsDefaults(), DisablePartialInvalidation);
|
||||
PERMANENT_OBSERVABLE_PROJECTED_SETTING(_settings.WindowSettingsDefaults(), SoftwareRendering);
|
||||
|
||||
private:
|
||||
Model::CascadiaSettings _settings{ nullptr };
|
||||
|
||||
@@ -113,6 +113,7 @@ Model::CascadiaSettings CascadiaSettings::Copy() const
|
||||
settings->_globals = _globals->Copy();
|
||||
settings->_allProfiles = winrt::single_threaded_observable_vector(std::move(allProfiles));
|
||||
settings->_activeProfiles = winrt::single_threaded_observable_vector(std::move(activeProfiles));
|
||||
settings->_baseWindowSettings = _baseWindowSettings->Copy();
|
||||
|
||||
// extension packages don't need a deep clone
|
||||
// because they're fully immutable. We can just copy the reference over instead.
|
||||
@@ -220,6 +221,37 @@ Model::Profile CascadiaSettings::ProfileDefaults() const
|
||||
return *_baseLayerProfile;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettingsDefaults() const
|
||||
{
|
||||
return *_baseWindowSettings;
|
||||
}
|
||||
|
||||
Model::WindowSettings CascadiaSettings::WindowSettings(const winrt::hstring& windowName) const
|
||||
{
|
||||
if (const auto& forName = _windows.TryLookup(windowName))
|
||||
{
|
||||
return forName;
|
||||
}
|
||||
else if (windowName == L"_quake")
|
||||
{
|
||||
const auto& quakeSettings{ winrt::make_self<implementation::WindowSettings>() };
|
||||
quakeSettings->AddLeastImportantParent(_baseWindowSettings);
|
||||
_resolveDefaultProfileForWindow(*quakeSettings, _allProfiles.GetAt(0).Guid());
|
||||
quakeSettings->InitializeForQuakeMode();
|
||||
|
||||
return *quakeSettings;
|
||||
}
|
||||
else
|
||||
{
|
||||
return *_baseWindowSettings;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> CascadiaSettings::AllWindowSettings() const noexcept
|
||||
{
|
||||
return _windows;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a new profile based off the default profile settings.
|
||||
// Arguments:
|
||||
@@ -709,7 +741,7 @@ static bool _validateNTMEntries(const IVector<Model::NewTabMenuEntry>& entries)
|
||||
|
||||
void CascadiaSettings::_validateRegexes()
|
||||
{
|
||||
if (!_validateNTMEntries(_globals->NewTabMenu()))
|
||||
if (!_validateNTMEntries(_baseWindowSettings->NewTabMenu()))
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::InvalidRegex);
|
||||
}
|
||||
@@ -731,7 +763,9 @@ void CascadiaSettings::_validateRegexes()
|
||||
// and attempt to look the profile up by name instead.
|
||||
// Return Value:
|
||||
// - the GUID of the profile corresponding to this combination of index and NewTerminalArgs
|
||||
Model::Profile CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const
|
||||
Model::Profile CascadiaSettings::GetProfileForArgs(
|
||||
const Model::NewTerminalArgs& newTerminalArgs,
|
||||
const Model::WindowSettings& currentWindowSettings) const
|
||||
{
|
||||
if (newTerminalArgs)
|
||||
{
|
||||
@@ -775,7 +809,7 @@ Model::Profile CascadiaSettings::GetProfileForArgs(const Model::NewTerminalArgs&
|
||||
// Case 2 above could be the result of a "nt" or "sp" invocation that doesn't specify anything.
|
||||
// TODO GH#10952: Detect the profile based on the commandline (add matching support)
|
||||
return (!newTerminalArgs || newTerminalArgs.Commandline().empty()) ?
|
||||
FindProfile(GlobalSettings().DefaultProfile()) :
|
||||
FindProfile(currentWindowSettings.DefaultProfile()) :
|
||||
ProfileDefaults();
|
||||
}
|
||||
|
||||
@@ -1235,10 +1269,10 @@ void CascadiaSettings::_validateThemeExists()
|
||||
auto newTheme = winrt::make_self<Theme>();
|
||||
newTheme->Name(L"system");
|
||||
_globals->AddTheme(*newTheme);
|
||||
_globals->Theme(Model::ThemePair{ L"system" });
|
||||
_baseWindowSettings->Theme(Model::ThemePair{ L"system" });
|
||||
}
|
||||
|
||||
const auto& theme{ _globals->Theme() };
|
||||
const auto& theme{ _baseWindowSettings->Theme() };
|
||||
if (theme.DarkName() == theme.LightName())
|
||||
{
|
||||
// Only one theme. We'll treat it as such.
|
||||
@@ -1246,7 +1280,7 @@ void CascadiaSettings::_validateThemeExists()
|
||||
{
|
||||
_warnings.Append(SettingsLoadWarnings::UnknownTheme);
|
||||
// safely fall back to system as the theme.
|
||||
_globals->Theme(*winrt::make_self<ThemePair>(L"system"));
|
||||
_baseWindowSettings->Theme(*winrt::make_self<ThemePair>(L"system"));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -69,8 +69,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
winrt::com_ptr<implementation::GlobalAppSettings> globals;
|
||||
winrt::com_ptr<implementation::Profile> baseLayerProfile;
|
||||
winrt::com_ptr<implementation::WindowSettings> baseWindowSettings;
|
||||
std::vector<winrt::com_ptr<implementation::Profile>> profiles;
|
||||
std::unordered_map<winrt::guid, winrt::com_ptr<implementation::Profile>> profilesByGuid;
|
||||
std::unordered_map<winrt::hstring, winrt::com_ptr<implementation::WindowSettings>> windowsByName;
|
||||
std::unordered_map<winrt::hstring, winrt::com_ptr<implementation::ColorScheme>> colorSchemes;
|
||||
std::unordered_map<winrt::hstring, winrt::hstring> colorSchemeRemappings;
|
||||
bool fixupsAppliedDuringLoad{ false };
|
||||
@@ -111,6 +113,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
const Json::Value& profileDefaults;
|
||||
const Json::Value& profilesList;
|
||||
const Json::Value& themes;
|
||||
const Json::Value& windowDefaults;
|
||||
const Json::Value& windowsList;
|
||||
};
|
||||
struct ParseFragmentMetadata
|
||||
{
|
||||
@@ -163,6 +167,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
winrt::hstring Hash() const noexcept;
|
||||
Model::CascadiaSettings Copy() const;
|
||||
Model::GlobalAppSettings GlobalSettings() const;
|
||||
|
||||
Model::WindowSettings WindowSettingsDefaults() const;
|
||||
Model::WindowSettings WindowSettings(const winrt::hstring& windowName) const;
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> AllWindowSettings() const noexcept;
|
||||
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> AllProfiles() const noexcept;
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> ActiveProfiles() const noexcept;
|
||||
Model::ActionMap ActionMap() const noexcept;
|
||||
@@ -175,7 +184,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
Model::Profile CreateNewProfile();
|
||||
Model::Profile FindProfile(const winrt::guid& guid) const noexcept;
|
||||
void UpdateColorSchemeReferences(const winrt::hstring& oldName, const winrt::hstring& newName);
|
||||
Model::Profile GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs) const;
|
||||
Model::Profile GetProfileForArgs(const Model::NewTerminalArgs& newTerminalArgs, const Model::WindowSettings& currentWindowSettings) const;
|
||||
Model::Profile GetProfileByName(const winrt::hstring& name) const;
|
||||
Model::Profile GetProfileByIndex(uint32_t index) const;
|
||||
Model::Profile DuplicateProfile(const Model::Profile& source);
|
||||
@@ -209,7 +218,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
void _writeSettingsToDisk(std::string_view contents);
|
||||
|
||||
void _resolveDefaultProfile() const;
|
||||
bool _resolveDefaultProfileForWindow(const Model::WindowSettings& window,
|
||||
const winrt::guid firstProfileGuid) const;
|
||||
void _resolveNewTabMenuProfiles() const;
|
||||
void _resolveNewTabMenuProfilesForWindow(const Model::WindowSettings& window) const;
|
||||
void _resolveNewTabMenuProfilesSet(const winrt::Windows::Foundation::Collections::IVector<Model::NewTabMenuEntry> entries, winrt::Windows::Foundation::Collections::IMap<int, Model::Profile>& remainingProfiles, Model::RemainingProfilesEntry& remainingProfilesEntry) const;
|
||||
|
||||
void _validateSettings();
|
||||
@@ -228,6 +240,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// user settings
|
||||
winrt::hstring _hash;
|
||||
winrt::com_ptr<implementation::GlobalAppSettings> _globals = winrt::make_self<implementation::GlobalAppSettings>();
|
||||
|
||||
winrt::com_ptr<implementation::WindowSettings> _baseWindowSettings = winrt::make_self<implementation::WindowSettings>();
|
||||
Windows::Foundation::Collections::IMap<winrt::hstring, Model::WindowSettings> _windows{ winrt::single_threaded_map<winrt::hstring, Model::WindowSettings>() };
|
||||
|
||||
winrt::com_ptr<implementation::Profile> _baseLayerProfile = winrt::make_self<implementation::Profile>();
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _allProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
|
||||
winrt::Windows::Foundation::Collections::IObservableVector<Model::Profile> _activeProfiles = winrt::single_threaded_observable_vector<Model::Profile>();
|
||||
|
||||
@@ -36,7 +36,9 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
String Hash { get; };
|
||||
|
||||
GlobalAppSettings GlobalSettings { get; };
|
||||
GlobalAppSettings GlobalSettings();
|
||||
WindowSettings WindowSettings(String windowName);
|
||||
WindowSettings WindowSettingsDefaults();
|
||||
|
||||
Profile ProfileDefaults { get; };
|
||||
|
||||
@@ -56,7 +58,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Profile FindProfile(Guid profileGuid);
|
||||
void UpdateColorSchemeReferences(String oldName, String newName);
|
||||
|
||||
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs);
|
||||
Profile GetProfileForArgs(NewTerminalArgs newTerminalArgs, WindowSettings currentWindowSettings);
|
||||
|
||||
static Boolean IsDefaultTerminalAvailable { get; };
|
||||
static Boolean IsDefaultTerminalSet { get; };
|
||||
|
||||
@@ -39,6 +39,7 @@ static constexpr std::string_view DefaultSettingsKey{ "defaults" };
|
||||
static constexpr std::string_view ProfilesListKey{ "list" };
|
||||
static constexpr std::string_view SchemesKey{ "schemes" };
|
||||
static constexpr std::string_view ThemesKey{ "themes" };
|
||||
static constexpr std::string_view WindowsListKey{ "windows" };
|
||||
|
||||
constexpr std::wstring_view systemThemeName{ L"system" };
|
||||
constexpr std::wstring_view darkThemeName{ L"dark" };
|
||||
@@ -103,9 +104,11 @@ void ParsedSettings::clear()
|
||||
{
|
||||
globals = {};
|
||||
baseLayerProfile = {};
|
||||
baseWindowSettings = {};
|
||||
profiles.clear();
|
||||
profilesByGuid.clear();
|
||||
colorSchemes.clear();
|
||||
windowsByName.clear();
|
||||
fixupsAppliedDuringLoad = false;
|
||||
themesChangeLog.clear();
|
||||
}
|
||||
@@ -291,7 +294,7 @@ void SettingsLoader::ApplyRuntimeInitialSettings()
|
||||
}
|
||||
}
|
||||
|
||||
userSettings.globals->DefaultProfile(guid);
|
||||
userSettings.baseWindowSettings->DefaultProfile(guid);
|
||||
}
|
||||
|
||||
// 2.
|
||||
@@ -470,6 +473,7 @@ void SettingsLoader::FinalizeLayering()
|
||||
|
||||
// Layer default globals -> user globals
|
||||
userSettings.globals->AddLeastImportantParent(inboxSettings.globals);
|
||||
userSettings.baseWindowSettings->AddLeastImportantParent(inboxSettings.baseWindowSettings);
|
||||
|
||||
// Actions are currently global, so if we want to conditionally light up a bunch of
|
||||
// actions, this is the time to do it.
|
||||
@@ -500,6 +504,13 @@ void SettingsLoader::FinalizeLayering()
|
||||
profile->Hidden(profile->Hidden());
|
||||
}
|
||||
}
|
||||
|
||||
// Layer user window settings defaults -> user named windows
|
||||
for (const auto& [_, window] : userSettings.windowsByName)
|
||||
{
|
||||
window->AddMostImportantParent(userSettings.baseWindowSettings);
|
||||
window->_FinalizeInheritance();
|
||||
}
|
||||
}
|
||||
|
||||
// Let's say a user doesn't know that they need to write `"hidden": true` in
|
||||
@@ -559,7 +570,7 @@ bool SettingsLoader::AddDynamicProfileFolders()
|
||||
folderEntry->RawEntries(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ *matchProfilesEntry }));
|
||||
|
||||
// NewTabMenu is guaranteed to exist by FixupUserSettings, which runs before this fixup.
|
||||
userSettings.globals->NewTabMenu().Append(folderEntry.as<Model::NewTabMenuEntry>());
|
||||
userSettings.baseWindowSettings->NewTabMenu().Append(folderEntry.as<Model::NewTabMenuEntry>());
|
||||
state->SSHFolderGenerated(true);
|
||||
return true;
|
||||
}
|
||||
@@ -693,9 +704,9 @@ bool SettingsLoader::FixupUserSettings()
|
||||
// Ensure that the user always has a newTabMenu. We used to do this last, after
|
||||
// resolving all of the new tab menu entries, but there was no conceivable reason
|
||||
// that it should happen so late.
|
||||
if (!userSettings.globals->HasNewTabMenu())
|
||||
if (!userSettings.baseWindowSettings->HasNewTabMenu())
|
||||
{
|
||||
userSettings.globals->NewTabMenu(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} }));
|
||||
userSettings.baseWindowSettings->NewTabMenu(winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} }));
|
||||
// This one does not need to be written back to the settings file immediately, it can wait until we write one for another reason.
|
||||
}
|
||||
|
||||
@@ -818,6 +829,18 @@ void SettingsLoader::_parse(const OriginTag origin, const winrt::hstring& source
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
settings.baseWindowSettings = WindowSettings::FromJson(json.root);
|
||||
|
||||
for (const auto& windowJson : json.windowsList)
|
||||
{
|
||||
if (auto window = WindowSettings::FromJson(windowJson))
|
||||
{
|
||||
settings.windowsByName.insert({ window->Name(), window });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
for (const auto& themeJson : json.themes)
|
||||
{
|
||||
@@ -1014,10 +1037,15 @@ SettingsLoader::JsonSettings SettingsLoader::_parseJson(const std::string_view&
|
||||
auto root = content.empty() ? Json::Value{ Json::ValueType::objectValue } : _parseJSON(content);
|
||||
const auto& colorSchemes = _getJSONValue(root, SchemesKey);
|
||||
const auto& themes = _getJSONValue(root, ThemesKey);
|
||||
|
||||
const auto& profilesObject = _getJSONValue(root, ProfilesKey);
|
||||
const auto& profileDefaults = _getJSONValue(profilesObject, DefaultSettingsKey);
|
||||
const auto& profilesList = profilesObject.isArray() ? profilesObject : _getJSONValue(profilesObject, ProfilesListKey);
|
||||
return JsonSettings{ std::move(root), colorSchemes, profileDefaults, profilesList, themes };
|
||||
|
||||
const auto& windowDefaults = content.empty() ? Json::Value{ Json::ValueType::objectValue } : _parseJSON(content);
|
||||
const auto& windowsList = _getJSONValue(root, WindowsListKey);
|
||||
|
||||
return JsonSettings{ std::move(root), colorSchemes, profileDefaults, profilesList, themes, windowDefaults, windowsList };
|
||||
}
|
||||
|
||||
// Just a common helper function between _parse and _parseFragment.
|
||||
@@ -1316,8 +1344,8 @@ void CascadiaSettings::_researchOnLoad()
|
||||
{
|
||||
// ----------------------------- RE: Themes ----------------------------
|
||||
const auto numThemes = GlobalSettings().Themes().Size();
|
||||
const auto themeInUse = GlobalSettings().CurrentTheme().Name();
|
||||
const auto changedTheme = GlobalSettings().HasTheme();
|
||||
const auto themeInUse = GlobalSettings().CurrentTheme(*_baseWindowSettings).Name();
|
||||
const auto changedTheme = _baseWindowSettings->HasTheme();
|
||||
|
||||
// system: 0
|
||||
// light: 1
|
||||
@@ -1478,6 +1506,12 @@ CascadiaSettings::CascadiaSettings(SettingsLoader&& loader) :
|
||||
_warnings = winrt::single_threaded_vector(std::move(warnings));
|
||||
_themesChangeLog = std::move(loader.userSettings.themesChangeLog);
|
||||
|
||||
_baseWindowSettings = loader.userSettings.baseWindowSettings;
|
||||
for (const auto& [name, window] : loader.userSettings.windowsByName)
|
||||
{
|
||||
_windows.Insert(name, *window);
|
||||
}
|
||||
|
||||
_resolveDefaultProfile();
|
||||
_resolveNewTabMenuProfiles();
|
||||
_validateSettings();
|
||||
@@ -1643,6 +1677,15 @@ Json::Value CascadiaSettings::ToJson() const
|
||||
{
|
||||
// top-level json object
|
||||
auto json{ _globals->ToJson() };
|
||||
|
||||
// Merge the base window settings into the root JSON.
|
||||
// (Window-level settings are written to the top level, just like globals.)
|
||||
const auto windowJson = _baseWindowSettings->ToJson();
|
||||
for (const auto& key : windowJson.getMemberNames())
|
||||
{
|
||||
json[key] = windowJson[key];
|
||||
}
|
||||
|
||||
json["$help"] = "https://aka.ms/terminal-documentation";
|
||||
json["$schema"] =
|
||||
#if defined(WT_BRANDING_RELEASE)
|
||||
@@ -1697,27 +1740,63 @@ Json::Value CascadiaSettings::ToJson() const
|
||||
}
|
||||
json[JsonKey(ThemesKey)] = themes;
|
||||
|
||||
// Serialize named windows (if any)
|
||||
if (_windows.Size() > 0)
|
||||
{
|
||||
Json::Value windowsList{ Json::ValueType::arrayValue };
|
||||
for (const auto& [name, window] : _windows)
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
auto windowJson = windowImpl->ToJson();
|
||||
windowJson["name"] = til::u16u8(name);
|
||||
windowsList.append(std::move(windowJson));
|
||||
}
|
||||
json[JsonKey(WindowsListKey)] = windowsList;
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the "defaultProfile", which can be a profile name, to a GUID
|
||||
// and stores it back to the globals.
|
||||
// and stores it back to the window settings.
|
||||
void CascadiaSettings::_resolveDefaultProfile() const
|
||||
{
|
||||
if (const auto unparsedDefaultProfile = _globals->UnparsedDefaultProfile(); !unparsedDefaultProfile.empty())
|
||||
const auto firstProfileGuid = _allProfiles.GetAt(0).Guid();
|
||||
|
||||
// Resolve for the base window settings first.
|
||||
_resolveDefaultProfileForWindow(*_baseWindowSettings, firstProfileGuid);
|
||||
|
||||
// Then resolve for each named window.
|
||||
for (const auto& [_, window] : _windows)
|
||||
{
|
||||
_resolveDefaultProfileForWindow(window, firstProfileGuid);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the "defaultProfile" for a single WindowSettings instance.
|
||||
// Returns:
|
||||
// - true if a warning was produced (missing default profile)
|
||||
bool CascadiaSettings::_resolveDefaultProfileForWindow(const Model::WindowSettings& window,
|
||||
const winrt::guid firstProfileGuid) const
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
if (const auto unparsedDefaultProfile = windowImpl->UnparsedDefaultProfile(); !unparsedDefaultProfile.empty())
|
||||
{
|
||||
if (const auto profile = GetProfileByName(unparsedDefaultProfile))
|
||||
{
|
||||
_globals->DefaultProfile(profile.Guid());
|
||||
return;
|
||||
windowImpl->DefaultProfile(profile.Guid());
|
||||
return false;
|
||||
}
|
||||
|
||||
_warnings.Append(SettingsLoadWarnings::MissingDefaultProfile);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use the first profile as the new default.
|
||||
GlobalSettings().DefaultProfile(_allProfiles.GetAt(0).Guid());
|
||||
windowImpl->DefaultProfile(firstProfileGuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -1729,6 +1808,22 @@ void CascadiaSettings::_resolveDefaultProfile() const
|
||||
// multiple of these entries are found.
|
||||
void CascadiaSettings::_resolveNewTabMenuProfiles() const
|
||||
{
|
||||
// Resolve for the base window settings first.
|
||||
_resolveNewTabMenuProfilesForWindow(*_baseWindowSettings);
|
||||
|
||||
// Then resolve for each named window.
|
||||
for (const auto& [_, window] : _windows)
|
||||
{
|
||||
_resolveNewTabMenuProfilesForWindow(window);
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Resolves the new tab menu profile entries for a single WindowSettings instance.
|
||||
void CascadiaSettings::_resolveNewTabMenuProfilesForWindow(const Model::WindowSettings& window) const
|
||||
{
|
||||
const auto windowImpl = winrt::get_self<implementation::WindowSettings>(window);
|
||||
|
||||
Model::RemainingProfilesEntry remainingProfilesEntry = nullptr;
|
||||
|
||||
// The TerminalPage needs to know which profile has which profile ID. To prevent
|
||||
@@ -1741,16 +1836,11 @@ void CascadiaSettings::_resolveNewTabMenuProfiles() const
|
||||
remainingProfilesMap.emplace(profileIndex, _activeProfiles.GetAt(profileIndex));
|
||||
}
|
||||
|
||||
// We keep track of the "remaining profiles" - those that have not yet been resolved
|
||||
// in either a "profile" or "source" entry. They will possibly be assigned to a
|
||||
// "remainingProfiles" entry
|
||||
auto remainingProfiles = single_threaded_map(std::move(remainingProfilesMap));
|
||||
|
||||
// We call a recursive helper function to process the entries
|
||||
auto entries = _globals->NewTabMenu();
|
||||
auto entries = windowImpl->NewTabMenu();
|
||||
_resolveNewTabMenuProfilesSet(entries, remainingProfiles, remainingProfilesEntry);
|
||||
|
||||
// If a "remainingProfiles" entry has been found, assign to it the remaining profiles
|
||||
if (remainingProfilesEntry != nullptr)
|
||||
{
|
||||
remainingProfilesEntry.Profiles(remainingProfiles);
|
||||
|
||||
@@ -59,9 +59,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
{
|
||||
auto globals{ winrt::make_self<GlobalAppSettings>() };
|
||||
|
||||
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
||||
|
||||
globals->_defaultProfile = _defaultProfile;
|
||||
globals->_actionMap = _actionMap->Copy();
|
||||
globals->_keybindingsWarnings = _keybindingsWarnings;
|
||||
|
||||
@@ -86,14 +83,6 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||
globals->_themes.Insert(kv.Key(), *themeImpl->Copy());
|
||||
}
|
||||
}
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu = winrt::single_threaded_vector<Model::NewTabMenuEntry>();
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu->Append(get_self<NewTabMenuEntry>(entry)->Copy());
|
||||
}
|
||||
}
|
||||
if (_DisabledProfileSources)
|
||||
{
|
||||
globals->_DisabledProfileSources = winrt::single_threaded_vector<hstring>();
|
||||
@@ -117,17 +106,6 @@ winrt::Windows::Foundation::Collections::IMapView<winrt::hstring, winrt::Microso
|
||||
|
||||
#pragma region DefaultProfile
|
||||
|
||||
void GlobalAppSettings::DefaultProfile(const winrt::guid& defaultProfile) noexcept
|
||||
{
|
||||
_defaultProfile = defaultProfile;
|
||||
_UnparsedDefaultProfile = Utils::GuidToString(defaultProfile);
|
||||
}
|
||||
|
||||
winrt::guid GlobalAppSettings::DefaultProfile() const
|
||||
{
|
||||
return _defaultProfile;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::ActionMap GlobalAppSettings::ActionMap() const noexcept
|
||||
@@ -150,17 +128,7 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::FromJson(const Json::Value&
|
||||
|
||||
void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origin)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
// GH#8076 - when adding enum values to this key, we also changed it from
|
||||
// "useTabSwitcher" to "tabSwitcherMode". Continue supporting
|
||||
// "useTabSwitcher", but prefer "tabSwitcherMode"
|
||||
_fixupsAppliedDuringLoad = JsonUtils::GetValueForKey(json, LegacyUseTabSwitcherModeKey, _TabSwitcherMode) || _fixupsAppliedDuringLoad;
|
||||
|
||||
_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;
|
||||
|
||||
#define GLOBAL_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::GetValueForKey(json, jsonKey, _##name); \
|
||||
@@ -169,17 +137,6 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_LAYER_JSON)
|
||||
#undef GLOBAL_SETTINGS_LAYER_JSON
|
||||
|
||||
// GH#11975 We only want to allow sensible values and prevent crashes, so we are clamping those values
|
||||
// We only want to assign if the value did change through clamping,
|
||||
// otherwise we could end up setting defaults that get persisted
|
||||
if (this->HasInitialCols())
|
||||
{
|
||||
this->InitialCols(std::clamp(this->InitialCols(), 1, 999));
|
||||
}
|
||||
if (this->HasInitialRows())
|
||||
{
|
||||
this->InitialRows(std::clamp(this->InitialRows(), 1, 999));
|
||||
}
|
||||
LayerActionsFrom(json, origin, true);
|
||||
|
||||
// No need to update _fixupsAppliedDuringLoad here.
|
||||
@@ -203,20 +160,11 @@ void GlobalAppSettings::LayerJson(const Json::Value& json, const OriginTag origi
|
||||
_fixupsAppliedDuringLoad |= firstWindowPreferenceValue == LegacyPersistedWindowLayout.data();
|
||||
}
|
||||
|
||||
// Remove settings included in userDefaults
|
||||
static constexpr std::array<std::pair<std::string_view, std::string_view>, 2> userDefaultSettings{ { { "copyOnSelect", "false" },
|
||||
{ "copyFormatting", "false" } } };
|
||||
for (const auto& [setting, val] : userDefaultSettings)
|
||||
{
|
||||
if (const auto settingJson{ json.find(&*setting.cbegin(), (&*setting.cbegin()) + setting.size()) })
|
||||
{
|
||||
if (settingJson->asString() == val)
|
||||
{
|
||||
// false positive!
|
||||
_changeLog.erase(std::string{ setting });
|
||||
}
|
||||
}
|
||||
}
|
||||
// NOTE: "copyOnSelect" and "copyFormatting" used to be global settings.
|
||||
// They were moved to WindowSettings and are now handled by
|
||||
// WindowSettings::LayerJson. No cleanup is needed here because
|
||||
// MTSM_GLOBAL_SETTINGS no longer includes them, so they never enter
|
||||
// the changeLog in the first place.
|
||||
}
|
||||
|
||||
void GlobalAppSettings::LayerActionsFrom(const Json::Value& json, const OriginTag origin, const bool withKeybindings)
|
||||
@@ -332,8 +280,6 @@ Json::Value GlobalAppSettings::ToJson()
|
||||
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
#define GLOBAL_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_TO_JSON)
|
||||
@@ -350,19 +296,20 @@ bool GlobalAppSettings::FixupsAppliedDuringLoad()
|
||||
return _fixupsAppliedDuringLoad || _actionMap->FixupsAppliedDuringLoad();
|
||||
}
|
||||
|
||||
winrt::Microsoft::Terminal::Settings::Model::Theme GlobalAppSettings::CurrentTheme() noexcept
|
||||
winrt::Microsoft::Terminal::Settings::Model::Theme GlobalAppSettings::CurrentTheme(const Model::WindowSettings& window) noexcept
|
||||
{
|
||||
auto requestedTheme = Model::Theme::IsSystemInDarkTheme() ?
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Dark :
|
||||
winrt::Windows::UI::Xaml::ElementTheme::Light;
|
||||
|
||||
const auto& themePair{ window.Theme() };
|
||||
switch (requestedTheme)
|
||||
{
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Light:
|
||||
return _themes.TryLookup(Theme().LightName());
|
||||
return _themes.TryLookup(themePair.LightName());
|
||||
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Dark:
|
||||
return _themes.TryLookup(Theme().DarkName());
|
||||
return _themes.TryLookup(themePair.DarkName());
|
||||
|
||||
case winrt::Windows::UI::Xaml::ElementTheme::Default:
|
||||
default:
|
||||
@@ -394,16 +341,6 @@ bool GlobalAppSettings::ShouldUsePersistedLayout() const
|
||||
void GlobalAppSettings::ResolveMediaResources(const Model::MediaResourceResolver& resolver)
|
||||
{
|
||||
_actionMap->ResolveMediaResourcesWithBasePath(SourceBasePath, resolver);
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
if (const auto resolvable{ entry.try_as<IPathlessMediaResourceContainer>() })
|
||||
{
|
||||
resolvable->ResolveMediaResourcesWithBasePath(SourceBasePath, resolver);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& parent : _parents)
|
||||
{
|
||||
parent->ResolveMediaResources(resolver);
|
||||
@@ -412,115 +349,20 @@ void GlobalAppSettings::ResolveMediaResources(const Model::MediaResourceResolver
|
||||
|
||||
void GlobalAppSettings::_logSettingSet(const std::string_view& setting)
|
||||
{
|
||||
if (setting == "theme")
|
||||
{
|
||||
if (_Theme.has_value())
|
||||
{
|
||||
// ThemePair always has a Dark/Light value,
|
||||
// so we need to check if they were explicitly set
|
||||
if (_Theme->DarkName() == _Theme->LightName())
|
||||
{
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
else
|
||||
{
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, "dark"));
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, "light"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (setting == "newTabMenu")
|
||||
{
|
||||
if (_NewTabMenu.has_value())
|
||||
{
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
std::string entryType;
|
||||
switch (entry.Type())
|
||||
{
|
||||
case NewTabMenuEntryType::Profile:
|
||||
entryType = "profile";
|
||||
break;
|
||||
case NewTabMenuEntryType::Separator:
|
||||
entryType = "separator";
|
||||
break;
|
||||
case NewTabMenuEntryType::Folder:
|
||||
entryType = "folder";
|
||||
break;
|
||||
case NewTabMenuEntryType::RemainingProfiles:
|
||||
entryType = "remainingProfiles";
|
||||
break;
|
||||
case NewTabMenuEntryType::MatchProfiles:
|
||||
entryType = "matchProfiles";
|
||||
break;
|
||||
case NewTabMenuEntryType::Action:
|
||||
entryType = "action";
|
||||
break;
|
||||
case NewTabMenuEntryType::Invalid:
|
||||
// ignore invalid
|
||||
continue;
|
||||
}
|
||||
_changeLog.emplace(fmt::format(FMT_COMPILE("{}.{}"), setting, entryType));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
_changeLog.emplace(setting);
|
||||
}
|
||||
|
||||
void GlobalAppSettings::UpdateCommandID(const Model::Command& cmd, winrt::hstring newID)
|
||||
{
|
||||
const auto oldID = cmd.ID();
|
||||
_actionMap->UpdateCommandID(cmd, newID);
|
||||
// newID might have been empty when this function was called, if so actionMap would have generated a new ID, use that
|
||||
newID = cmd.ID();
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
// Recursive lambda function to look through all the new tab menu entries and update IDs accordingly
|
||||
std::function<void(const Model::NewTabMenuEntry&)> recursiveEntryIdUpdate;
|
||||
recursiveEntryIdUpdate = [&](const Model::NewTabMenuEntry& entry) {
|
||||
if (entry.Type() == NewTabMenuEntryType::Action)
|
||||
{
|
||||
if (const auto actionEntry{ entry.try_as<ActionEntry>() })
|
||||
{
|
||||
if (actionEntry.ActionId() == oldID)
|
||||
{
|
||||
actionEntry.ActionId(newID);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (entry.Type() == NewTabMenuEntryType::Folder)
|
||||
{
|
||||
if (const auto folderEntry{ entry.try_as<FolderEntry>() })
|
||||
{
|
||||
for (const auto& nestedEntry : folderEntry.RawEntries())
|
||||
{
|
||||
recursiveEntryIdUpdate(nestedEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
recursiveEntryIdUpdate(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalAppSettings::_logSettingIfSet(const std::string_view& setting, const bool isSet)
|
||||
{
|
||||
if (isSet)
|
||||
{
|
||||
// Exclude some false positives from userDefaults.json
|
||||
const bool settingCopyFormattingToDefault = til::equals_insensitive_ascii(setting, "copyFormatting") && _CopyFormatting.has_value() && _CopyFormatting.value() == static_cast<Control::CopyFormat>(0);
|
||||
const bool settingNTMToDefault = til::equals_insensitive_ascii(setting, "newTabMenu") && _NewTabMenu.has_value() && _NewTabMenu->Size() == 1 && _NewTabMenu->GetAt(0).Type() == NewTabMenuEntryType::RemainingProfiles;
|
||||
if (!settingCopyFormattingToDefault && !settingNTMToDefault)
|
||||
{
|
||||
_logSettingSet(setting);
|
||||
}
|
||||
_logSettingSet(setting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ Author(s):
|
||||
#include "Theme.h"
|
||||
#include "NewTabMenuEntry.h"
|
||||
#include "RemainingProfilesEntry.h"
|
||||
#include "WindowSettings.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelUnitTests
|
||||
@@ -58,14 +59,11 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
const std::vector<SettingsLoadWarnings>& KeybindingsWarnings() const;
|
||||
|
||||
// This DefaultProfile() setter is called by CascadiaSettings,
|
||||
// when it parses UnparsedDefaultProfile in _finalizeSettings().
|
||||
void DefaultProfile(const guid& defaultProfile) noexcept;
|
||||
guid DefaultProfile() const;
|
||||
|
||||
|
||||
Windows::Foundation::Collections::IMapView<hstring, Model::Theme> Themes() noexcept;
|
||||
void AddTheme(const Model::Theme& theme);
|
||||
Model::Theme CurrentTheme() noexcept;
|
||||
Model::Theme CurrentTheme(const Model::WindowSettings& window) noexcept;
|
||||
bool ShouldUsePersistedLayout() const;
|
||||
|
||||
void ExpandCommands(const Windows::Foundation::Collections::IVectorView<Model::Profile>& profiles,
|
||||
@@ -80,8 +78,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
|
||||
winrt::hstring SourceBasePath;
|
||||
|
||||
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
|
||||
|
||||
#define GLOBAL_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
|
||||
INHERITABLE_SETTING_WITH_LOGGING(Model::GlobalAppSettings, type, name, jsonKey, ##__VA_ARGS__)
|
||||
MTSM_GLOBAL_SETTINGS(GLOBAL_SETTINGS_INITIALIZE)
|
||||
@@ -94,7 +90,6 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static constexpr bool debugFeaturesDefault{ true };
|
||||
#endif
|
||||
|
||||
winrt::guid _defaultProfile{};
|
||||
bool _fixupsAppliedDuringLoad{ false };
|
||||
bool _legacyReloadEnvironmentVariables{ true };
|
||||
bool _legacyForceVTInput{ false };
|
||||
|
||||
@@ -50,63 +50,34 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
AfterCurrentTab,
|
||||
};
|
||||
|
||||
enum DockPosition
|
||||
{
|
||||
None,
|
||||
Top,
|
||||
Bottom,
|
||||
Left,
|
||||
Right
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass Docking
|
||||
{
|
||||
Docking();
|
||||
DockPosition Side { get; };
|
||||
Double Width { get; };
|
||||
Double Height { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass GlobalAppSettings {
|
||||
Guid DefaultProfile;
|
||||
|
||||
INHERITABLE_SETTING(String, UnparsedDefaultProfile);
|
||||
|
||||
INHERITABLE_SETTING(Int32, InitialRows);
|
||||
INHERITABLE_SETTING(Int32, InitialCols);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowTabs);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
|
||||
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
|
||||
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
INHERITABLE_SETTING(String, Language);
|
||||
INHERITABLE_SETTING(Microsoft.UI.Xaml.Controls.TabViewWidthMode, TabWidthMode);
|
||||
INHERITABLE_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsInTitlebar);
|
||||
INHERITABLE_SETTING(String, WordDelimiters);
|
||||
INHERITABLE_SETTING(Boolean, CopyOnSelect);
|
||||
INHERITABLE_SETTING(Boolean, InputServiceWarning);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.CopyFormat, CopyFormatting);
|
||||
INHERITABLE_SETTING(Boolean, WarnAboutLargePaste);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.WarnAboutMultiLinePaste, WarnAboutMultiLinePaste);
|
||||
INHERITABLE_SETTING(Boolean, TrimPaste);
|
||||
INHERITABLE_SETTING(LaunchPosition, InitialPosition);
|
||||
INHERITABLE_SETTING(Boolean, CenterOnLaunch);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.DefaultInputScope, DefaultInputScope);
|
||||
INHERITABLE_SETTING(FirstWindowPreference, FirstWindowPreference);
|
||||
INHERITABLE_SETTING(LaunchMode, LaunchMode);
|
||||
INHERITABLE_SETTING(Boolean, SnapToGridOnResize);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.GraphicsAPI, GraphicsAPI);
|
||||
INHERITABLE_SETTING(Boolean, DisablePartialInvalidation);
|
||||
INHERITABLE_SETTING(Boolean, SoftwareRendering);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.TextMeasurement, TextMeasurement);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.AmbiguousWidth, AmbiguousWidth);
|
||||
INHERITABLE_SETTING(Boolean, UseBackgroundImageForWindow);
|
||||
INHERITABLE_SETTING(Boolean, DebugFeaturesEnabled);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysOnTop);
|
||||
INHERITABLE_SETTING(Boolean, AutoHideWindow);
|
||||
INHERITABLE_SETTING(TabSwitcherMode, TabSwitcherMode);
|
||||
INHERITABLE_SETTING(Boolean, DisableAnimations);
|
||||
INHERITABLE_SETTING(String, StartupActions);
|
||||
INHERITABLE_SETTING(Boolean, FocusFollowMouse);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToZoom);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToChangeOpacity);
|
||||
INHERITABLE_SETTING(WindowingMode, WindowingBehavior);
|
||||
INHERITABLE_SETTING(Boolean, TrimBlockSelection);
|
||||
INHERITABLE_SETTING(Boolean, DetectURLs);
|
||||
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon);
|
||||
INHERITABLE_SETTING(IVector<String>, DisabledProfileSources);
|
||||
INHERITABLE_SETTING(Boolean, ShowAdminShield);
|
||||
INHERITABLE_SETTING(IVector<NewTabMenuEntry>, NewTabMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableColorSelection);
|
||||
INHERITABLE_SETTING(Boolean, EnableShellCompletionMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(Boolean, AllowHeadless);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(Boolean, EnableColorSelection);
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||
void AddColorScheme(ColorScheme scheme);
|
||||
@@ -117,9 +88,62 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
Windows.Foundation.Collections.IMapView<String, Theme> Themes();
|
||||
void AddTheme(Theme theme);
|
||||
INHERITABLE_SETTING(ThemePair, Theme);
|
||||
Theme CurrentTheme { get; };
|
||||
Theme CurrentTheme(WindowSettings window);
|
||||
|
||||
Boolean ShouldUsePersistedLayout();
|
||||
}
|
||||
|
||||
[default_interface] runtimeclass WindowSettings {
|
||||
|
||||
String Name { get; };
|
||||
|
||||
Guid DefaultProfile;
|
||||
INHERITABLE_SETTING(String, UnparsedDefaultProfile);
|
||||
|
||||
INHERITABLE_SETTING(Int32, InitialRows);
|
||||
INHERITABLE_SETTING(Int32, InitialCols);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysShowTabs);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsFullscreen);
|
||||
INHERITABLE_SETTING(NewTabPosition, NewTabPosition);
|
||||
INHERITABLE_SETTING(Boolean, ShowTitleInTitlebar);
|
||||
INHERITABLE_SETTING(Boolean, ConfirmCloseAllTabs);
|
||||
INHERITABLE_SETTING(Microsoft.UI.Xaml.Controls.TabViewWidthMode, TabWidthMode);
|
||||
INHERITABLE_SETTING(Boolean, UseAcrylicInTabRow);
|
||||
INHERITABLE_SETTING(Boolean, ShowTabsInTitlebar);
|
||||
INHERITABLE_SETTING(String, WordDelimiters);
|
||||
INHERITABLE_SETTING(Boolean, CopyOnSelect);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.CopyFormat, CopyFormatting);
|
||||
INHERITABLE_SETTING(Boolean, WarnAboutLargePaste);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.WarnAboutMultiLinePaste, WarnAboutMultiLinePaste);
|
||||
INHERITABLE_SETTING(Boolean, TrimPaste);
|
||||
INHERITABLE_SETTING(LaunchPosition, InitialPosition);
|
||||
INHERITABLE_SETTING(Boolean, CenterOnLaunch);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.DefaultInputScope, DefaultInputScope);
|
||||
INHERITABLE_SETTING(LaunchMode, LaunchMode);
|
||||
INHERITABLE_SETTING(Boolean, SnapToGridOnResize);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.GraphicsAPI, GraphicsAPI);
|
||||
INHERITABLE_SETTING(Boolean, DisablePartialInvalidation);
|
||||
INHERITABLE_SETTING(Boolean, SoftwareRendering);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.TextMeasurement, TextMeasurement);
|
||||
INHERITABLE_SETTING(Microsoft.Terminal.Control.AmbiguousWidth, AmbiguousWidth);
|
||||
INHERITABLE_SETTING(Boolean, UseBackgroundImageForWindow);
|
||||
INHERITABLE_SETTING(Boolean, AlwaysOnTop);
|
||||
INHERITABLE_SETTING(Boolean, AutoHideWindow);
|
||||
INHERITABLE_SETTING(TabSwitcherMode, TabSwitcherMode);
|
||||
INHERITABLE_SETTING(Boolean, DisableAnimations);
|
||||
INHERITABLE_SETTING(String, StartupActions);
|
||||
INHERITABLE_SETTING(Boolean, FocusFollowMouse);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToZoom);
|
||||
INHERITABLE_SETTING(Boolean, ScrollToChangeOpacity);
|
||||
INHERITABLE_SETTING(Boolean, TrimBlockSelection);
|
||||
INHERITABLE_SETTING(Boolean, DetectURLs);
|
||||
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
||||
INHERITABLE_SETTING(Boolean, ShowAdminShield);
|
||||
INHERITABLE_SETTING(IVector<NewTabMenuEntry>, NewTabMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableShellCompletionMenu);
|
||||
INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic);
|
||||
INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl);
|
||||
INHERITABLE_SETTING(ThemePair, Theme);
|
||||
INHERITABLE_SETTING(Docking, DockWindow);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ Author(s):
|
||||
#include <json/json.h>
|
||||
|
||||
#include "../types/inc/utils.hpp"
|
||||
#include <til/winrt.h>
|
||||
|
||||
namespace winrt
|
||||
{
|
||||
@@ -59,6 +60,35 @@ namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
std::string TypeDescription() const { return "<unknown>"; }
|
||||
};
|
||||
|
||||
// Specialization for til::property<T> so we can deserialize directly into properties
|
||||
template<typename T>
|
||||
struct ConversionTrait<til::property<T>>
|
||||
{
|
||||
til::property<T> FromJson(const Json::Value& json)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return til::property<T>{ trait.FromJson(json) };
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.CanConvert(json);
|
||||
}
|
||||
|
||||
Json::Value ToJson(const til::property<T>& val)
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.ToJson(val());
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
ConversionTrait<T> trait;
|
||||
return trait.TypeDescription();
|
||||
}
|
||||
};
|
||||
|
||||
namespace Detail
|
||||
{
|
||||
// Function Description:
|
||||
|
||||
@@ -18,7 +18,22 @@ Author(s):
|
||||
// Macro format (defaultArgs are optional):
|
||||
// (type, name, jsonKey, defaultArgs)
|
||||
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
// These are truly global settings - they apply to the entire application,
|
||||
// not to any specific window.
|
||||
#define MTSM_GLOBAL_SETTINGS(X) \
|
||||
X(hstring, Language, "language") \
|
||||
X(bool, InputServiceWarning, "warning.inputService", true) \
|
||||
X(Model::FirstWindowPreference, FirstWindowPreference, "firstWindowPreference", FirstWindowPreference::DefaultProfile) \
|
||||
X(bool, DebugFeaturesEnabled, "debugFeatures", debugFeaturesDefault) \
|
||||
X(Model::WindowingMode, WindowingBehavior, "windowingBehavior", Model::WindowingMode::UseNew) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(bool, AllowHeadless, "compatibility.allowHeadless", false) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false)
|
||||
|
||||
// These are per-window settings - different windows can have different values.
|
||||
// The "base" window settings act as the defaults for all windows.
|
||||
#define MTSM_WINDOW_SETTINGS(X) \
|
||||
X(int32_t, InitialRows, "initialRows", 30) \
|
||||
X(int32_t, InitialCols, "initialCols", 80) \
|
||||
X(hstring, WordDelimiters, "wordDelimiters", DEFAULT_WORD_DELIMITERS) \
|
||||
@@ -40,36 +55,28 @@ Author(s):
|
||||
X(bool, ShowTitleInTitlebar, "showTerminalTitleInTitlebar", true) \
|
||||
X(bool, ConfirmCloseAllTabs, "warning.confirmCloseAllTabs", true) \
|
||||
X(Model::ThemePair, Theme, "theme") \
|
||||
X(hstring, Language, "language") \
|
||||
X(Model::Docking, DockWindow, "dockWindow", nullptr) \
|
||||
X(winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode, TabWidthMode, "tabWidthMode", winrt::Microsoft::UI::Xaml::Controls::TabViewWidthMode::Equal) \
|
||||
X(bool, UseAcrylicInTabRow, "useAcrylicInTabRow", false) \
|
||||
X(bool, ShowTabsInTitlebar, "showTabsInTitlebar", true) \
|
||||
X(bool, InputServiceWarning, "warning.inputService", true) \
|
||||
X(winrt::Microsoft::Terminal::Control::CopyFormat, CopyFormatting, "copyFormatting", 0) \
|
||||
X(bool, WarnAboutLargePaste, "warning.largePaste", true) \
|
||||
X(winrt::Microsoft::Terminal::Control::WarnAboutMultiLinePaste, WarnAboutMultiLinePaste, "warning.multiLinePaste", winrt::Microsoft::Terminal::Control::WarnAboutMultiLinePaste::Automatic) \
|
||||
X(Model::LaunchPosition, InitialPosition, "initialPosition", nullptr, nullptr) \
|
||||
X(bool, CenterOnLaunch, "centerOnLaunch", false) \
|
||||
X(Model::FirstWindowPreference, FirstWindowPreference, "firstWindowPreference", FirstWindowPreference::DefaultProfile) \
|
||||
X(Model::LaunchMode, LaunchMode, "launchMode", LaunchMode::DefaultMode) \
|
||||
X(bool, SnapToGridOnResize, "snapToGridOnResize", true) \
|
||||
X(bool, DebugFeaturesEnabled, "debugFeatures", debugFeaturesDefault) \
|
||||
X(bool, AlwaysOnTop, "alwaysOnTop", false) \
|
||||
X(bool, AutoHideWindow, "autoHideWindow", false) \
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(Model::TabSwitcherMode, TabSwitcherMode, "tabSwitcherMode", Model::TabSwitcherMode::InOrder) \
|
||||
X(bool, DisableAnimations, "disableAnimations", false) \
|
||||
X(hstring, StartupActions, "startupActions", L"") \
|
||||
X(Model::WindowingMode, WindowingBehavior, "windowingBehavior", Model::WindowingMode::UseNew) \
|
||||
X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \
|
||||
X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, "disabledProfileSources", nullptr) \
|
||||
X(bool, ShowAdminShield, "showAdminShield", true) \
|
||||
X(bool, TrimPaste, "trimPaste", true) \
|
||||
X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \
|
||||
X(bool, EnableShellCompletionMenu, "experimental.enableShellCompletionMenu", false) \
|
||||
X(bool, EnableUnfocusedAcrylic, "compatibility.enableUnfocusedAcrylic", true) \
|
||||
X(winrt::Windows::Foundation::Collections::IVector<Model::NewTabMenuEntry>, NewTabMenu, "newTabMenu", winrt::single_threaded_vector<Model::NewTabMenuEntry>({ Model::RemainingProfilesEntry{} })) \
|
||||
X(bool, AllowHeadless, "compatibility.allowHeadless", false) \
|
||||
X(hstring, SearchWebDefaultQueryUrl, "searchWebDefaultQueryUrl", L"https://www.bing.com/search?q=%22%s%22") \
|
||||
X(bool, ShowTabsFullscreen, "showTabsFullscreen", false)
|
||||
|
||||
|
||||
@@ -82,6 +82,9 @@
|
||||
<ClInclude Include="GlobalAppSettings.h">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="WindowSettings.h">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClInclude>
|
||||
<ClInclude Include="IInheritable.h" />
|
||||
<ClInclude Include="MTSMSettings.h" />
|
||||
<ClInclude Include="IDynamicProfileGenerator.h" />
|
||||
@@ -161,6 +164,9 @@
|
||||
<ClCompile Include="GlobalAppSettings.cpp">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WindowSettings.cpp">
|
||||
<DependentUpon>GlobalAppSettings.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
<ClCompile Include="KeyChordSerialization.cpp">
|
||||
<DependentUpon>KeyChordSerialization.idl</DependentUpon>
|
||||
</ClCompile>
|
||||
|
||||
@@ -528,6 +528,17 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::WindowingMode)
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::DockPosition)
|
||||
{
|
||||
JSON_MAPPINGS(5) = {
|
||||
pair_type{ "none", ValueType::None },
|
||||
pair_type{ "top", ValueType::Top },
|
||||
pair_type{ "bottom", ValueType::Bottom },
|
||||
pair_type{ "left", ValueType::Left },
|
||||
pair_type{ "right", ValueType::Right },
|
||||
};
|
||||
};
|
||||
|
||||
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::DesktopBehavior)
|
||||
{
|
||||
JSON_MAPPINGS(3) = {
|
||||
|
||||
203
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
203
src/cascadia/TerminalSettingsModel/WindowSettings.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#include "pch.h"
|
||||
#include "WindowSettings.h"
|
||||
#include "../../types/inc/Utils.hpp"
|
||||
#include "JsonUtils.h"
|
||||
#include "KeyChordSerialization.h"
|
||||
|
||||
#include "WindowSettings.g.cpp"
|
||||
#include "Docking.g.cpp"
|
||||
|
||||
#include "ProfileEntry.h"
|
||||
#include "FolderEntry.h"
|
||||
#include "MatchProfilesEntry.h"
|
||||
|
||||
using namespace ::Microsoft::Console;
|
||||
using namespace ::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model::implementation;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
|
||||
using namespace winrt::Microsoft::UI::Xaml::Controls;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::Foundation::Collections;
|
||||
|
||||
static constexpr std::string_view NameKey{ "name" };
|
||||
static constexpr std::string_view ThemeKey{ "theme" };
|
||||
static constexpr std::string_view DefaultProfileKey{ "defaultProfile" };
|
||||
static constexpr std::string_view LegacyUseTabSwitcherModeKey{ "useTabSwitcher" };
|
||||
|
||||
// Method Description:
|
||||
// - Copies any extraneous data from the parent before completing a CreateChild call
|
||||
void WindowSettings::_FinalizeInheritance()
|
||||
{
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
parent;
|
||||
}
|
||||
}
|
||||
|
||||
winrt::com_ptr<WindowSettings> WindowSettings::Copy() const
|
||||
{
|
||||
auto globals{ winrt::make_self<WindowSettings>() };
|
||||
|
||||
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
||||
globals->_defaultProfile = _defaultProfile;
|
||||
|
||||
#define WINDOW_SETTINGS_COPY(type, name, jsonKey, ...) \
|
||||
globals->_##name = _##name;
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_COPY)
|
||||
#undef WINDOW_SETTINGS_COPY
|
||||
|
||||
if (_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu = winrt::single_threaded_vector<Model::NewTabMenuEntry>();
|
||||
for (const auto& entry : *_NewTabMenu)
|
||||
{
|
||||
globals->_NewTabMenu->Append(get_self<NewTabMenuEntry>(entry)->Copy());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& parent : _parents)
|
||||
{
|
||||
globals->AddLeastImportantParent(parent->Copy());
|
||||
}
|
||||
return globals;
|
||||
}
|
||||
|
||||
#pragma region DefaultProfile
|
||||
|
||||
void WindowSettings::DefaultProfile(const winrt::guid& defaultProfile) noexcept
|
||||
{
|
||||
_defaultProfile = defaultProfile;
|
||||
_UnparsedDefaultProfile = Utils::GuidToString(defaultProfile);
|
||||
}
|
||||
|
||||
winrt::guid WindowSettings::DefaultProfile() const
|
||||
{
|
||||
return _defaultProfile;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
// Method Description:
|
||||
// - Create a new instance of this class from a serialized JsonObject.
|
||||
winrt::com_ptr<WindowSettings> WindowSettings::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto result = winrt::make_self<WindowSettings>();
|
||||
result->LayerJson(json);
|
||||
return result;
|
||||
}
|
||||
|
||||
void WindowSettings::LayerJson(const Json::Value& json)
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, NameKey, Name);
|
||||
|
||||
// If the name is _quake, set up some default window settings:
|
||||
if (Name() == L"_quake")
|
||||
{
|
||||
InitializeForQuakeMode();
|
||||
}
|
||||
|
||||
JsonUtils::GetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
// GH#8076 - when adding enum values to this key, we also changed it from
|
||||
// "useTabSwitcher" to "tabSwitcherMode". Continue supporting
|
||||
// "useTabSwitcher", but prefer "tabSwitcherMode"
|
||||
JsonUtils::GetValueForKey(json, LegacyUseTabSwitcherModeKey, _TabSwitcherMode);
|
||||
|
||||
#define WINDOW_SETTINGS_LAYER_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::GetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_LAYER_JSON)
|
||||
#undef WINDOW_SETTINGS_LAYER_JSON
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Create a new serialized JsonObject from an instance of this class
|
||||
Json::Value WindowSettings::ToJson()
|
||||
{
|
||||
// These experimental options should be removed from the settings file if they're at their default value.
|
||||
// This prevents them from sticking around forever, even if the user was just experimenting with them.
|
||||
// One could consider this a workaround for the settings UI right now not having a "reset to default" button for these.
|
||||
if (_GraphicsAPI == winrt::Microsoft::Terminal::Control::GraphicsAPI::Automatic)
|
||||
{
|
||||
_GraphicsAPI.reset();
|
||||
}
|
||||
if (_TextMeasurement == winrt::Microsoft::Terminal::Control::TextMeasurement::Graphemes)
|
||||
{
|
||||
_TextMeasurement.reset();
|
||||
}
|
||||
if (_DefaultInputScope == winrt::Microsoft::Terminal::Control::DefaultInputScope::Default)
|
||||
{
|
||||
_DefaultInputScope.reset();
|
||||
}
|
||||
if (_DisablePartialInvalidation == false)
|
||||
{
|
||||
_DisablePartialInvalidation.reset();
|
||||
}
|
||||
if (_SoftwareRendering == false)
|
||||
{
|
||||
_SoftwareRendering.reset();
|
||||
}
|
||||
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, DefaultProfileKey, _UnparsedDefaultProfile);
|
||||
|
||||
#define WINDOW_SETTINGS_TO_JSON(type, name, jsonKey, ...) \
|
||||
JsonUtils::SetValueForKey(json, jsonKey, _##name);
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_TO_JSON)
|
||||
#undef WINDOW_SETTINGS_TO_JSON
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
// Set up anything that we need that's quake-mode specific.
|
||||
void WindowSettings::InitializeForQuakeMode()
|
||||
{
|
||||
LaunchMode(LaunchMode::FocusMode);
|
||||
|
||||
auto dockSettings{ winrt::make_self<Docking>() };
|
||||
dockSettings->Side(Model::DockPosition::Top);
|
||||
dockSettings->Width(1.0);
|
||||
dockSettings->Height(0.5);
|
||||
_DockWindow = *dockSettings;
|
||||
_MinimizeToNotificationArea = true;
|
||||
}
|
||||
|
||||
static constexpr std::string_view SideKey{ "side" };
|
||||
static constexpr std::string_view WidthKey{ "width" };
|
||||
static constexpr std::string_view HeightKey{ "height" };
|
||||
|
||||
winrt::com_ptr<Docking> Docking::FromJson(const Json::Value& json)
|
||||
{
|
||||
auto result = winrt::make_self<Docking>();
|
||||
|
||||
if (json.isObject())
|
||||
{
|
||||
JsonUtils::GetValueForKey(json, SideKey, result->Side);
|
||||
JsonUtils::GetValueForKey(json, WidthKey, result->Width);
|
||||
JsonUtils::GetValueForKey(json, HeightKey, result->Height);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Json::Value Docking::ToJson() const
|
||||
{
|
||||
Json::Value json{ Json::ValueType::objectValue };
|
||||
|
||||
JsonUtils::SetValueForKey(json, SideKey, Side);
|
||||
JsonUtils::SetValueForKey(json, WidthKey, Width);
|
||||
JsonUtils::SetValueForKey(json, HeightKey, Height);
|
||||
return json;
|
||||
}
|
||||
|
||||
winrt::com_ptr<Docking> Docking::Copy() const
|
||||
{
|
||||
auto pair{ winrt::make_self<Docking>() };
|
||||
pair->Side = Side;
|
||||
pair->Width = Width;
|
||||
pair->Height = Height;
|
||||
return pair;
|
||||
}
|
||||
123
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
123
src/cascadia/TerminalSettingsModel/WindowSettings.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/*++
|
||||
Copyright (c) Microsoft Corporation
|
||||
Licensed under the MIT license.
|
||||
|
||||
Module Name:
|
||||
- WindowSettings.h
|
||||
|
||||
Abstract:
|
||||
- This class encapsulates all of the settings that are specific to a single
|
||||
window. Broader than Profile settings (which are more like, per-pane
|
||||
settings). Different windows can have different settings for things like
|
||||
Theme, default profile, launch mode, etc.
|
||||
|
||||
Author(s):
|
||||
- Mike Griese - Sept 2023
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "WindowSettings.g.h"
|
||||
#include "Docking.g.h"
|
||||
#include "IInheritable.h"
|
||||
#include "MTSMSettings.h"
|
||||
|
||||
#include "TerminalSettingsSerializationHelpers.h"
|
||||
#include "ColorScheme.h"
|
||||
#include "Theme.h"
|
||||
#include "NewTabMenuEntry.h"
|
||||
#include "RemainingProfilesEntry.h"
|
||||
|
||||
// fwdecl unittest classes
|
||||
namespace SettingsModelUnitTests
|
||||
{
|
||||
class DeserializationTests;
|
||||
class ColorSchemeTests;
|
||||
};
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
{
|
||||
struct WindowSettings : WindowSettingsT<WindowSettings>, IInheritable<WindowSettings>
|
||||
{
|
||||
public:
|
||||
void _FinalizeInheritance() override;
|
||||
com_ptr<WindowSettings> Copy() const;
|
||||
|
||||
static com_ptr<WindowSettings> FromJson(const Json::Value& json);
|
||||
void LayerJson(const Json::Value& json);
|
||||
|
||||
Json::Value ToJson();
|
||||
|
||||
void InitializeForQuakeMode();
|
||||
|
||||
// This DefaultProfile() setter is called by CascadiaSettings,
|
||||
// when it parses UnparsedDefaultProfile in _finalizeSettings().
|
||||
void DefaultProfile(const guid& defaultProfile) noexcept;
|
||||
guid DefaultProfile() const;
|
||||
|
||||
til::property<winrt::hstring> Name;
|
||||
|
||||
INHERITABLE_SETTING(Model::WindowSettings, hstring, UnparsedDefaultProfile, L"");
|
||||
|
||||
#define WINDOW_SETTINGS_INITIALIZE(type, name, jsonKey, ...) \
|
||||
INHERITABLE_SETTING(Model::WindowSettings, type, name, ##__VA_ARGS__)
|
||||
MTSM_WINDOW_SETTINGS(WINDOW_SETTINGS_INITIALIZE)
|
||||
#undef WINDOW_SETTINGS_INITIALIZE
|
||||
|
||||
private:
|
||||
winrt::guid _defaultProfile;
|
||||
};
|
||||
|
||||
struct Docking : DockingT<Docking>
|
||||
{
|
||||
Docking() = default;
|
||||
|
||||
til::property<Model::DockPosition> Side{ Model::DockPosition::None };
|
||||
til::property<double> Width{ 1.0 };
|
||||
til::property<double> Height{ 1.0 };
|
||||
|
||||
static com_ptr<Docking> FromJson(const Json::Value& json);
|
||||
Json::Value ToJson() const;
|
||||
com_ptr<Docking> Copy() const;
|
||||
};
|
||||
}
|
||||
|
||||
namespace Microsoft::Terminal::Settings::Model::JsonUtils
|
||||
{
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
|
||||
template<>
|
||||
struct ConversionTrait<Docking>
|
||||
{
|
||||
Docking FromJson(const Json::Value& json)
|
||||
{
|
||||
const auto entry = implementation::Docking::FromJson(json);
|
||||
if (entry == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *entry;
|
||||
}
|
||||
|
||||
bool CanConvert(const Json::Value& json) const
|
||||
{
|
||||
return json.isObject();
|
||||
}
|
||||
|
||||
Json::Value ToJson(const Docking& val)
|
||||
{
|
||||
return winrt::get_self<implementation::Docking>(val)->ToJson();
|
||||
}
|
||||
|
||||
std::string TypeDescription() const
|
||||
{
|
||||
return "Docking";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
{
|
||||
BASIC_FACTORY(Docking);
|
||||
}
|
||||
@@ -235,7 +235,7 @@ namespace SettingsModelUnitTests
|
||||
const auto settings = createSettings(goodProfiles);
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(0), settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 2: Bad settings
|
||||
@@ -246,7 +246,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 2: Bad settings
|
||||
@@ -257,7 +257,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(0));
|
||||
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(0).Guid());
|
||||
}
|
||||
{
|
||||
// Case 4: Good settings, default profile is a string
|
||||
@@ -266,7 +266,7 @@ namespace SettingsModelUnitTests
|
||||
const auto settings = createSettings(goodProfilesSpecifiedByName);
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(0), settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(static_cast<size_t>(2), settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->AllProfiles().GetAt(1).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->AllProfiles().GetAt(1).Guid());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(SettingsLoadWarnings::MissingDefaultProfile, settings->Warnings().GetAt(1));
|
||||
|
||||
VERIFY_ARE_EQUAL(3u, settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Guid(), settings->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().GetAt(0).Guid(), settings->WindowSettingsDefaults().DefaultProfile());
|
||||
}
|
||||
|
||||
void DeserializationTests::LayerGlobalProperties()
|
||||
@@ -376,10 +376,10 @@ namespace SettingsModelUnitTests
|
||||
})" };
|
||||
|
||||
const auto settings = winrt::make_self<implementation::CascadiaSettings>(userSettings, inboxSettings);
|
||||
VERIFY_ARE_EQUAL(true, settings->GlobalSettings().AlwaysShowTabs());
|
||||
VERIFY_ARE_EQUAL(240, settings->GlobalSettings().InitialCols());
|
||||
VERIFY_ARE_EQUAL(60, settings->GlobalSettings().InitialRows());
|
||||
VERIFY_ARE_EQUAL(false, settings->GlobalSettings().ShowTabsInTitlebar());
|
||||
VERIFY_ARE_EQUAL(true, settings->WindowSettingsDefaults().AlwaysShowTabs());
|
||||
VERIFY_ARE_EQUAL(240, settings->WindowSettingsDefaults().InitialCols());
|
||||
VERIFY_ARE_EQUAL(60, settings->WindowSettingsDefaults().InitialRows());
|
||||
VERIFY_ARE_EQUAL(false, settings->WindowSettingsDefaults().ShowTabsInTitlebar());
|
||||
}
|
||||
|
||||
void DeserializationTests::ValidateProfileOrdering()
|
||||
@@ -989,7 +989,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_IS_NOT_NULL(settings->ProfileDefaults());
|
||||
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", settings->GlobalSettings().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", settings->WindowSettingsDefaults().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(2u, settings->AllProfiles().Size());
|
||||
|
||||
VERIFY_ARE_EQUAL(2345, settings->AllProfiles().GetAt(0).HistorySize());
|
||||
@@ -1027,7 +1027,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto settings = winrt::make_self<implementation::CascadiaSettings>(settings0String, implementation::LoadStringResource(IDR_DEFAULTS));
|
||||
|
||||
VERIFY_ARE_EQUAL(guid1String, settings->GlobalSettings().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(guid1String, settings->WindowSettingsDefaults().UnparsedDefaultProfile());
|
||||
VERIFY_ARE_EQUAL(4u, settings->AllProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(guid1, settings->AllProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_NOT_EQUAL(guid1, settings->AllProfiles().GetAt(1).Guid());
|
||||
@@ -1273,8 +1273,8 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto settings = createSettings(inputSettings);
|
||||
|
||||
VERIFY_ARE_EQUAL(999, settings->GlobalSettings().InitialCols());
|
||||
VERIFY_ARE_EQUAL(1, settings->GlobalSettings().InitialRows());
|
||||
VERIFY_ARE_EQUAL(999, settings->WindowSettingsDefaults().InitialCols());
|
||||
VERIFY_ARE_EQUAL(1, settings->WindowSettingsDefaults().InitialRows());
|
||||
}
|
||||
|
||||
void DeserializationTests::TestTrailingCommas()
|
||||
@@ -1757,7 +1757,7 @@ namespace SettingsModelUnitTests
|
||||
const auto copyImpl{ winrt::get_self<implementation::CascadiaSettings>(copy) };
|
||||
|
||||
// test globals
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), copyImpl->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), copyImpl->WindowSettingsDefaults().DefaultProfile());
|
||||
|
||||
// test profiles
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size());
|
||||
@@ -1775,9 +1775,9 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(nameMapOriginal.Size(), nameMapCopy.Size());
|
||||
|
||||
// Test that changing the copy should not change the original
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().WordDelimiters(), copyImpl->GlobalSettings().WordDelimiters());
|
||||
copyImpl->GlobalSettings().WordDelimiters(L"changed value");
|
||||
VERIFY_ARE_NOT_EQUAL(settings->GlobalSettings().WordDelimiters(), copyImpl->GlobalSettings().WordDelimiters());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().WordDelimiters(), copyImpl->WindowSettingsDefaults().WordDelimiters());
|
||||
copyImpl->WindowSettingsDefaults().WordDelimiters(L"changed value");
|
||||
VERIFY_ARE_NOT_EQUAL(settings->WindowSettingsDefaults().WordDelimiters(), copyImpl->WindowSettingsDefaults().WordDelimiters());
|
||||
}
|
||||
|
||||
void DeserializationTests::TestCloneInheritanceTree()
|
||||
@@ -1813,7 +1813,7 @@ namespace SettingsModelUnitTests
|
||||
const auto copyImpl{ winrt::get_self<implementation::CascadiaSettings>(copy) };
|
||||
|
||||
// test globals
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), copyImpl->GlobalSettings().DefaultProfile());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), copyImpl->WindowSettingsDefaults().DefaultProfile());
|
||||
|
||||
// test profiles
|
||||
VERIFY_ARE_EQUAL(settings->AllProfiles().Size(), copyImpl->AllProfiles().Size());
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->Warnings().Size());
|
||||
|
||||
const auto& entries = settings->GlobalSettings().NewTabMenu();
|
||||
const auto& entries = settings->WindowSettingsDefaults().NewTabMenu();
|
||||
VERIFY_ARE_EQUAL(1u, entries.Size());
|
||||
VERIFY_ARE_EQUAL(winrt::Microsoft::Terminal::Settings::Model::NewTabMenuEntryType::RemainingProfiles, entries.GetAt(0).Type());
|
||||
}
|
||||
@@ -74,7 +74,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(0u, settings->Warnings().Size());
|
||||
|
||||
const auto& entries = settings->GlobalSettings().NewTabMenu();
|
||||
const auto& entries = settings->WindowSettingsDefaults().NewTabMenu();
|
||||
VERIFY_ARE_EQUAL(1u, entries.Size());
|
||||
}
|
||||
catch (const SettingsException& ex)
|
||||
|
||||
@@ -244,7 +244,7 @@ namespace SettingsModelUnitTests
|
||||
NewTerminalArgs args;
|
||||
args.Commandline(testCase.input);
|
||||
|
||||
const auto profile = settings->GetProfileForArgs(args);
|
||||
const auto profile = settings->GetProfileForArgs(args, settings->WindowSettingsDefaults());
|
||||
VERIFY_IS_NOT_NULL(profile);
|
||||
|
||||
if (testCase.expected < 0)
|
||||
@@ -332,8 +332,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.TabTitle().empty());
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -356,8 +356,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"{6239a42c-1111-49a3-80bd-e8fdd045185c}", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
@@ -380,8 +380,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"pwsh.exe", termSettings->Commandline());
|
||||
@@ -404,8 +404,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_FALSE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -428,8 +428,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", terminalArgs.Commandline());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
// This action specified a command but no profile; it gets reassigned to the base profile
|
||||
VERIFY_ARE_EQUAL(settings->ProfileDefaults(), profile);
|
||||
@@ -454,8 +454,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", terminalArgs.Commandline());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", termSettings->Commandline());
|
||||
@@ -476,8 +476,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.TabTitle().empty());
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -499,8 +499,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"c:\\foo", terminalArgs.StartingDirectory());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -524,8 +524,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"c:\\foo", terminalArgs.StartingDirectory());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -548,8 +548,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_TRUE(terminalArgs.Profile().empty());
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid0, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"cmd.exe", termSettings->Commandline());
|
||||
@@ -573,8 +573,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
VERIFY_ARE_EQUAL(L"profile2", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(profile2Guid, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"wsl.exe", termSettings->Commandline());
|
||||
@@ -600,8 +600,8 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_ARE_EQUAL(L"bar", terminalArgs.TabTitle());
|
||||
VERIFY_ARE_EQUAL(L"profile1", terminalArgs.Profile());
|
||||
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs) };
|
||||
const auto profile{ settings->GetProfileForArgs(terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, terminalArgs, settings->WindowSettingsDefaults()) };
|
||||
const auto termSettings = settingsStruct.DefaultSettings();
|
||||
VERIFY_ARE_EQUAL(guid1, profile.Guid());
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", termSettings->Commandline());
|
||||
@@ -640,7 +640,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile1) };
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile1, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -650,7 +650,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile2) };
|
||||
auto settingsStruct{ TerminalSettings::CreateWithProfile(*settings, profile2, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(2, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -660,7 +660,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
try
|
||||
{
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -695,10 +695,10 @@ namespace SettingsModelUnitTests
|
||||
|
||||
VERIFY_ARE_EQUAL(2u, settings->Warnings().Size());
|
||||
VERIFY_ARE_EQUAL(2u, settings->ActiveProfiles().Size());
|
||||
VERIFY_ARE_EQUAL(settings->GlobalSettings().DefaultProfile(), settings->ActiveProfiles().GetAt(0).Guid());
|
||||
VERIFY_ARE_EQUAL(settings->WindowSettingsDefaults().DefaultProfile(), settings->ActiveProfiles().GetAt(0).Guid());
|
||||
try
|
||||
{
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, nullptr, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(1, settingsStruct.DefaultSettings()->HistorySize());
|
||||
}
|
||||
catch (...)
|
||||
@@ -799,7 +799,7 @@ namespace SettingsModelUnitTests
|
||||
|
||||
const auto activeProfiles = settings->ActiveProfiles();
|
||||
const auto colorSchemes = settings->GlobalSettings().ColorSchemes();
|
||||
const auto currentTheme = settings->GlobalSettings().CurrentTheme();
|
||||
const auto currentTheme = settings->GlobalSettings().CurrentTheme(settings->WindowSettingsDefaults());
|
||||
const auto terminalSettings0 = createTerminalSettings(activeProfiles.GetAt(0), colorSchemes, currentTheme);
|
||||
const auto terminalSettings1 = createTerminalSettings(activeProfiles.GetAt(1), colorSchemes, currentTheme);
|
||||
const auto terminalSettings2 = createTerminalSettings(activeProfiles.GetAt(2), colorSchemes, currentTheme);
|
||||
@@ -838,58 +838,58 @@ namespace SettingsModelUnitTests
|
||||
{ // just a profile (profile wins)
|
||||
NewTerminalArgs args{};
|
||||
args.Profile(L"profile0");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // profile and command line -> no promotion (profile wins)
|
||||
NewTerminalArgs args{};
|
||||
args.Profile(L"profile0");
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"profile0", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // just a title -> it is propagated
|
||||
NewTerminalArgs args{};
|
||||
args.TabTitle(L"Analog Kid");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"Analog Kid", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // title and command line -> no promotion
|
||||
NewTerminalArgs args{};
|
||||
args.TabTitle(L"Digital Man");
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"Digital Man", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{ // just a commandline -> promotion
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"foo.exe");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
// various typesof commandline follow
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"foo.exe bar");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"\"foo exe.exe\" bar");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"foo exe.exe", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L"\"\" grand designs");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
{
|
||||
NewTerminalArgs args{};
|
||||
args.Commandline(L" imagine a man");
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args) };
|
||||
const auto settingsStruct{ TerminalSettings::CreateWithNewTerminalArgs(*settings, args, settings->WindowSettingsDefaults()) };
|
||||
VERIFY_ARE_EQUAL(L"", settingsStruct.DefaultSettings()->StartingTitle());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace SettingsModelUnitTests
|
||||
VERIFY_IS_NULL(bar.TabRow().Background());
|
||||
}
|
||||
|
||||
const auto currentTheme{ settings->GlobalSettings().CurrentTheme() };
|
||||
const auto currentTheme{ settings->GlobalSettings().CurrentTheme(settings->WindowSettingsDefaults()) };
|
||||
VERIFY_IS_NOT_NULL(currentTheme);
|
||||
VERIFY_ARE_EQUAL(L"system", currentTheme.Name());
|
||||
}
|
||||
|
||||
@@ -556,21 +556,66 @@ void AppHost::_initialResizeAndRepositionWindow(const HWND hwnd, til::rect propo
|
||||
til::point origin{ (proposedRect.left + nonClientFrame.left),
|
||||
(proposedRect.top) };
|
||||
|
||||
if (_windowLogic.IsQuakeWindow())
|
||||
if (const auto dockingSettings{ _windowLogic.Docking() })
|
||||
{
|
||||
// If we just use rcWork by itself, we'll fail to account for the invisible
|
||||
// space reserved for the resize handles. So retrieve that size here.
|
||||
const auto availableSpace = desktopDimensions + nonClientSize;
|
||||
const auto singleBorderWidth = nonClientSize.width / 2;
|
||||
const auto singleBorderHeight = nonClientSize.height / 2;
|
||||
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (nonClientSize.width / 2)),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
dimensions = {
|
||||
availableSpace.width,
|
||||
availableSpace.height / 2
|
||||
};
|
||||
launchMode = LaunchMode::FocusMode;
|
||||
// If it's >1, then use that as a number of px.
|
||||
// If it's <= 1, then use that as a multiplier on the available space
|
||||
const auto settingsWidth = dockingSettings.Width();
|
||||
const auto width{ settingsWidth > 1.0 ? settingsWidth : (availableSpace.width * settingsWidth) };
|
||||
const auto settingsHeight = dockingSettings.Height();
|
||||
const auto height{ settingsHeight > 1.0 ? settingsHeight : (availableSpace.height * settingsHeight) };
|
||||
|
||||
dimensions = { til::math::rounding,
|
||||
width,
|
||||
height };
|
||||
|
||||
// Account for centerOnLaunch too
|
||||
const til::size fromSide = centerOnLaunch ? (til::size{ til::math::rounding,
|
||||
(availableSpace.width - width) / 2.0,
|
||||
(availableSpace.height - height) / 2.0 }) :
|
||||
(til::size{ 0, 0 });
|
||||
|
||||
switch (dockingSettings.Side())
|
||||
{
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Bottom:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.bottom - singleBorderHeight - (dimensions.height))
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Left:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Right:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.right - (singleBorderWidth) - (dimensions.width)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (centerOnLaunch)
|
||||
{
|
||||
@@ -930,7 +975,7 @@ void _frameColorHelper(const HWND h, const COLORREF color)
|
||||
|
||||
void AppHost::_updateTheme()
|
||||
{
|
||||
auto theme = _appLogic.Settings().GlobalSettings().CurrentTheme();
|
||||
auto theme = _windowLogic.Theme();
|
||||
|
||||
_window->OnApplicationThemeChanged(theme.RequestedTheme());
|
||||
|
||||
@@ -1027,7 +1072,13 @@ void AppHost::_HandleSettingsChanged(const winrt::Windows::Foundation::IInspecta
|
||||
void AppHost::_IsQuakeWindowChanged(const winrt::Windows::Foundation::IInspectable&,
|
||||
const winrt::Windows::Foundation::IInspectable&)
|
||||
{
|
||||
_window->IsQuakeWindow(_windowLogic.IsQuakeWindow());
|
||||
// The window's per-window settings identity changed (e.g. window
|
||||
// name changed, or settings reloaded). Re-push every host-level
|
||||
// per-window property so the IslandWindow stays in sync.
|
||||
_window->DockSettings(_windowLogic.Docking(), _windowLogic.CenterOnLaunch());
|
||||
_window->SetMinimizeToNotificationAreaBehavior(_windowLogic.GetMinimizeToNotificationArea());
|
||||
_window->SetAutoHideWindow(_windowLogic.AutoHideWindow());
|
||||
_window->SetShowTabsFullscreen(_windowLogic.ShowTabsFullscreen());
|
||||
}
|
||||
|
||||
// Raised from TerminalWindow. We handle by bubbling the request to the window manager.
|
||||
|
||||
@@ -17,6 +17,7 @@ using namespace winrt::Windows::UI::Composition;
|
||||
using namespace winrt::Windows::UI::Xaml;
|
||||
using namespace winrt::Windows::UI::Xaml::Hosting;
|
||||
using namespace winrt::Windows::Foundation::Numerics;
|
||||
using namespace winrt::Microsoft::Terminal::Settings;
|
||||
using namespace winrt::Microsoft::Terminal::Settings::Model;
|
||||
using namespace winrt::Microsoft::Terminal::Control;
|
||||
using namespace winrt::Microsoft::Terminal;
|
||||
@@ -230,6 +231,14 @@ void IslandWindow::_HandleCreateWindow(const WPARAM, const LPARAM lParam) noexce
|
||||
UpdateWindowIconForActiveMetrics(_window.get());
|
||||
}
|
||||
|
||||
bool _preventSizingForDocked(const Model::DockPosition side, const WPARAM sizingSide)
|
||||
{
|
||||
return (side == Model::DockPosition::Top && sizingSide == WMSZ_TOP) ||
|
||||
(side == Model::DockPosition::Bottom && sizingSide == WMSZ_BOTTOM) ||
|
||||
(side == Model::DockPosition::Left && sizingSide == WMSZ_LEFT) ||
|
||||
(side == Model::DockPosition::Right && sizingSide == WMSZ_RIGHT);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Handles a WM_SIZING message, which occurs when user drags a window border
|
||||
// or corner. It intercepts this resize action and applies 'snapping' i.e.
|
||||
@@ -253,14 +262,16 @@ LRESULT IslandWindow::_OnSizing(const WPARAM wParam, const LPARAM lParam)
|
||||
|
||||
auto winRect = reinterpret_cast<LPRECT>(lParam);
|
||||
|
||||
// If we're the quake window, prevent resizing on all sides except the
|
||||
// bottom. This also applies to resizing with the Alt+Space menu
|
||||
if (IsQuakeWindow() && wParam != WMSZ_BOTTOM)
|
||||
// I think it's okay to resize a docked window on any side that's not the side we're docked to.
|
||||
if (_docked())
|
||||
{
|
||||
// Stuff our current window size into the lParam, and return true. This
|
||||
// will tell User32 to use our current dimensions to resize to.
|
||||
::GetWindowRect(_window.get(), winRect);
|
||||
return true;
|
||||
if (_preventSizingForDocked(_dockingSettings.Side(), wParam))
|
||||
{
|
||||
// Stuff our current window size into the lParam, and return true. This
|
||||
// will tell User32 to use our current dimensions to resize to.
|
||||
::GetWindowRect(_window.get(), winRect);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Find nearest monitor.
|
||||
@@ -355,7 +366,7 @@ LRESULT IslandWindow::_OnMoving(const WPARAM /*wParam*/, const LPARAM lParam)
|
||||
|
||||
// If we're the quake window, prevent moving the window. If we don't do
|
||||
// this, then Alt+Space...Move will still be able to move the window.
|
||||
if (IsQuakeWindow())
|
||||
if (_docked())
|
||||
{
|
||||
// Stuff our current window into the lParam, and return true. This
|
||||
// will tell User32 to use our current position to move to.
|
||||
@@ -520,7 +531,7 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
|
||||
if (_autoHideWindow && !activated)
|
||||
{
|
||||
if (_isQuakeWindow || _minimizeToNotificationArea)
|
||||
if (_minimizeToNotificationArea)
|
||||
{
|
||||
HideWindow();
|
||||
}
|
||||
@@ -569,7 +580,8 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
if (wparam == SIZE_MINIMIZED)
|
||||
{
|
||||
WindowVisibilityChanged.raise(false);
|
||||
if (_isQuakeWindow)
|
||||
|
||||
if (_minimizeToNotificationArea)
|
||||
{
|
||||
ShowWindow(GetHandle(), SW_HIDE);
|
||||
return 0;
|
||||
@@ -643,7 +655,7 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
{
|
||||
// GH#10274 - if the quake window gets moved to another monitor via aero
|
||||
// snap (win+shift+arrows), then re-adjust the size for the new monitor.
|
||||
if (IsQuakeWindow())
|
||||
if (_docked())
|
||||
{
|
||||
// Retrieve the suggested dimensions and make a rect and size.
|
||||
auto lpwpos = (LPWINDOWPOS)lparam;
|
||||
@@ -679,10 +691,10 @@ void IslandWindow::_OnGetMinMaxInfo(const WPARAM /*wParam*/, const LPARAM lParam
|
||||
if (til::rect{ proposedInfo.rcMonitor } !=
|
||||
til::rect{ currentInfo.rcMonitor })
|
||||
{
|
||||
const auto newWindowRect{ _getQuakeModeSize(proposed) };
|
||||
const auto newWindowRect{ _getDockedSize(proposed) };
|
||||
|
||||
// Inform User32 that we want to be placed at the position
|
||||
// and dimensions that _getQuakeModeSize returned. When we
|
||||
// and dimensions that _getDockedSize returned. When we
|
||||
// snap across monitor boundaries, this will re-evaluate our
|
||||
// size for the new monitor.
|
||||
lpwpos->x = newWindowRect.left;
|
||||
@@ -1309,7 +1321,10 @@ void IslandWindow::SummonWindow(winrt::TerminalApp::SummonWindowBehavior args)
|
||||
|
||||
// Method Description:
|
||||
// - Helper for performing a sliding animation. This will animate our _Xaml
|
||||
// Island_, either growing down or shrinking up, using SetWindowRgn.
|
||||
// Island_ using SetWindowRgn, revealing or hiding the window from the edge
|
||||
// it is docked to. For Top-docked windows the region grows/shrinks
|
||||
// vertically from the top; for Bottom from the bottom; for Left horizontally
|
||||
// from the left; for Right from the right.
|
||||
// - This function does the entire animation on the main thread (the UI thread),
|
||||
// and **DOES NOT YIELD IT**. The window will be animating for the entire
|
||||
// duration of dropdownDuration.
|
||||
@@ -1318,15 +1333,22 @@ void IslandWindow::SummonWindow(winrt::TerminalApp::SummonWindowBehavior args)
|
||||
// Arguments:
|
||||
// - dropdownDuration: The duration to play the animation, in milliseconds. If
|
||||
// 0, we won't perform a dropdown animation.
|
||||
// - down: if true, increase the height from top to bottom. otherwise, decrease
|
||||
// the height, from bottom to top.
|
||||
// - appearing: if true, the window is sliding into view (the visible region
|
||||
// grows). If false, it is sliding out of view (the visible region shrinks).
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool down)
|
||||
void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool appearing)
|
||||
{
|
||||
til::rect fullWindowSize{ GetWindowRect() };
|
||||
const auto fullWidth = fullWindowSize.width();
|
||||
const auto fullHeight = fullWindowSize.height();
|
||||
|
||||
// Determine which axis and direction to animate based on the dock side.
|
||||
// Default to Top for the (unlikely) case where there is no docking config.
|
||||
const auto side = _dockingSettings ? _dockingSettings.Side() : Model::DockPosition::Top;
|
||||
const bool horizontal = (side == Model::DockPosition::Left || side == Model::DockPosition::Right);
|
||||
const auto fullExtent = horizontal ? fullWidth : fullHeight;
|
||||
|
||||
const double animationDuration = dropdownDuration; // use floating-point math throughout
|
||||
const auto start = std::chrono::system_clock::now();
|
||||
|
||||
@@ -1343,12 +1365,31 @@ void IslandWindow::_doSlideAnimation(const uint32_t dropdownDuration, const bool
|
||||
break;
|
||||
}
|
||||
|
||||
// If going down, increase the height over time. If going up, decrease the height.
|
||||
const auto currentHeight = ::base::saturated_cast<int>(
|
||||
down ? ((dt / animationDuration) * fullHeight) :
|
||||
((1.0 - (dt / animationDuration)) * fullHeight));
|
||||
// Progress goes 0→1 when appearing and 1→0 when disappearing.
|
||||
const auto progress = appearing ? (dt / animationDuration) : (1.0 - (dt / animationDuration));
|
||||
const auto currentExtent = ::base::saturated_cast<int>(progress * fullExtent);
|
||||
|
||||
wil::unique_hrgn rgn{ CreateRectRgn(0, 0, fullWindowSize.width(), currentHeight) };
|
||||
wil::unique_hrgn rgn;
|
||||
switch (side)
|
||||
{
|
||||
case Model::DockPosition::Top:
|
||||
default:
|
||||
// Reveal/hide from the top edge downward.
|
||||
rgn.reset(CreateRectRgn(0, 0, fullWidth, currentExtent));
|
||||
break;
|
||||
case Model::DockPosition::Bottom:
|
||||
// Reveal/hide from the bottom edge upward.
|
||||
rgn.reset(CreateRectRgn(0, fullHeight - currentExtent, fullWidth, fullHeight));
|
||||
break;
|
||||
case Model::DockPosition::Left:
|
||||
// Reveal/hide from the left edge rightward.
|
||||
rgn.reset(CreateRectRgn(0, 0, currentExtent, fullHeight));
|
||||
break;
|
||||
case Model::DockPosition::Right:
|
||||
// Reveal/hide from the right edge leftward.
|
||||
rgn.reset(CreateRectRgn(fullWidth - currentExtent, 0, fullWidth, fullHeight));
|
||||
break;
|
||||
}
|
||||
SetWindowRgn(_interopWindowHandle, rgn.get(), true);
|
||||
|
||||
// Go immediately into another frame. This prevents the window from
|
||||
@@ -1388,13 +1429,13 @@ void IslandWindow::_dropdownWindow(const uint32_t dropdownDuration,
|
||||
// Possibly go to the monitor of the mouse / old foreground window.
|
||||
_moveToMonitor(oldForegroundWindow, toMonitor);
|
||||
|
||||
// Now that we're visible, animate the dropdown.
|
||||
// Now that we're visible, animate the window sliding into view.
|
||||
_doSlideAnimation(dropdownDuration, true);
|
||||
}
|
||||
|
||||
void IslandWindow::_slideUpWindow(const uint32_t dropdownDuration)
|
||||
{
|
||||
// First, animate the window sliding up.
|
||||
// First, animate the window sliding out of view.
|
||||
_doSlideAnimation(dropdownDuration, false);
|
||||
|
||||
// Then, use SetWindowPlacement to minimize without the animation.
|
||||
@@ -1616,46 +1657,56 @@ void IslandWindow::_moveToMonitor(const MONITORINFO activeMonitor)
|
||||
|
||||
// GH#10274, GH#10182: Re-evaluate the size of the quake window when we
|
||||
// move to another monitor.
|
||||
if (IsQuakeWindow())
|
||||
{
|
||||
_enterQuakeMode();
|
||||
}
|
||||
_applyDocking();
|
||||
}
|
||||
}
|
||||
|
||||
bool IslandWindow::IsQuakeWindow() const noexcept
|
||||
Docking IslandWindow::DockSettings() const noexcept
|
||||
{
|
||||
return _isQuakeWindow;
|
||||
return _dockingSettings;
|
||||
}
|
||||
|
||||
void IslandWindow::IsQuakeWindow(bool isQuakeWindow) noexcept
|
||||
void IslandWindow::DockSettings(Docking settings, const bool centered) noexcept
|
||||
{
|
||||
if (_isQuakeWindow != isQuakeWindow)
|
||||
_centered = centered;
|
||||
if (_dockingSettings != settings)
|
||||
{
|
||||
_isQuakeWindow = isQuakeWindow;
|
||||
// Don't enter quake mode if we don't have an HWND yet
|
||||
if (IsQuakeWindow() && _window)
|
||||
_dockingSettings = settings;
|
||||
|
||||
// If the window has already been created, immediately apply the
|
||||
// new docking configuration so it snaps into place. When called
|
||||
// before window creation (e.g. during startup) the docking will
|
||||
// be applied later by _initialResizeAndRepositionWindow.
|
||||
if (settings && _window)
|
||||
{
|
||||
_enterQuakeMode();
|
||||
_applyDocking();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool IslandWindow::_docked() const noexcept
|
||||
{
|
||||
return _dockingSettings != nullptr && _dockingSettings.Side() != Model::DockPosition::None;
|
||||
}
|
||||
|
||||
void IslandWindow::SetAutoHideWindow(bool autoHideWindow) noexcept
|
||||
{
|
||||
_autoHideWindow = autoHideWindow;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Enter quake mode for the monitor this window is currently on. This involves
|
||||
// resizing it to the top half of the monitor.
|
||||
// - Apply the current docking configuration. The window is moved and
|
||||
// resized to the appropriate edge of the nearest monitor according
|
||||
// to _dockingSettings (side, width, height). If _centered is set,
|
||||
// the window is offset towards the centre of the monitor along the
|
||||
// non-docked axis.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void IslandWindow::_enterQuakeMode()
|
||||
void IslandWindow::_applyDocking()
|
||||
{
|
||||
if (!_window)
|
||||
if (!_window || !_dockingSettings || _dockingSettings.Side() == Model::DockPosition::None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1664,7 +1715,7 @@ void IslandWindow::_enterQuakeMode()
|
||||
auto hmon = MonitorFromRect(&windowRect, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
// Get the size and position of the window that we should occupy
|
||||
const auto newRect{ _getQuakeModeSize(hmon) };
|
||||
const auto newRect{ _getDockedSize(hmon) };
|
||||
|
||||
SetWindowPos(GetHandle(),
|
||||
HWND_TOP,
|
||||
@@ -1676,14 +1727,14 @@ void IslandWindow::_enterQuakeMode()
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Get the size and position of the window that a "quake mode" should occupy
|
||||
// on the given monitor.
|
||||
// - The window will occupy the top half of the monitor.
|
||||
// - Calculate the position and size of the docked window on the given
|
||||
// monitor. The result depends on _dockingSettings (side, width,
|
||||
// height) and _centered.
|
||||
// Arguments:
|
||||
// - <none>
|
||||
// - hmon: the monitor to dock on.
|
||||
// Return Value:
|
||||
// - <none>
|
||||
til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
|
||||
// - A til::rect describing the window rectangle in screen coordinates.
|
||||
til::rect IslandWindow::_getDockedSize(HMONITOR hmon)
|
||||
{
|
||||
MONITORINFO nearestMonitorInfo;
|
||||
|
||||
@@ -1704,17 +1755,61 @@ til::rect IslandWindow::_getQuakeModeSize(HMONITOR hmon)
|
||||
const til::size ncSize{ GetTotalNonClientExclusiveSize(dpix) };
|
||||
const auto availableSpace = desktopDimensions + ncSize;
|
||||
|
||||
// GH#10201 - The borders are still visible in quake mode, so make us 1px
|
||||
// smaller on either side to account for that, so they don't hang onto
|
||||
// adjacent monitors.
|
||||
const til::point origin{
|
||||
::base::ClampSub(nearestMonitorInfo.rcWork.left, (ncSize.width / 2)) + 1,
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
const til::size dimensions{
|
||||
availableSpace.width - 2,
|
||||
availableSpace.height / 2
|
||||
};
|
||||
const auto singleBorderWidth = ncSize.width / 2;
|
||||
const auto singleBorderHeight = ncSize.height / 2;
|
||||
|
||||
// If it's >1, then use that as a number of px.
|
||||
// If it's <= 1, then use that as a multiplier on the available space
|
||||
const auto settingsWidth = _dockingSettings.Width();
|
||||
const auto width{ settingsWidth > 1.0 ? settingsWidth : (availableSpace.width * settingsWidth) };
|
||||
const auto settingsHeight = _dockingSettings.Height();
|
||||
const auto height{ settingsHeight > 1.0 ? settingsHeight : (availableSpace.height * settingsHeight) };
|
||||
|
||||
const til::size dimensions = { til::math::rounding,
|
||||
width,
|
||||
height };
|
||||
|
||||
// Account for centerOnLaunch too
|
||||
const til::size fromSide = _centered ? (til::size{ til::math::rounding,
|
||||
(availableSpace.width - width) / 2.0,
|
||||
(availableSpace.height - height) / 2.0 }) :
|
||||
(til::size{ 0, 0 });
|
||||
til::point origin;
|
||||
switch (_dockingSettings.Side())
|
||||
{
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.top)
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Bottom:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth) + fromSide.width),
|
||||
(nearestMonitorInfo.rcWork.bottom - singleBorderHeight - (dimensions.height))
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Left:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.left - (singleBorderWidth)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
case winrt::Microsoft::Terminal::Settings::Model::DockPosition::Right:
|
||||
{
|
||||
origin = {
|
||||
(nearestMonitorInfo.rcWork.right - (singleBorderWidth) - (dimensions.width)),
|
||||
(nearestMonitorInfo.rcWork.top) + fromSide.height
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { origin, dimensions };
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ public:
|
||||
|
||||
void SummonWindow(winrt::TerminalApp::SummonWindowBehavior args);
|
||||
|
||||
bool IsQuakeWindow() const noexcept;
|
||||
void IsQuakeWindow(bool isQuakeWindow) noexcept;
|
||||
winrt::Microsoft::Terminal::Settings::Model::Docking DockSettings() const noexcept;
|
||||
void DockSettings(winrt::Microsoft::Terminal::Settings::Model::Docking settings, const bool centered) noexcept;
|
||||
void SetAutoHideWindow(bool autoHideWindow) noexcept;
|
||||
|
||||
void HideWindow();
|
||||
@@ -131,7 +131,7 @@ protected:
|
||||
void _dropdownWindow(const uint32_t dropdownDuration,
|
||||
const winrt::TerminalApp::MonitorBehavior toMonitor);
|
||||
void _slideUpWindow(const uint32_t dropdownDuration);
|
||||
void _doSlideAnimation(const uint32_t dropdownDuration, const bool down);
|
||||
void _doSlideAnimation(const uint32_t dropdownDuration, const bool appearing);
|
||||
void _globalDismissWindow(const uint32_t dropdownDuration);
|
||||
|
||||
static MONITORINFO _getMonitorForCursor();
|
||||
@@ -141,11 +141,13 @@ protected:
|
||||
void _moveToMonitorOf(HWND foregroundWindow);
|
||||
void _moveToMonitor(const MONITORINFO activeMonitor);
|
||||
|
||||
bool _isQuakeWindow{ false };
|
||||
winrt::Microsoft::Terminal::Settings::Model::Docking _dockingSettings{ nullptr };
|
||||
bool _centered{ false };
|
||||
bool _autoHideWindow{ false };
|
||||
|
||||
void _enterQuakeMode();
|
||||
til::rect _getQuakeModeSize(HMONITOR hmon);
|
||||
void _applyDocking();
|
||||
til::rect _getDockedSize(HMONITOR hmon);
|
||||
bool _docked() const noexcept;
|
||||
|
||||
bool _minimizeToNotificationArea{ false };
|
||||
|
||||
|
||||
@@ -743,23 +743,6 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
||||
|
||||
if (originalRet != HTCLIENT)
|
||||
{
|
||||
// If we're the quake window, suppress resizing on any side except the
|
||||
// bottom. I don't believe that this actually works on the top. That's
|
||||
// handled below.
|
||||
if (IsQuakeWindow())
|
||||
{
|
||||
switch (originalRet)
|
||||
{
|
||||
case HTBOTTOMRIGHT:
|
||||
case HTRIGHT:
|
||||
case HTTOPRIGHT:
|
||||
case HTTOP:
|
||||
case HTTOPLEFT:
|
||||
case HTLEFT:
|
||||
case HTBOTTOMLEFT:
|
||||
return HTCLIENT;
|
||||
}
|
||||
}
|
||||
return originalRet;
|
||||
}
|
||||
|
||||
@@ -779,9 +762,15 @@ int NonClientIslandWindow::_GetResizeHandleHeight() const noexcept
|
||||
// the top of the drag bar is used to resize the window
|
||||
if (!_isMaximized && isOnResizeBorder)
|
||||
{
|
||||
// However, if we're the quake window, then just return HTCAPTION so we
|
||||
// don't get a resize handle on the top.
|
||||
return IsQuakeWindow() ? HTCAPTION : HTTOP;
|
||||
// If we're docked to the top, return HTCAPTION so we don't get a
|
||||
// resize handle on the side we're docked to. The user can't resize
|
||||
// the window away from the docked edge.
|
||||
if (_docked() && _dockingSettings.Side() == winrt::Microsoft::Terminal::Settings::Model::DockPosition::Top)
|
||||
{
|
||||
return HTCAPTION;
|
||||
}
|
||||
|
||||
return HTTOP;
|
||||
}
|
||||
|
||||
return HTCAPTION;
|
||||
|
||||
@@ -1443,12 +1443,14 @@ void WindowEmperor::_checkWindowsForNotificationIcon()
|
||||
// RequestsTrayIcon setting value, and combine that with the result of each
|
||||
// window (which won't change during a settings reload).
|
||||
const auto globals = _app.Logic().Settings().GlobalSettings();
|
||||
auto needsIcon = globals.AlwaysShowNotificationIcon() || globals.MinimizeToNotificationArea();
|
||||
const auto windowDefaults = _app.Logic().Settings().WindowSettingsDefaults();
|
||||
auto needsIcon = globals.AlwaysShowNotificationIcon() || windowDefaults.MinimizeToNotificationArea();
|
||||
if (!needsIcon)
|
||||
{
|
||||
for (const auto& host : _windows)
|
||||
{
|
||||
needsIcon |= host->Logic().IsQuakeWindow();
|
||||
const auto logic = host->Logic();
|
||||
needsIcon |= logic.GetMinimizeToNotificationArea();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user