Add shield to tab row when elevated (#11224)
## Summary of the Pull Request Adds a visible indicator that a Terminal window is elevated. This icon can be disabled with `"showAdminShield" false` in the global settings. ## References * spec'd in #8455 * Also in https://github.com/microsoft/terminal/projects/5 * big picture: #5000 ## PR Checklist * [x] Closes #1939 * [x] I work here * [n/a] Tests added/passed * [ ] Requires documentation to be updated - yea probably ## Validation Steps Performed ![image](https://user-images.githubusercontent.com/18356694/133293009-4215e319-fbf9-4ca8-8af5-afe2fa8bb62d.png) ![image](https://user-images.githubusercontent.com/18356694/133292970-90cb17fd-16c7-429a-a25f-8457850eb278.png)
This commit is contained in:
parent
f04fd089fe
commit
171e0a0242
|
@ -1274,6 +1274,11 @@
|
||||||
"description": "When set to true, the Terminal's notification icon will always be shown in the notification area.",
|
"description": "When set to true, the Terminal's notification icon will always be shown in the notification area.",
|
||||||
"type": "boolean"
|
"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": {
|
"useAcrylicInTabRow": {
|
||||||
"default": "false",
|
"default": "false",
|
||||||
"description": "When set to true, the tab row will have an acrylic background with 50% opacity.",
|
"description": "When set to true, the tab row will have an acrylic background with 50% opacity.",
|
||||||
|
|
|
@ -715,4 +715,7 @@
|
||||||
<data name="InfoBarDismissButton.Content" xml:space="preserve">
|
<data name="InfoBarDismissButton.Content" xml:space="preserve">
|
||||||
<value>Don't show again</value>
|
<value>Don't show again</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ElevationShield.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
|
||||||
|
<value>This Terminal window is running as Admin</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "winrt/Microsoft.UI.Xaml.Controls.h"
|
#include "winrt/Microsoft.UI.Xaml.Controls.h"
|
||||||
|
#include "../../cascadia/inc/cppwinrt_utils.h"
|
||||||
|
|
||||||
#include "TabRowControl.g.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 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 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);
|
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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
|
|
||||||
namespace TerminalApp
|
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();
|
TabRowControl();
|
||||||
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
Microsoft.UI.Xaml.Controls.TabView TabView { get; };
|
||||||
|
Boolean ShowElevationShield;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,17 @@
|
||||||
IsAddTabButtonVisible="false"
|
IsAddTabButtonVisible="false"
|
||||||
TabWidthMode="Equal">
|
TabWidthMode="Equal">
|
||||||
|
|
||||||
|
<mux:TabView.TabStripHeader>
|
||||||
|
<!-- EA18 is the "Shield" glyph -->
|
||||||
|
<FontIcon x:Uid="ElevationShield"
|
||||||
|
Margin="9,4,0,0"
|
||||||
|
FontFamily="Segoe MDL2 Assets"
|
||||||
|
FontSize="16"
|
||||||
|
Foreground="{ThemeResource SystemControlForegroundBaseMediumBrush}"
|
||||||
|
Glyph=""
|
||||||
|
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
|
||||||
|
</mux:TabView.TabStripHeader>
|
||||||
|
|
||||||
<mux:TabView.TabStripFooter>
|
<mux:TabView.TabStripFooter>
|
||||||
<mux:SplitButton x:Name="NewTabButton"
|
<mux:SplitButton x:Name="NewTabButton"
|
||||||
x:Uid="NewTabSplitButton"
|
x:Uid="NewTabSplitButton"
|
||||||
|
|
|
@ -118,6 +118,29 @@ namespace winrt::TerminalApp::implementation
|
||||||
_systemRowsToScroll = _ReadSystemRowsToScroll();
|
_systemRowsToScroll = _ReadSystemRowsToScroll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TerminalPage::IsElevated() const noexcept
|
||||||
|
{
|
||||||
|
// use C++11 magic statics to make sure we only do this once.
|
||||||
|
// This won't change over the lifetime of the application
|
||||||
|
|
||||||
|
static const bool isElevated = []() {
|
||||||
|
// *** THIS IS A SINGLETON ***
|
||||||
|
auto result = 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
|
||||||
|
try
|
||||||
|
{
|
||||||
|
result = ::winrt::Windows::UI::Xaml::Application::Current().as<::winrt::TerminalApp::App>().Logic().IsElevated();
|
||||||
|
}
|
||||||
|
CATCH_LOG();
|
||||||
|
return result;
|
||||||
|
}();
|
||||||
|
|
||||||
|
return isElevated;
|
||||||
|
}
|
||||||
|
|
||||||
void TerminalPage::Create()
|
void TerminalPage::Create()
|
||||||
{
|
{
|
||||||
// Hookup the key bindings
|
// Hookup the key bindings
|
||||||
|
@ -128,19 +151,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
_tabView = _tabRow.TabView();
|
_tabView = _tabRow.TabView();
|
||||||
_rearranging = false;
|
_rearranging = false;
|
||||||
|
|
||||||
// GH#2455 - Make sure to try/catch calls to Application::Current,
|
const auto isElevated = IsElevated();
|
||||||
// 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();
|
|
||||||
|
|
||||||
if (_settings.GlobalSettings().UseAcrylicInTabRow())
|
if (_settings.GlobalSettings().UseAcrylicInTabRow())
|
||||||
{
|
{
|
||||||
|
@ -267,6 +278,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
// Setup mouse vanish attributes
|
// Setup mouse vanish attributes
|
||||||
SystemParametersInfoW(SPI_GETMOUSEVANISH, 0, &_shouldMouseVanish, false);
|
SystemParametersInfoW(SPI_GETMOUSEVANISH, 0, &_shouldMouseVanish, false);
|
||||||
|
|
||||||
|
_tabRow.ShowElevationShield(IsElevated() && _settings.GlobalSettings().ShowAdminShield());
|
||||||
|
|
||||||
// Store cursor, so we can restore it, e.g., after mouse vanishing
|
// 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)
|
// (we'll need to adapt this logic once we make cursor context aware)
|
||||||
try
|
try
|
||||||
|
@ -2242,6 +2255,8 @@ namespace winrt::TerminalApp::implementation
|
||||||
// enabled application-wide, so we don't need to check it each time we
|
// enabled application-wide, so we don't need to check it each time we
|
||||||
// want to create an animation.
|
// want to create an animation.
|
||||||
WUX::Media::Animation::Timeline::AllowDependentAnimations(!_settings.GlobalSettings().DisableAnimations());
|
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.
|
// This is a helper to aid in sorting commands by their `Name`s, alphabetically.
|
||||||
|
|
|
@ -115,6 +115,7 @@ namespace winrt::TerminalApp::implementation
|
||||||
winrt::hstring WindowIdForDisplay() const noexcept;
|
winrt::hstring WindowIdForDisplay() const noexcept;
|
||||||
winrt::hstring WindowNameForDisplay() const noexcept;
|
winrt::hstring WindowNameForDisplay() const noexcept;
|
||||||
bool IsQuakeWindow() const noexcept;
|
bool IsQuakeWindow() const noexcept;
|
||||||
|
bool IsElevated() const noexcept;
|
||||||
|
|
||||||
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
WINRT_CALLBACK(PropertyChanged, Windows::UI::Xaml::Data::PropertyChangedEventHandler);
|
||||||
|
|
||||||
|
|
|
@ -51,6 +51,7 @@ static constexpr std::string_view TrimBlockSelectionKey{ "trimBlockSelection" };
|
||||||
static constexpr std::string_view AlwaysShowNotificationIconKey{ "alwaysShowNotificationIcon" };
|
static constexpr std::string_view AlwaysShowNotificationIconKey{ "alwaysShowNotificationIcon" };
|
||||||
static constexpr std::string_view MinimizeToNotificationAreaKey{ "minimizeToNotificationArea" };
|
static constexpr std::string_view MinimizeToNotificationAreaKey{ "minimizeToNotificationArea" };
|
||||||
static constexpr std::string_view DisabledProfileSourcesKey{ "disabledProfileSources" };
|
static constexpr std::string_view DisabledProfileSourcesKey{ "disabledProfileSources" };
|
||||||
|
static constexpr std::string_view ShowAdminShieldKey{ "showAdminShield" };
|
||||||
|
|
||||||
static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" };
|
static constexpr std::string_view DebugFeaturesKey{ "debugFeatures" };
|
||||||
|
|
||||||
|
@ -121,6 +122,8 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
|
||||||
globals->_MinimizeToNotificationArea = _MinimizeToNotificationArea;
|
globals->_MinimizeToNotificationArea = _MinimizeToNotificationArea;
|
||||||
globals->_AlwaysShowNotificationIcon = _AlwaysShowNotificationIcon;
|
globals->_AlwaysShowNotificationIcon = _AlwaysShowNotificationIcon;
|
||||||
globals->_DisabledProfileSources = _DisabledProfileSources;
|
globals->_DisabledProfileSources = _DisabledProfileSources;
|
||||||
|
globals->_ShowAdminShield = _ShowAdminShield;
|
||||||
|
|
||||||
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;
|
||||||
|
|
||||||
globals->_defaultProfile = _defaultProfile;
|
globals->_defaultProfile = _defaultProfile;
|
||||||
|
@ -227,6 +230,8 @@ void GlobalAppSettings::LayerJson(const Json::Value& json)
|
||||||
JsonUtils::GetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
|
JsonUtils::GetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
|
||||||
JsonUtils::GetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
|
JsonUtils::GetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
|
||||||
|
|
||||||
|
JsonUtils::GetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield);
|
||||||
|
|
||||||
static constexpr std::array bindingsKeys{ LegacyKeybindingsKey, ActionsKey };
|
static constexpr std::array bindingsKeys{ LegacyKeybindingsKey, ActionsKey };
|
||||||
for (const auto& jsonKey : bindingsKeys)
|
for (const auto& jsonKey : bindingsKeys)
|
||||||
{
|
{
|
||||||
|
@ -324,6 +329,7 @@ Json::Value GlobalAppSettings::ToJson() const
|
||||||
JsonUtils::SetValueForKey(json, MinimizeToNotificationAreaKey, _MinimizeToNotificationArea);
|
JsonUtils::SetValueForKey(json, MinimizeToNotificationAreaKey, _MinimizeToNotificationArea);
|
||||||
JsonUtils::SetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
|
JsonUtils::SetValueForKey(json, AlwaysShowNotificationIconKey, _AlwaysShowNotificationIcon);
|
||||||
JsonUtils::SetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
|
JsonUtils::SetValueForKey(json, DisabledProfileSourcesKey, _DisabledProfileSources);
|
||||||
|
JsonUtils::SetValueForKey(json, ShowAdminShieldKey, _ShowAdminShield);
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
json[JsonKey(ActionsKey)] = _actionMap->ToJson();
|
json[JsonKey(ActionsKey)] = _actionMap->ToJson();
|
||||||
|
|
|
@ -99,6 +99,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||||
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowNotificationIcon, false);
|
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, AlwaysShowNotificationIcon, false);
|
||||||
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, nullptr);
|
INHERITABLE_SETTING(Model::GlobalAppSettings, winrt::Windows::Foundation::Collections::IVector<winrt::hstring>, DisabledProfileSources, nullptr);
|
||||||
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
|
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
|
||||||
|
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowAdminShield, true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
|
|
|
@ -84,6 +84,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||||
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
|
||||||
INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon);
|
INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon);
|
||||||
INHERITABLE_SETTING(IVector<String>, DisabledProfileSources);
|
INHERITABLE_SETTING(IVector<String>, DisabledProfileSources);
|
||||||
|
INHERITABLE_SETTING(Boolean, ShowAdminShield);
|
||||||
|
|
||||||
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
|
||||||
void AddColorScheme(ColorScheme scheme);
|
void AddColorScheme(ColorScheme scheme);
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
"showTerminalTitleInTitlebar": true,
|
"showTerminalTitleInTitlebar": true,
|
||||||
"tabWidthMode": "equal",
|
"tabWidthMode": "equal",
|
||||||
"tabSwitcherMode": "inOrder",
|
"tabSwitcherMode": "inOrder",
|
||||||
|
"showAdminShield": true,
|
||||||
|
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
"confirmCloseAllTabs": true,
|
"confirmCloseAllTabs": true,
|
||||||
|
|
Loading…
Reference in a new issue