From 6f71e6cca67e2a39cebcb0bdf7aae1b5b7f1db0f Mon Sep 17 00:00:00 2001 From: TGSAN Date: Tue, 4 Jun 2019 17:15:25 +0800 Subject: [PATCH 1/3] Support Windows 10 1903 Light Theme Support Windows 10 1903 Light Theme (Menu icon color) --- shadowsocks-csharp/View/MenuViewController.cs | 85 ++++++++++++++++++++++++++- shadowsocks-csharp/shadowsocks-csharp.csproj | 1 + 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 9d44d02b..26c2beed 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 int windowsThemeMode; public MenuViewController(ShadowsocksController controller) { @@ -83,6 +86,7 @@ namespace Shadowsocks.View _notifyIcon.MouseClick += notifyIcon1_Click; _notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick; _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; + _notifyIcon.MouseMove += _notifyIcon_MouseMove; controller.TrafficChanged += controller_TrafficChanged; this.updateChecker = new UpdateChecker(); @@ -104,6 +108,11 @@ namespace Shadowsocks.View } } + private void _notifyIcon_MouseMove(object sender, MouseEventArgs e) + { + UpdateTrayIcon(); + } + private void controller_TrafficChanged(object sender, EventArgs e) { if (icon_baseBitmap == null) @@ -161,6 +170,20 @@ namespace Shadowsocks.View Configuration config = controller.GetConfigurationCopy(); bool enabled = config.enabled; bool global = config.global; + + // set Windows 10 Theme color (1903+) + windowsThemeMode = getWindows10SystemThemeSetting(); + + switch (windowsThemeMode) + { + case 1: + if (!global || !enabled) + icon_baseBitmap = getDarkTrayIcon(icon_baseBitmap); + break; + default: + break; + } + icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); icon_base = Icon.FromHandle(icon_baseBitmap.GetHicon()); @@ -192,6 +215,37 @@ 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 = (255 - color.R) * flyBlue.R / 255; + //int green = (255 - color.G) * flyBlue.G / 255; + //int blue = (255 - color.B) * flyBlue.B / 255; + //int alpha = color.A * flyBlue.A / 255; + 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 * flyBlue.A / 255; + 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 +258,13 @@ namespace Shadowsocks.View { if (!enabled) { - Color flyBlue = Color.FromArgb(192, 192, 192); + Color flyBlue = Color.FromArgb(192, 192, 192, 192); // Multiply with flyBlue 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) { @@ -230,6 +285,32 @@ namespace Shadowsocks.View return iconCopy; } + public int getWindows10SystemThemeSetting() + { + // Support on Windows 10 1903+ + int registData = 0; // 0:dark mode, 1:light mode + 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) + { + registData = Convert.ToInt32(reg_ThemesPersonalize.GetValue("SystemUsesLightTheme").ToString()); + //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; + } + private Bitmap AddBitmapOverlay(Bitmap original, params Bitmap[] overlays) { Bitmap bitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format64bppArgb); diff --git a/shadowsocks-csharp/shadowsocks-csharp.csproj b/shadowsocks-csharp/shadowsocks-csharp.csproj index 60be34bd..9677af8d 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 + From 95b760c6e130ccf747bea372b92db5919aacb0ed Mon Sep 17 00:00:00 2001 From: TGSAN Date: Sun, 16 Jun 2019 00:22:20 +0800 Subject: [PATCH 2/3] Update for #2379 Move GetWindows10SystemThemeSetting() to Util.cs WindowsThemeMode use enum Status var windowsThemeMode rename to windowsThemeMode Used `if else` to replace `switch case` Delete legacy commint (Some code). Increase contrast for icon. --- shadowsocks-csharp/Util/Util.cs | 31 +++++++++++++++ shadowsocks-csharp/View/MenuViewController.cs | 54 ++++++--------------------- 2 files changed, 42 insertions(+), 43 deletions(-) diff --git a/shadowsocks-csharp/Util/Util.cs b/shadowsocks-csharp/Util/Util.cs index 8130b961..9ca331a3 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 26c2beed..1d8ed5b6 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -59,7 +59,7 @@ namespace Shadowsocks.View private LogForm logForm; private HotkeySettingsForm hotkeySettingsForm; private string _urlToOpen; - private int windowsThemeMode; + private Utils.WindowsThemeMode currentWindowsThemeMode; public MenuViewController(ShadowsocksController controller) { @@ -172,17 +172,11 @@ namespace Shadowsocks.View bool global = config.global; // set Windows 10 Theme color (1903+) - windowsThemeMode = getWindows10SystemThemeSetting(); + currentWindowsThemeMode = Utils.GetWindows10SystemThemeSetting(); - switch (windowsThemeMode) - { - case 1: - if (!global || !enabled) - icon_baseBitmap = getDarkTrayIcon(icon_baseBitmap); - break; - default: - break; - } + if (currentWindowsThemeMode == Utils.WindowsThemeMode.Light) + if (!global || !enabled) + icon_baseBitmap = getDarkTrayIcon(icon_baseBitmap); icon_baseBitmap = getTrayIconByState(icon_baseBitmap, enabled, global); @@ -227,14 +221,10 @@ namespace Shadowsocks.View { Color flyBlue = Color.FromArgb(192, 0, 0, 0); // Multiply with flyBlue - //int red = (255 - color.R) * flyBlue.R / 255; - //int green = (255 - color.G) * flyBlue.G / 255; - //int blue = (255 - color.B) * flyBlue.B / 255; - //int alpha = color.A * flyBlue.A / 255; 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 * flyBlue.A / 255; + int alpha = color.A; iconCopy.SetPixel(x, y, Color.FromArgb(alpha, red, green, blue)); } else @@ -258,8 +248,12 @@ namespace Shadowsocks.View { if (!enabled) { - Color flyBlue = Color.FromArgb(192, 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; @@ -285,32 +279,6 @@ namespace Shadowsocks.View return iconCopy; } - public int getWindows10SystemThemeSetting() - { - // Support on Windows 10 1903+ - int registData = 0; // 0:dark mode, 1:light mode - 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) - { - registData = Convert.ToInt32(reg_ThemesPersonalize.GetValue("SystemUsesLightTheme").ToString()); - //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; - } - private Bitmap AddBitmapOverlay(Bitmap original, params Bitmap[] overlays) { Bitmap bitmap = new Bitmap(original.Width, original.Height, PixelFormat.Format64bppArgb); From 66b94d4983071495630eeb4e914c714801aa5d7c Mon Sep 17 00:00:00 2001 From: TGSAN Date: Thu, 27 Jun 2019 17:15:53 +0800 Subject: [PATCH 3/3] Fixed bug of #2379 pullrequestreview-254461303 Fixed bug of #2379 pullrequestreview-254461303 Redundant paintings when user move mouse on the icon, pixel by pixel. --- shadowsocks-csharp/View/MenuViewController.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/shadowsocks-csharp/View/MenuViewController.cs b/shadowsocks-csharp/View/MenuViewController.cs index 1d8ed5b6..5268d57b 100644 --- a/shadowsocks-csharp/View/MenuViewController.cs +++ b/shadowsocks-csharp/View/MenuViewController.cs @@ -86,7 +86,6 @@ namespace Shadowsocks.View _notifyIcon.MouseClick += notifyIcon1_Click; _notifyIcon.MouseDoubleClick += notifyIcon1_DoubleClick; _notifyIcon.BalloonTipClosed += _notifyIcon_BalloonTipClosed; - _notifyIcon.MouseMove += _notifyIcon_MouseMove; controller.TrafficChanged += controller_TrafficChanged; this.updateChecker = new UpdateChecker(); @@ -108,11 +107,6 @@ namespace Shadowsocks.View } } - private void _notifyIcon_MouseMove(object sender, MouseEventArgs e) - { - UpdateTrayIcon(); - } - private void controller_TrafficChanged(object sender, EventArgs e) { if (icon_baseBitmap == null) @@ -632,6 +626,7 @@ namespace Shadowsocks.View private void notifyIcon1_Click(object sender, MouseEventArgs e) { + UpdateTrayIcon(); if (e.Button == MouseButtons.Middle) { ShowLogForm();