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,