diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index 319e0bae7a8..ad827c79c1b 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -1274,6 +1274,11 @@ "description": "When set to true, the Terminal's notification icon will always be shown in the notification area.", "type": "boolean" }, + "showAdminShield": { + "default": "true", + "description": "When set to true, the Terminal's tab row will display a shield icon when the Terminal is running with administrator privileges", + "type": "boolean" + }, "useAcrylicInTabRow": { "default": "false", "description": "When set to true, the tab row will have an acrylic background with 50% opacity.", diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw index 86b0b407f63..421816f5849 100644 --- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw @@ -715,4 +715,7 @@ Don't show again + + This Terminal window is running as Admin + diff --git a/src/cascadia/TerminalApp/TabRowControl.h b/src/cascadia/TerminalApp/TabRowControl.h index 6ffa605320b..1e4bd573f46 100644 --- a/src/cascadia/TerminalApp/TabRowControl.h +++ b/src/cascadia/TerminalApp/TabRowControl.h @@ -4,6 +4,7 @@ #pragma once #include "winrt/Microsoft.UI.Xaml.Controls.h" +#include "../../cascadia/inc/cppwinrt_utils.h" #include "TabRowControl.g.h" @@ -16,6 +17,9 @@ namespace winrt::TerminalApp::implementation void OnNewTabButtonClick(Windows::Foundation::IInspectable const& sender, Microsoft::UI::Xaml::Controls::SplitButtonClickEventArgs const& args); void OnNewTabButtonDrop(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::DragEventArgs const& e); void OnNewTabButtonDragOver(winrt::Windows::Foundation::IInspectable const& sender, winrt::Windows::UI::Xaml::DragEventArgs const& e); + + WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); + WINRT_OBSERVABLE_PROPERTY(bool, ShowElevationShield, _PropertyChangedHandlers, false); }; } diff --git a/src/cascadia/TerminalApp/TabRowControl.idl b/src/cascadia/TerminalApp/TabRowControl.idl index 1415df9a255..4dd1d37bd97 100644 --- a/src/cascadia/TerminalApp/TabRowControl.idl +++ b/src/cascadia/TerminalApp/TabRowControl.idl @@ -3,9 +3,11 @@ namespace TerminalApp { - [default_interface] runtimeclass TabRowControl : Windows.UI.Xaml.Controls.ContentPresenter + [default_interface] runtimeclass TabRowControl : Windows.UI.Xaml.Controls.ContentPresenter, + Windows.UI.Xaml.Data.INotifyPropertyChanged { TabRowControl(); Microsoft.UI.Xaml.Controls.TabView TabView { get; }; + Boolean ShowElevationShield; } } diff --git a/src/cascadia/TerminalApp/TabRowControl.xaml b/src/cascadia/TerminalApp/TabRowControl.xaml index 802e7c529cc..b3b0f58c332 100644 --- a/src/cascadia/TerminalApp/TabRowControl.xaml +++ b/src/cascadia/TerminalApp/TabRowControl.xaml @@ -20,6 +20,17 @@ IsAddTabButtonVisible="false" TabWidthMode="Equal"> + + + + + ().Logic().IsElevated(); + } + CATCH_LOG(); + return result; + }(); + + return isElevated; + } + void TerminalPage::Create() { // Hookup the key bindings @@ -128,19 +151,7 @@ namespace winrt::TerminalApp::implementation _tabView = _tabRow.TabView(); _rearranging = false; - // GH#2455 - Make sure to try/catch calls to Application::Current, - // because that _won't_ be an instance of TerminalApp::App in the - // LocalTests - auto isElevated = false; - try - { - // GH#3581 - There's a platform limitation that causes us to crash when we rearrange tabs. - // Xaml tries to send a drag visual (to wit: a screenshot) to the drag hosting process, - // but that process is running at a different IL than us. - // For now, we're disabling elevated drag. - isElevated = ::winrt::Windows::UI::Xaml::Application::Current().as<::winrt::TerminalApp::App>().Logic().IsElevated(); - } - CATCH_LOG(); + const auto isElevated = IsElevated(); if (_settings.GlobalSettings().UseAcrylicInTabRow()) { @@ -267,6 +278,8 @@ namespace winrt::TerminalApp::implementation // Setup mouse vanish attributes SystemParametersInfoW(SPI_GETMOUSEVANISH, 0, &_shouldMouseVanish, false); + _tabRow.ShowElevationShield(IsElevated() && _settings.GlobalSettings().ShowAdminShield()); + // Store cursor, so we can restore it, e.g., after mouse vanishing // (we'll need to adapt this logic once we make cursor context aware) try @@ -2242,6 +2255,8 @@ namespace winrt::TerminalApp::implementation // 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()); + + _tabRow.ShowElevationShield(IsElevated() && _settings.GlobalSettings().ShowAdminShield()); } // This is a helper to aid in sorting commands by their `Name`s, alphabetically. diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 7302cf6ed92..a9ff78959ab 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -115,6 +115,7 @@ namespace winrt::TerminalApp::implementation winrt::hstring WindowIdForDisplay() const noexcept; winrt::hstring WindowNameForDisplay() const noexcept; bool IsQuakeWindow() const noexcept; + bool IsElevated() const noexcept; WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler); diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp index 4a8860e3ddc..53c0fd90f7a 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp @@ -51,6 +51,7 @@ static constexpr std::string_view TrimBlockSelectionKey{ "trimBlockSelection" }; static constexpr std::string_view AlwaysShowNotificationIconKey{ "alwaysShowNotificationIcon" }; static constexpr std::string_view MinimizeToNotificationAreaKey{ "minimizeToNotificationArea" }; static constexpr std::string_view DisabledProfileSourcesKey{ "disabledProfileSources" }; +static constexpr std::string_view ShowAdminShieldKey{ "showAdminShield" }; static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" }; @@ -121,6 +122,8 @@ winrt::com_ptr GlobalAppSettings::Copy() const globals->_MinimizeToNotificationArea = _MinimizeToNotificationArea; globals->_AlwaysShowNotificationIcon = _AlwaysShowNotificationIcon; globals->_DisabledProfileSources = _DisabledProfileSources; + globals->_ShowAdminShield = _ShowAdminShield; + globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile; globals->_defaultProfile = _defaultProfile; @@ -227,6 +230,8 @@ void GlobalAppSettings::LayerJson(const Json::Value& json) JsonUtils::GetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon); JsonUtils::GetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources); + JsonUtils::GetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield); + static constexpr std::array bindingsKeys{ LegacyKeybindingsKey, ActionsKey }; for (const auto& jsonKey : bindingsKeys) { @@ -324,6 +329,7 @@ Json::Value GlobalAppSettings::ToJson() const JsonUtils::SetValueForKey(json, MinimizeToNotificationAreaKey, _MinimizeToNotificationArea); JsonUtils::SetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon); JsonUtils::SetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources); + JsonUtils::SetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield); // clang-format on json[JsonKey(ActionsKey)] = _actionMap->ToJson(); diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h index 87d87445dd5..32f73cafec1 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.h @@ -99,6 +99,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowNotificationIcon, false); INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Windows::Foundation::Collections::IVector, DisabledProfileSources, nullptr); INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L""); + INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowAdminShield, true); private: #ifdef NDEBUG diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl index ea1d7de79ef..66b2125df8e 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl @@ -84,6 +84,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea); INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon); INHERITABLE_SETTING(IVector, DisabledProfileSources); + INHERITABLE_SETTING(Boolean, ShowAdminShield); Windows.Foundation.Collections.IMapView ColorSchemes(); void AddColorScheme(ColorScheme scheme); diff --git a/src/cascadia/TerminalSettingsModel/defaults.json b/src/cascadia/TerminalSettingsModel/defaults.json index 6261e743a93..d6b45016f50 100644 --- a/src/cascadia/TerminalSettingsModel/defaults.json +++ b/src/cascadia/TerminalSettingsModel/defaults.json @@ -20,6 +20,7 @@ "showTerminalTitleInTitlebar": true, "tabWidthMode": "equal", "tabSwitcherMode": "inOrder", + "showAdminShield": true, // Miscellaneous "confirmCloseAllTabs": true,