mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-03 09:46:54 +02:00
Option to toggle the system tray icon (#23220)
* Added option to toggle the system tray icon At the moment, this hides the icon making the settings window inaccessible without first modifying the general `settings.json` file. * Use IPC messages to manage the tray icon settings * Fix launching second window binds to active settings process * Added context menu option to hide tray icon * Added Exit PT button to settings ui NavigationView.PaneFooter * Moved DllImports to NativeMethods.cs * Sentence case titles * Fix whitespace * Re-add exit icon to NavView * Re-added toggle switch to new UI * Fix build * Fix build after merge main * Fix the string to display * add shut down buttons * finish polish * fix string * Styling tweaks to titlebar and settingscards * fix comment * fix unit test * fix ut --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com> Co-authored-by: vanzue <vanzue@outlook.com> Co-authored-by: Kayla Cinnamon <cinnamon@microsoft.com> Co-authored-by: Niels Laute <niels.laute@live.nl>
This commit is contained in:
@@ -19,6 +19,10 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
[JsonPropertyName("startup")]
|
||||
public bool Startup { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether the powertoys system tray icon should be hidden.
|
||||
[JsonPropertyName("show_tray_icon")]
|
||||
public bool ShowSysTrayIcon { get; set; }
|
||||
|
||||
// Gets or sets a value indicating whether the powertoy elevated.
|
||||
[CmdConfigureIgnoreAttribute]
|
||||
[JsonPropertyName("is_elevated")]
|
||||
@@ -75,6 +79,7 @@ namespace Microsoft.PowerToys.Settings.UI.Library
|
||||
public GeneralSettings()
|
||||
{
|
||||
Startup = false;
|
||||
ShowSysTrayIcon = true;
|
||||
IsAdmin = false;
|
||||
EnableWarningsElevatedApps = true;
|
||||
IsElevated = false;
|
||||
|
||||
@@ -224,6 +224,36 @@ namespace ViewModelTests
|
||||
viewModel.ThemeIndex = 0;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsShowSysTrayIconEnabledByDefaultShouldDisableWhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
// Assert
|
||||
Func<string, int> sendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.IsFalse(snd.GeneralSettings.ShowSysTrayIcon);
|
||||
return 0;
|
||||
};
|
||||
|
||||
Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new(
|
||||
settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
sendMockIPCConfigMSG,
|
||||
sendRestartAdminIPCMessage,
|
||||
sendCheckForUpdatesIPCMessage,
|
||||
GeneralSettingsFileName);
|
||||
Assert.IsTrue(viewModel.ShowSysTrayIcon);
|
||||
|
||||
// Act
|
||||
viewModel.ShowSysTrayIcon = false;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void AllModulesAreEnabledByDefault()
|
||||
{
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
internal const int SW_SHOWNORMAL = 1;
|
||||
internal const int SW_SHOWMAXIMIZED = 3;
|
||||
internal const int SW_HIDE = 0;
|
||||
internal const int WM_COMMAND = 0x0111; // https://learn.microsoft.com/en-us/windows/win32/menurc/wm-command
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr GetActiveWindow();
|
||||
@@ -48,6 +49,12 @@ namespace Microsoft.PowerToys.Settings.UI.Helpers
|
||||
[DllImport("Comdlg32.dll", CharSet = CharSet.Unicode)]
|
||||
internal static extern bool GetOpenFileName([In, Out] OpenFileName openFileName);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
internal static extern IntPtr SendMessage(IntPtr hWnd, IntPtr msg, UIntPtr wParam, UIntPtr lParam);
|
||||
|
||||
[DllImport("comdlg32.dll", CharSet = CharSet.Auto, EntryPoint = "ChooseFont", SetLastError = true)]
|
||||
internal static extern bool ChooseFont(IntPtr lpChooseFont);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
<tkconverters:StringFormatConverter x:Key="StringFormatConverter" />
|
||||
<tkconverters:BoolNegationConverter x:Key="BoolNegationConverter" />
|
||||
<x:Double x:Key="SettingsCardSpacing">2</x:Double>
|
||||
|
||||
<!-- Overrides -->
|
||||
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<StackPanel
|
||||
ChildrenTransitions="{StaticResource SettingsCardsAnimations}"
|
||||
Orientation="Vertical"
|
||||
Spacing="2" />
|
||||
Spacing="{StaticResource SettingsCardSpacing}" />
|
||||
</ItemsPanelTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
|
||||
@@ -176,7 +176,7 @@ namespace Microsoft.PowerToys.Settings.UI.Flyout
|
||||
});
|
||||
}
|
||||
|
||||
private void ReportBugBtn_Click(object sender, RoutedEventArgs e)
|
||||
internal void ReportBugBtn_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ViewModel.StartBugReport();
|
||||
|
||||
|
||||
@@ -266,6 +266,10 @@
|
||||
<tkcontrols:SettingsCard x:Uid="GeneralPage_RunAtStartUp" IsEnabled="{x:Bind ViewModel.IsRunAtStartupGPOManaged, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
|
||||
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.Startup, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
|
||||
<tkcontrols:SettingsCard x:Uid="ShowSystemTrayIcon">
|
||||
<ToggleSwitch x:Uid="ShowSystemTrayIcon_ToggleSwitch" IsOn="{x:Bind ViewModel.ShowSysTrayIcon, Mode=TwoWay}" />
|
||||
</tkcontrols:SettingsCard>
|
||||
<InfoBar
|
||||
x:Uid="GPO_SettingIsManaged"
|
||||
BorderThickness="0"
|
||||
@@ -402,10 +406,11 @@
|
||||
</InfoBar>
|
||||
</controls:SettingsGroup>
|
||||
<controls:SettingsGroup x:Uid="General_DiagnosticsAndFeedback" Visibility="Visible">
|
||||
<StackPanel>
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<HyperlinkButton
|
||||
x:Uid="GeneralPage_DiagnosticsAndFeedback_Link"
|
||||
Margin="-8,0,0,0"
|
||||
Margin="0,0,0,8"
|
||||
Padding="0"
|
||||
NavigateUri="https://aka.ms/powertoys-data-and-privacy-documentation" />
|
||||
<tkcontrols:SettingsCard
|
||||
x:Uid="GeneralPage_EnableDataDiagnostics"
|
||||
@@ -449,7 +454,12 @@
|
||||
<Button x:Uid="GeneralPage_ViewDiagnosticDataViewerInfoButton" Click="Click_ViewDiagnosticDataViewerRestart" />
|
||||
</InfoBar.ActionButton>
|
||||
</InfoBar>
|
||||
|
||||
<tkcontrols:SettingsCard x:Uid="GeneralPage_ReportBugPackage" HeaderIcon="{ui:FontIcon Glyph=}">
|
||||
<Button
|
||||
x:Uid="GeneralPageReportBugPackage"
|
||||
HorizontalAlignment="Right"
|
||||
Click="BugReportToolClicked" />
|
||||
</tkcontrols:SettingsCard>
|
||||
</StackPanel>
|
||||
</controls:SettingsGroup>
|
||||
</StackPanel>
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Flyout;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Library;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
@@ -165,5 +166,24 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
await Task.Run(ViewModel.ViewDiagnosticData);
|
||||
}
|
||||
|
||||
private void ExitPTItem_Tapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
const string ptTrayIconWindowClass = "PToyTrayIconWindow"; // Defined in runner/tray_icon.h
|
||||
const nuint ID_EXIT_MENU_COMMAND = 40001; // Generated resource from runner/runner.base.rc
|
||||
|
||||
// Exit the XAML application
|
||||
Application.Current.Exit();
|
||||
|
||||
// Invoke the exit command from the tray icon
|
||||
IntPtr hWnd = NativeMethods.FindWindow(ptTrayIconWindowClass, ptTrayIconWindowClass);
|
||||
NativeMethods.SendMessage(hWnd, NativeMethods.WM_COMMAND, ID_EXIT_MENU_COMMAND, 0);
|
||||
}
|
||||
|
||||
private void BugReportToolClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var launchPage = new LaunchPage();
|
||||
launchPage.ReportBugBtn_Click(sender, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,10 +39,17 @@
|
||||
Margin="48,0,0,0"
|
||||
VerticalAlignment="Top"
|
||||
IsHitTestVisible="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition x:Name="LeftTitleBarColumn" Width="*" />
|
||||
<ColumnDefinition x:Name="RightTitleBarColumn" Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<animations:Implicit.Animations>
|
||||
<animations:OffsetAnimation Duration="0:0:0.3" />
|
||||
</animations:Implicit.Animations>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Left"
|
||||
Orientation="Horizontal">
|
||||
<Image
|
||||
Width="16"
|
||||
Height="16"
|
||||
@@ -64,6 +71,24 @@
|
||||
TextWrapping="NoWrap"
|
||||
Visibility="Collapsed" />
|
||||
</StackPanel>
|
||||
<StackPanel
|
||||
Grid.Column="1"
|
||||
Margin="0,0,148,0"
|
||||
HorizontalAlignment="Right"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="ShutDownBtn"
|
||||
Height="48"
|
||||
Click="ExitPTItem_Tapped"
|
||||
Style="{StaticResource SubtleButtonStyle}">
|
||||
<FontIcon FontSize="16" Glyph="" />
|
||||
<ToolTipService.ToolTip>
|
||||
<ToolTip>
|
||||
<TextBlock x:Uid="AppTitleBarShutDown_Tooltip" />
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<NavigationView
|
||||
x:Name="navigationView"
|
||||
|
||||
@@ -9,6 +9,7 @@ using ManagedCommon;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Services;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Automation.Peers;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
@@ -422,6 +423,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
// A custom title bar is required for full window theme and Mica support.
|
||||
// https://docs.microsoft.com/windows/apps/develop/title-bar?tabs=winui3#full-customization
|
||||
u.ExtendsContentIntoTitleBar = true;
|
||||
u.AppWindow.TitleBar.PreferredHeightOption = TitleBarHeightOption.Tall;
|
||||
WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(u));
|
||||
u.SetTitleBar(AppTitleBar);
|
||||
var loader = ResourceLoaderInstance.ResourceLoader;
|
||||
@@ -457,5 +459,18 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
{
|
||||
navigationView.IsPaneOpen = !navigationView.IsPaneOpen;
|
||||
}
|
||||
|
||||
private void ExitPTItem_Tapped(object sender, RoutedEventArgs e)
|
||||
{
|
||||
const string ptTrayIconWindowClass = "PToyTrayIconWindow"; // Defined in runner/tray_icon.h
|
||||
const nuint ID_EXIT_MENU_COMMAND = 40001; // Generated resource from runner/runner.base.rc
|
||||
|
||||
// Exit the XAML application
|
||||
Application.Current.Exit();
|
||||
|
||||
// Invoke the exit command from the tray icon
|
||||
IntPtr hWnd = NativeMethods.FindWindow(ptTrayIconWindowClass, ptTrayIconWindowClass);
|
||||
NativeMethods.SendMessage(hWnd, NativeMethods.WM_COMMAND, ID_EXIT_MENU_COMMAND, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4299,6 +4299,12 @@ Activate by holding the key for the character you want to add an accent to, then
|
||||
<data name="GeneralPage_ShowWhatsNewAfterUpdates.Content" xml:space="preserve">
|
||||
<value>Show the release notes after an update</value>
|
||||
</data>
|
||||
<data name="ShowSystemTrayIcon.Description" xml:space="preserve">
|
||||
<value>This settings page is accessible by running the PowerToys executable again</value>
|
||||
</data>
|
||||
<data name="ShowSystemTrayIcon.Header" xml:space="preserve">
|
||||
<value>Show system tray icon</value>
|
||||
</data>
|
||||
<data name="QuickAccent_Prevent_Activation_On_Game_Mode.Content" xml:space="preserve">
|
||||
<value>Do not activate when Game Mode is on</value>
|
||||
<comment>"Game mode" is the Windows feature to prevent notification when playing a game.</comment>
|
||||
@@ -5020,4 +5026,25 @@ To record a specific window, enter the hotkey with the Alt key in the opposite m
|
||||
<data name="Help_hueOklch" xml:space="preserve">
|
||||
<value>hue (Oklch)</value>
|
||||
</data>
|
||||
<data name="ExitPT_NavViewItem.Content" xml:space="preserve">
|
||||
<value>Exit PowerToys</value>
|
||||
</data>
|
||||
<data name="General_System.Header" xml:space="preserve">
|
||||
<value>System</value>
|
||||
</data>
|
||||
<data name="GeneralPage_ReportBugPackage.Header" xml:space="preserve">
|
||||
<value>Generate bug report package</value>
|
||||
</data>
|
||||
<data name="GeneralPage_ReportBugPackage.Description" xml:space="preserve">
|
||||
<value>Create zip folder with logs on the Desktop</value>
|
||||
</data>
|
||||
<data name="GeneralPageReportBugPackage.Content" xml:space="preserve">
|
||||
<value>Generate package</value>
|
||||
</data>
|
||||
<data name="AppTitleBarShutDown_Tooltip.Text" xml:space="preserve">
|
||||
<value>Shut down</value>
|
||||
</data>
|
||||
<data name="BugReportUnderConstruction" xml:space="preserve">
|
||||
<value>Bug report package is being created</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -146,6 +146,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_startup = GeneralSettingsConfig.Startup;
|
||||
}
|
||||
|
||||
_showSysTrayIcon = GeneralSettingsConfig.ShowSysTrayIcon;
|
||||
_showNewUpdatesToastNotification = GeneralSettingsConfig.ShowNewUpdatesToastNotification;
|
||||
_autoDownloadUpdates = GeneralSettingsConfig.AutoDownloadUpdates;
|
||||
_showWhatsNewAfterUpdates = GeneralSettingsConfig.ShowWhatsNewAfterUpdates;
|
||||
@@ -228,6 +229,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
private static bool _isDevBuild;
|
||||
private bool _startup;
|
||||
private bool _showSysTrayIcon;
|
||||
private GpoRuleConfigured _runAtStartupGpoRuleConfiguration;
|
||||
private bool _runAtStartupIsGPOConfigured;
|
||||
private bool _isElevated;
|
||||
@@ -359,6 +361,25 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
// Gets or sets a value indicating whether the PowerToys icon should be shown in the system tray.
|
||||
public bool ShowSysTrayIcon
|
||||
{
|
||||
get
|
||||
{
|
||||
return _showSysTrayIcon;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (_showSysTrayIcon != value)
|
||||
{
|
||||
_showSysTrayIcon = value;
|
||||
GeneralSettingsConfig.ShowSysTrayIcon = value;
|
||||
NotifyPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string RunningAsText
|
||||
{
|
||||
get
|
||||
|
||||
Reference in New Issue
Block a user