diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index 653f9a2b..b62bb567 100755 --- a/shadowsocks-csharp/Util/Util.cs +++ b/shadowsocks-csharp/Util/Util.cs @@ -55,6 +55,37 @@ namespace Shadowsocks.Util return _tempPath; } + public enum WindowsThemeMode { Dark, Light } + + // Support on Windows 10 1903+ + public static WindowsThemeMode GetWindows10SystemThemeSetting() + { + WindowsThemeMode registData = WindowsThemeMode.Dark; + try + { + RegistryKey reg_HKCU = Registry.CurrentUser; + RegistryKey reg_ThemesPersonalize = reg_HKCU.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", false); + if (reg_ThemesPersonalize.GetValue("SystemUsesLightTheme") != null) + { + if (Convert.ToInt32(reg_ThemesPersonalize.GetValue("SystemUsesLightTheme").ToString()) == 0) // 0:dark mode, 1:light mode + registData = WindowsThemeMode.Dark; + else + registData = WindowsThemeMode.Light; + //Console.WriteLine(registData); + } + else + { + throw new Exception("Reg-Value SystemUsesLightTheme not found."); + } + } + catch + { + Logging.Info( + $"Cannot get Windows 10 system theme mode, return default value 0 (dark mode)."); + } + return registData; + } + // return a full path with filename combined which pointed to the temporary directory public static string GetTempPath(string filename) { diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 845f8319..b593fefb 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -13,6 +13,8 @@ using Shadowsocks.Model; using Shadowsocks.Properties; using Shadowsocks.Util; using System.Linq; +using Microsoft.Win32; +using System.Windows.Interop; namespace Shadowsocks.View { @@ -57,6 +59,7 @@ namespace Shadowsocks.View private LogForm logForm; private HotkeySettingsForm hotkeySettingsForm; private string _urlToOpen; + private Utils.WindowsThemeMode currentWindowsThemeMode; public MenuViewController(ShadowsocksController controller) { @@ -161,6 +164,14 @@ namespace Shadowsocks.View Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; + + // set Windows 10 Theme color (1903+) + currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); + + if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) + if (!global || !enabled) + icon_baseBitmap = getDarkTrayIcon(icon_baseBitmap); + icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); icon_base = Icon.FromHandle(icon_baseBitmap.GetHicon()); @@ -192,6 +203,33 @@ namespace Shadowsocks.View ViewUtils.SetNotifyIconText(_notifyIcon, text); } + private Bitmap getDarkTrayIcon(Bitmap originIcon) + { + Bitmap iconCopy = new Bitmap(originIcon); + for (int x = 0; x < iconCopy.Width; x++) + { + for (int y = 0; y < iconCopy.Height; y++) + { + Color color = originIcon.GetPixel(x, y); + if (color.A != 0) + { + Color flyBlue = Color.FromArgb(192, 0, 0, 0); + // Multiply with flyBlue + int red = color.R * flyBlue.R / 255; + int green = color.G * flyBlue.G / 255; + int blue = color.B * flyBlue.B / 255; + int alpha = color.A; + iconCopy.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); + } + else + { + iconCopy.SetPixel(x, y, Color.FromArgb(color.A, color.R, color.G, color.B)); + } + } + } + return iconCopy; + } + private Bitmap getTrayIconByState(Bitmap originIcon, bool enabled, bool global) { Bitmap iconCopy = new Bitmap(originIcon); @@ -204,12 +242,17 @@ namespace Shadowsocks.View { if (!enabled) { - Color flyBlue = Color.FromArgb(192, 192, 192); // Multiply with flyBlue + Color flyBlue; + if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) + flyBlue = Color.FromArgb(128, 192, 192, 192); // Dark icon more transparent + else + flyBlue = Color.FromArgb(192, 192, 192, 192); // Light icon less transparent int red = color.R * flyBlue.R / 255; int green = color.G * flyBlue.G / 255; int blue = color.B * flyBlue.B / 255; - iconCopy.SetPixel(x, y, Color.FromArgb(color.A, red, green, blue)); + int alpha = color.A * flyBlue.A / 255; + iconCopy.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); } else if (global) { @@ -586,6 +629,7 @@ namespace Shadowsocks.View private void notifyIcon1_Click(object sender, MouseEventArgs e) { + UpdateTrayIcon(); if (e.Button == MouseButtons.Middle) { ShowLogForm(); diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 7e600fac..68c76381 100644 --- a/shadowsocks-csharp/shadowsocks-csharp.csproj +++ b/shadowsocks-csharp/shadowsocks-csharp.csproj @@ -83,6 +83,7 @@ 3rd\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll +