Skip to content

Commit

Permalink
Add shield to tab row when elevated (#11224)
Browse files Browse the repository at this point in the history
## 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)
  • Loading branch information
zadjii-msft committed Sep 23, 2021
1 parent f04fd08 commit 171e0a0
Show file tree
Hide file tree
Showing 11 changed files with 64 additions and 14 deletions.
5 changes: 5 additions & 0 deletions doc/cascadia/profiles.schema.json
Expand Up @@ -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.",
Expand Down
3 changes: 3 additions & 0 deletions src/cascadia/TerminalApp/Resources/en-US/Resources.resw
Expand Up @@ -715,4 +715,7 @@
<data name="InfoBarDismissButton.Content" xml:space="preserve">
<value>Don't show again</value>
</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>
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TabRowControl.h
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "winrt/Microsoft.UI.Xaml.Controls.h"
#include "../../cascadia/inc/cppwinrt_utils.h"

#include "TabRowControl.g.h"

Expand All @@ -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);
};
}

Expand Down
4 changes: 3 additions & 1 deletion src/cascadia/TerminalApp/TabRowControl.idl
Expand Up @@ -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;
}
}
11 changes: 11 additions & 0 deletions src/cascadia/TerminalApp/TabRowControl.xaml
Expand Up @@ -20,6 +20,17 @@
IsAddTabButtonVisible="false"
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="&#xEA18;"
Visibility="{x:Bind ShowElevationShield, Mode=OneWay}" />
</mux:TabView.TabStripHeader>

<mux:TabView.TabStripFooter>
<mux:SplitButton x:Name="NewTabButton"
x:Uid="NewTabSplitButton"
Expand Down
41 changes: 28 additions & 13 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Expand Up @@ -118,6 +118,29 @@ namespace winrt::TerminalApp::implementation
_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()
{
// Hookup the key bindings
Expand All @@ -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())
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Expand Up @@ -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);

Expand Down
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp
Expand Up @@ -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" };

Expand Down Expand Up @@ -121,6 +122,8 @@ winrt::com_ptr<GlobalAppSettings> GlobalAppSettings::Copy() const
globals->_MinimizeToNotificationArea = _MinimizeToNotificationArea;
globals->_AlwaysShowNotificationIcon = _AlwaysShowNotificationIcon;
globals->_DisabledProfileSources = _DisabledProfileSources;
globals->_ShowAdminShield = _ShowAdminShield;

globals->_UnparsedDefaultProfile = _UnparsedDefaultProfile;

globals->_defaultProfile = _defaultProfile;
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/GlobalAppSettings.h
Expand Up @@ -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<winrt::hstring>, DisabledProfileSources, nullptr);
INHERITABLE_SETTING(Model::GlobalAppSettings, hstring, UnparsedDefaultProfile, L"");
INHERITABLE_SETTING(Model::GlobalAppSettings, bool, ShowAdminShield, true);

private:
#ifdef NDEBUG
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl
Expand Up @@ -84,6 +84,7 @@ namespace Microsoft.Terminal.Settings.Model
INHERITABLE_SETTING(Boolean, MinimizeToNotificationArea);
INHERITABLE_SETTING(Boolean, AlwaysShowNotificationIcon);
INHERITABLE_SETTING(IVector<String>, DisabledProfileSources);
INHERITABLE_SETTING(Boolean, ShowAdminShield);

Windows.Foundation.Collections.IMapView<String, ColorScheme> ColorSchemes();
void AddColorScheme(ColorScheme scheme);
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/defaults.json
Expand Up @@ -20,6 +20,7 @@
"showTerminalTitleInTitlebar": true,
"tabWidthMode": "equal",
"tabSwitcherMode": "inOrder",
"showAdminShield": true,

// Miscellaneous
"confirmCloseAllTabs": true,
Expand Down

0 comments on commit 171e0a0

Please sign in to comment.