From 7574ad4ad66f9418ef890837904abbfdaae9ebbd Mon Sep 17 00:00:00 2001 From: RobertBeekman Date: Tue, 27 Oct 2026 20:29:08 +0100 Subject: [PATCH] UI - Add a monochrome tray icon option - New "Monochrome tray icon" toggle under General settings - Shows a black or white icon matching the light or dark mode of the system tray - On Windows the color follows the taskbar (Windows mode), which can differ from the app mode - On Linux the color follows the system's light or dark mode - On macOS the icon is a template icon, so the menu bar colors it itself - Icons come in 16 to 256px, including the sizes used for high-DPI tray scaling Based on the idea and work in #867 by ArthurGamerHD. --- src/Artemis.UI.Linux/App.axaml | 2 +- src/Artemis.UI.MacOS/App.axaml | 2 +- src/Artemis.UI.Windows/App.axaml | 2 +- .../DryIoc/ContainerExtensions.cs | 2 + .../Providers/WindowsTrayThemeProvider.cs | 49 ++++++++++++++++++ .../Logo/application-monochrome-black.ico | Bin 0 -> 117419 bytes .../Logo/application-monochrome-white.ico | Bin 0 -> 118150 bytes src/Artemis.UI/DryIoc/ContainerExtensions.cs | 2 + src/Artemis.UI/Screens/Root/RootViewModel.cs | 42 +++++++++++++++ .../Settings/Tabs/GeneralTabView.axaml | 13 +++++ .../Settings/Tabs/GeneralTabViewModel.cs | 1 + .../Services/Tray/BasicTrayThemeProvider.cs | 26 ++++++++++ .../Services/Tray/ITrayThemeProvider.cs | 19 +++++++ 13 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 src/Artemis.UI.Windows/Providers/WindowsTrayThemeProvider.cs create mode 100644 src/Artemis.UI/Assets/Images/Logo/application-monochrome-black.ico create mode 100644 src/Artemis.UI/Assets/Images/Logo/application-monochrome-white.ico create mode 100644 src/Artemis.UI/Services/Tray/BasicTrayThemeProvider.cs create mode 100644 src/Artemis.UI/Services/Tray/ITrayThemeProvider.cs diff --git a/src/Artemis.UI.Linux/App.axaml b/src/Artemis.UI.Linux/App.axaml index d2109667a..94a041f7a 100644 --- a/src/Artemis.UI.Linux/App.axaml +++ b/src/Artemis.UI.Linux/App.axaml @@ -14,7 +14,7 @@ - + diff --git a/src/Artemis.UI.MacOS/App.axaml b/src/Artemis.UI.MacOS/App.axaml index 5a000915e..9ea5abac2 100644 --- a/src/Artemis.UI.MacOS/App.axaml +++ b/src/Artemis.UI.MacOS/App.axaml @@ -14,7 +14,7 @@ - + diff --git a/src/Artemis.UI.Windows/App.axaml b/src/Artemis.UI.Windows/App.axaml index 63ff0b8a1..f35f8ffde 100644 --- a/src/Artemis.UI.Windows/App.axaml +++ b/src/Artemis.UI.Windows/App.axaml @@ -14,7 +14,7 @@ - + diff --git a/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs b/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs index a2906d46c..2e8b4f424 100644 --- a/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.UI.Windows/DryIoc/ContainerExtensions.cs @@ -1,5 +1,6 @@ using Artemis.Core.Providers; using Artemis.Core.Services; +using Artemis.UI.Services.Tray; using Artemis.UI.Services.Updating; using Artemis.UI.Shared.Providers; using Artemis.UI.Windows.Providers; @@ -25,5 +26,6 @@ public static class UIContainerExtensions container.Register(serviceKey: WindowsInputProvider.Id); container.Register(); container.Register(); + container.Register(Reuse.Singleton); } } \ No newline at end of file diff --git a/src/Artemis.UI.Windows/Providers/WindowsTrayThemeProvider.cs b/src/Artemis.UI.Windows/Providers/WindowsTrayThemeProvider.cs new file mode 100644 index 000000000..b525b3832 --- /dev/null +++ b/src/Artemis.UI.Windows/Providers/WindowsTrayThemeProvider.cs @@ -0,0 +1,49 @@ +using System; +using Artemis.UI.Services.Tray; +using Microsoft.Win32; +using Serilog; + +namespace Artemis.UI.Windows.Providers; + +/// +/// Provides the light or dark mode of the Windows taskbar, which can differ from the app mode Avalonia reports. +/// +public class WindowsTrayThemeProvider : ITrayThemeProvider +{ + private const string PersonalizeKey = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; + + /// + /// Initializes a new instance of the class. + /// + public WindowsTrayThemeProvider(ILogger logger) + { + try + { + SystemEvents.UserPreferenceChanged += SystemEventsOnUserPreferenceChanged; + } + catch (Exception e) + { + logger.Warning(e, "Could not subscribe to system events, the tray icon won't follow changes to the taskbar color"); + } + } + + /// + public bool IsTrayDark + { + get + { + // Versions of Windows without the setting only have a dark taskbar + using RegistryKey? key = Registry.CurrentUser.OpenSubKey(PersonalizeKey); + return key?.GetValue("SystemUsesLightTheme") is not 1; + } + } + + /// + public event EventHandler? TrayThemeChanged; + + private void SystemEventsOnUserPreferenceChanged(object sender, UserPreferenceChangedEventArgs e) + { + if (e.Category == UserPreferenceCategory.General) + TrayThemeChanged?.Invoke(this, EventArgs.Empty); + } +} diff --git a/src/Artemis.UI/Assets/Images/Logo/application-monochrome-black.ico b/src/Artemis.UI/Assets/Images/Logo/application-monochrome-black.ico new file mode 100644 index 0000000000000000000000000000000000000000..0d4c13e2302846795687c212623dd53fdf93aea7 GIT binary patch literal 117419 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 literal 0 HcmV?d00001 diff --git a/src/Artemis.UI/Assets/Images/Logo/application-monochrome-white.ico b/src/Artemis.UI/Assets/Images/Logo/application-monochrome-white.ico new file mode 100644 index 0000000000000000000000000000000000000000..91399e5ed44c24f234bf79692fe745aa7aba4676 GIT binary patch literal 118150 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 V46|Mfzavl-WedQUVd#Ud{{cxK!GQn( literal 0 HcmV?d00001 diff --git a/src/Artemis.UI/DryIoc/ContainerExtensions.cs b/src/Artemis.UI/DryIoc/ContainerExtensions.cs index bcf4a20b0..7871e46c8 100644 --- a/src/Artemis.UI/DryIoc/ContainerExtensions.cs +++ b/src/Artemis.UI/DryIoc/ContainerExtensions.cs @@ -4,6 +4,7 @@ using Artemis.UI.DryIoc.InstanceProviders; using Artemis.UI.Screens.Device.Layout.LayoutProviders; using Artemis.UI.Screens.VisualScripting; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Services.Tray; using Artemis.UI.Services.Updating; using Artemis.UI.Shared; using Artemis.UI.Shared.Services.NodeEditor; @@ -33,6 +34,7 @@ public static class ContainerExtensions container.Register(Reuse.Singleton); container.Register(Reuse.Singleton); container.Register(); + container.Register(Reuse.Singleton); container.RegisterMany(thisAssembly, type => type.IsAssignableTo(), Reuse.Singleton); } diff --git a/src/Artemis.UI/Screens/Root/RootViewModel.cs b/src/Artemis.UI/Screens/Root/RootViewModel.cs index 55c2051a2..f3e4b8f83 100644 --- a/src/Artemis.UI/Screens/Root/RootViewModel.cs +++ b/src/Artemis.UI/Screens/Root/RootViewModel.cs @@ -7,6 +7,7 @@ using Artemis.Core.Services; using Artemis.UI.Models; using Artemis.UI.Screens.Sidebar; using Artemis.UI.Services.Interfaces; +using Artemis.UI.Services.Tray; using Artemis.UI.Services.Updating; using Artemis.UI.Shared; using Artemis.UI.Shared.Routing; @@ -16,6 +17,7 @@ using Artemis.WebClient.Workshop.Services; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Platform; using Avalonia.Threading; using ReactiveUI; using Serilog; @@ -34,6 +36,11 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv private readonly IUpdateService _updateService; private readonly IWindowService _windowService; private readonly ObservableAsPropertyHelper _titleBarViewModel; + private readonly PluginSetting _monochromeTrayIcon; + private readonly ITrayThemeProvider _trayThemeProvider; + private WindowIcon? _coloredTrayIcon; + private WindowIcon? _blackTrayIcon; + private WindowIcon? _whiteTrayIcon; public RootViewModel(ILogger logger, IRouter router, @@ -45,6 +52,7 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv IDebugService debugService, IUpdateService updateService, IWorkshopService workshopService, + ITrayThemeProvider trayThemeProvider, SidebarViewModel sidebarViewModel, DefaultTitleBarViewModel defaultTitleBarViewModel) { @@ -60,8 +68,17 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv _debugService = debugService; _updateService = updateService; _defaultTitleBarViewModel = defaultTitleBarViewModel; + _trayThemeProvider = trayThemeProvider; _lifeTime = (IClassicDesktopStyleApplicationLifetime) Application.Current!.ApplicationLifetime!; + _monochromeTrayIcon = settingsService.GetSetting("UI.MonochromeTrayIcon", false); + _monochromeTrayIcon.SettingChanged += (_, _) => + { + this.RaisePropertyChanged(nameof(MonochromeTrayIcon)); + this.RaisePropertyChanged(nameof(TrayIcon)); + }; + _trayThemeProvider.TrayThemeChanged += (_, _) => Dispatcher.UIThread.Post(() => this.RaisePropertyChanged(nameof(TrayIcon))); + router.SetRoot(this); mainWindowService.ConfigureMainWindowProvider(this); @@ -117,6 +134,26 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv public ReactiveCommand Exit { get; } public ViewModelBase? TitleBarViewModel => _titleBarViewModel.Value; + + /// + /// Gets a value indicating whether the tray icon is black or white rather than colored. + /// + public bool MonochromeTrayIcon => _monochromeTrayIcon.Value; + + /// + /// Gets the tray icon, in black or white to match the system tray when is enabled. + /// + public WindowIcon TrayIcon + { + get + { + if (!_monochromeTrayIcon.Value) + return _coloredTrayIcon ??= LoadTrayIcon("application"); + return _trayThemeProvider.IsTrayDark + ? _whiteTrayIcon ??= LoadTrayIcon("application-monochrome-white") + : _blackTrayIcon ??= LoadTrayIcon("application-monochrome-black"); + } + } public static PluginSetting? WindowSizeSetting { get; private set; } public void GoBack() @@ -188,6 +225,11 @@ public class RootViewModel : RoutableHostScreen, IMainWindowProv #region Implementation of IMainWindowProvider + private static WindowIcon LoadTrayIcon(string name) + { + return new WindowIcon(AssetLoader.Open(new Uri($"avares://Artemis.UI/Assets/Images/Logo/{name}.ico"))); + } + /// public bool IsMainWindowOpen => _lifeTime.MainWindow != null; diff --git a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml index 537a950b2..ab96d77b3 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml +++ b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabView.axaml @@ -70,6 +70,19 @@ + + + + Monochrome tray icon + + Show a black or white icon in the system tray instead of the colored one, matching your light or dark mode. + + + + + + + diff --git a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs index a22f8f5f1..61d4cfc14 100644 --- a/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs +++ b/src/Artemis.UI/Screens/Settings/Tabs/GeneralTabViewModel.cs @@ -159,6 +159,7 @@ public class GeneralTabViewModel : RoutableScreen public PluginSetting UIAutoRunDelay => _settingsService.GetSetting("UI.AutoRunDelay", 15); public PluginSetting UIShowOnStartup => _settingsService.GetSetting("UI.ShowOnStartup", true); public PluginSetting EnableMica => _settingsService.GetSetting("UI.EnableMica", true); + public PluginSetting UIMonochromeTrayIcon => _settingsService.GetSetting("UI.MonochromeTrayIcon", false); public PluginSetting UICheckForUpdates => _settingsService.GetSetting("UI.Updating.AutoCheck", true); public PluginSetting WorkshopShowNotifications => _settingsService.GetSetting("Workshop.ShowNotifications", true); public PluginSetting UIAutoUpdate => _settingsService.GetSetting("UI.Updating.AutoInstall", true); diff --git a/src/Artemis.UI/Services/Tray/BasicTrayThemeProvider.cs b/src/Artemis.UI/Services/Tray/BasicTrayThemeProvider.cs new file mode 100644 index 000000000..cdc3fbd11 --- /dev/null +++ b/src/Artemis.UI/Services/Tray/BasicTrayThemeProvider.cs @@ -0,0 +1,26 @@ +using System; +using Avalonia; +using Avalonia.Platform; + +namespace Artemis.UI.Services.Tray; + +/// +/// Provides the light or dark mode of the system tray based on the light or dark mode of the operating system. +/// +public class BasicTrayThemeProvider : ITrayThemeProvider +{ + /// + /// Initializes a new instance of the class. + /// + public BasicTrayThemeProvider() + { + if (Application.Current?.PlatformSettings is { } platformSettings) + platformSettings.ColorValuesChanged += (_, _) => TrayThemeChanged?.Invoke(this, EventArgs.Empty); + } + + /// + public bool IsTrayDark => Application.Current?.PlatformSettings?.GetColorValues().ThemeVariant != PlatformThemeVariant.Light; + + /// + public event EventHandler? TrayThemeChanged; +} diff --git a/src/Artemis.UI/Services/Tray/ITrayThemeProvider.cs b/src/Artemis.UI/Services/Tray/ITrayThemeProvider.cs new file mode 100644 index 000000000..a68338701 --- /dev/null +++ b/src/Artemis.UI/Services/Tray/ITrayThemeProvider.cs @@ -0,0 +1,19 @@ +using System; + +namespace Artemis.UI.Services.Tray; + +/// +/// Provides the light or dark mode of the system tray. +/// +public interface ITrayThemeProvider +{ + /// + /// Gets a value indicating whether the system tray has a dark background. + /// + bool IsTrayDark { get; } + + /// + /// Occurs when the background of the system tray may have changed, possibly on a background thread. + /// + event EventHandler? TrayThemeChanged; +}