From 4ff38c260f02388385ce6b424ef84a26db9f39aa Mon Sep 17 00:00:00 2001 From: Mike Griese Date: Mon, 26 Feb 2024 13:32:19 -0800 Subject: [PATCH] When the profile icon is set to null, fall back to the icon of the commandline (#15843) Basically, title. If you null out the icon, we'll automatically try to use the `commandline` as an icon (because we can now). We'll even be smart about it - `cmd.exe /k echo wassup` will still just use the ico of `cmd.exe`. This doesn't work for `ubuntu.exe` (et. al), because that commandline is technically a reparse point, that doesn't actually have an icon associated with it. Closes #705 `"none"` becomes our sentinel value for "no icon". This will also use the same `NormalizeCommandLine` we use for commandline matching for finding the full path to the exe. --- .../TerminalSettingsTests.cpp | 4 +- src/cascadia/TerminalApp/TabManagement.cpp | 7 +- src/cascadia/TerminalApp/TerminalPage.cpp | 5 +- .../TerminalSettingsEditor/MainPage.cpp | 2 +- .../ProfileViewModel.cpp | 26 +++ .../TerminalSettingsEditor/ProfileViewModel.h | 10 ++ .../ProfileViewModel.idl | 3 + .../TerminalSettingsEditor/Profiles_Base.xaml | 11 +- .../Resources/en-US/Resources.resw | 8 + .../CascadiaSettings.cpp | 136 +------------- .../TerminalSettingsModel/CascadiaSettings.h | 1 - .../TerminalSettingsModel/Command.cpp | 2 +- .../TerminalSettingsModel/MTSMSettings.h | 1 - .../TerminalSettingsModel/Profile.cpp | 170 ++++++++++++++++++ src/cascadia/TerminalSettingsModel/Profile.h | 15 ++ .../TerminalSettingsModel/Profile.idl | 4 + 16 files changed, 265 insertions(+), 140 deletions(-) diff --git a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp index 0ae0bcc164e..4dbc7f88db8 100644 --- a/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp +++ b/src/cascadia/LocalTests_SettingsModel/TerminalSettingsTests.cpp @@ -173,13 +173,13 @@ namespace SettingsModelLocalTests { const auto commandLine = file2.native() + LR"( -foo "bar1 bar2" -baz)"s; const auto expected = file2.native() + L"\0-foo\0bar1 bar2\0-baz"s; - const auto actual = implementation::CascadiaSettings::NormalizeCommandLine(commandLine.c_str()); + const auto actual = implementation::Profile::NormalizeCommandLine(commandLine.c_str()); VERIFY_ARE_EQUAL(expected, actual); } { const auto commandLine = L"C:\\"; const auto expected = L"C:\\"; - const auto actual = implementation::CascadiaSettings::NormalizeCommandLine(commandLine); + const auto actual = implementation::Profile::NormalizeCommandLine(commandLine); VERIFY_ARE_EQUAL(expected, actual); } } diff --git a/src/cascadia/TerminalApp/TabManagement.cpp b/src/cascadia/TerminalApp/TabManagement.cpp index 1717c05b8b7..78a1ead3acd 100644 --- a/src/cascadia/TerminalApp/TabManagement.cpp +++ b/src/cascadia/TerminalApp/TabManagement.cpp @@ -174,11 +174,12 @@ namespace winrt::TerminalApp::implementation // Set this tab's icon to the icon from the user's profile if (const auto profile{ newTabImpl->GetFocusedProfile() }) { - if (!profile.Icon().empty()) + const auto& icon = profile.EvaluatedIcon(); + if (!icon.empty()) { const auto theme = _settings.GlobalSettings().CurrentTheme(); const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default; - newTabImpl->UpdateIcon(profile.Icon(), iconStyle); + newTabImpl->UpdateIcon(icon, iconStyle); } } @@ -245,7 +246,7 @@ namespace winrt::TerminalApp::implementation { const auto theme = _settings.GlobalSettings().CurrentTheme(); const auto iconStyle = (theme && theme.Tab()) ? theme.Tab().IconStyle() : IconStyle::Default; - tab.UpdateIcon(profile.Icon(), iconStyle); + tab.UpdateIcon(profile.EvaluatedIcon(), iconStyle); } } diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 26a80fa7457..568a4d03f7e 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -1033,9 +1033,10 @@ namespace winrt::TerminalApp::implementation // If there's an icon set for this profile, set it as the icon for // this flyout item - if (!profile.Icon().empty()) + const auto& iconPath = profile.EvaluatedIcon(); + if (!iconPath.empty()) { - const auto icon = _CreateNewTabFlyoutIcon(profile.Icon()); + const auto icon = _CreateNewTabFlyoutIcon(iconPath); profileMenuItem.Icon(icon); } diff --git a/src/cascadia/TerminalSettingsEditor/MainPage.cpp b/src/cascadia/TerminalSettingsEditor/MainPage.cpp index 797c207ef88..b85b0ad5d11 100644 --- a/src/cascadia/TerminalSettingsEditor/MainPage.cpp +++ b/src/cascadia/TerminalSettingsEditor/MainPage.cpp @@ -602,7 +602,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation MUX::Controls::NavigationViewItem profileNavItem; profileNavItem.Content(box_value(profile.Name())); profileNavItem.Tag(box_value(profile)); - profileNavItem.Icon(IconPathConverter::IconWUX(profile.Icon())); + profileNavItem.Icon(IconPathConverter::IconWUX(profile.EvaluatedIcon())); // Update the menu item when the icon/name changes auto weakMenuItem{ make_weak(profileNavItem) }; diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp index 5f31f6be579..5f7517068b4 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.cpp @@ -26,6 +26,8 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Windows::Foundation::Collections::IObservableVector ProfileViewModel::_MonospaceFontList{ nullptr }; Windows::Foundation::Collections::IObservableVector ProfileViewModel::_FontList{ nullptr }; + static constexpr std::wstring_view HideIconValue{ L"none" }; + ProfileViewModel::ProfileViewModel(const Model::Profile& profile, const Model::CascadiaSettings& appSettings) : _profile{ profile }, _defaultAppearanceViewModel{ winrt::make(profile.DefaultAppearance().try_as()) }, @@ -69,6 +71,10 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation { _NotifyChanges(L"CurrentScrollState"); } + else if (viewModelProperty == L"Icon") + { + _NotifyChanges(L"HideIcon"); + } }); // Do the same for the starting directory @@ -348,6 +354,26 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation } } + bool ProfileViewModel::HideIcon() + { + return Icon() == HideIconValue; + } + void ProfileViewModel::HideIcon(const bool hide) + { + if (hide) + { + // Stash the current value of Icon. If the user + // checks and un-checks the "Hide Icon" checkbox, we want + // the path that we display in the text box to remain unchanged. + _lastIcon = Icon(); + Icon(HideIconValue); + } + else + { + Icon(_lastIcon); + } + } + bool ProfileViewModel::IsBellStyleFlagSet(const uint32_t flag) { return (WI_EnumValue(BellStyle()) & flag) == flag; diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h index 44df681665f..7770c1b2f3a 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.h @@ -58,11 +58,20 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation Padding(to_hstring(value)); } + winrt::hstring EvaluatedIcon() const + { + return _profile.EvaluatedIcon(); + } + // starting directory bool UseParentProcessDirectory(); void UseParentProcessDirectory(const bool useParent); bool UseCustomStartingDirectory(); + // icon + bool HideIcon(); + void HideIcon(const bool hide); + // general profile knowledge winrt::guid OriginalProfileGuid() const noexcept; bool CanDeleteProfile() const; @@ -119,6 +128,7 @@ namespace winrt::Microsoft::Terminal::Settings::Editor::implementation winrt::guid _originalProfileGuid{}; winrt::hstring _lastBgImagePath; winrt::hstring _lastStartingDirectoryPath; + winrt::hstring _lastIcon; Editor::AppearanceViewModel _defaultAppearanceViewModel; static Windows::Foundation::Collections::IObservableVector _MonospaceFontList; diff --git a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl index 5020ecb7945..f9f618c8b80 100644 --- a/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl +++ b/src/cascadia/TerminalSettingsEditor/ProfileViewModel.idl @@ -67,6 +67,7 @@ namespace Microsoft.Terminal.Settings.Editor ProfileSubPage CurrentPage; Boolean UseParentProcessDirectory; Boolean UseCustomStartingDirectory { get; }; + Boolean HideIcon; AppearanceViewModel DefaultAppearance { get; }; Guid OriginalProfileGuid { get; }; Boolean HasUnfocusedAppearance { get; }; @@ -75,6 +76,8 @@ namespace Microsoft.Terminal.Settings.Editor AppearanceViewModel UnfocusedAppearance { get; }; Boolean VtPassthroughAvailable { get; }; + String EvaluatedIcon { get; }; + void CreateUnfocusedAppearance(); void DeleteUnfocusedAppearance(); diff --git a/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml b/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml index 11885a52fe3..28f2901261f 100644 --- a/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml +++ b/src/cascadia/TerminalSettingsEditor/Profiles_Base.xaml @@ -108,13 +108,20 @@ + Text="{x:Bind Profile.Icon, Mode=TwoWay}" + Visibility="{x:Bind local:Converters.InvertedBooleanToVisibility(Profile.HideIcon), Mode=OneWay}" />