diff --git a/v2rayN/v2rayN/App.xaml b/v2rayN/v2rayN/App.xaml
index ddb2a4ba..03af3be5 100644
--- a/v2rayN/v2rayN/App.xaml
+++ b/v2rayN/v2rayN/App.xaml
@@ -20,6 +20,8 @@
13
14
11
+
+
+ /// 查找类似 Follow System Theme 的本地化字符串。
+ ///
+ public static string TbSettingsFollowSystemTheme {
+ get {
+ return ResourceManager.GetString("TbSettingsFollowSystemTheme", resourceCulture);
+ }
+ }
+
///
/// 查找类似 FontSize 的本地化字符串。
///
diff --git a/v2rayN/v2rayN/Resx/ResUI.resx b/v2rayN/v2rayN/Resx/ResUI.resx
index 1625e449..5b513251 100644
--- a/v2rayN/v2rayN/Resx/ResUI.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.resx
@@ -505,6 +505,9 @@
Dark Mode
+
+ Follow System Theme
+
Language(Restart)
diff --git a/v2rayN/v2rayN/Resx/ResUI.ru.resx b/v2rayN/v2rayN/Resx/ResUI.ru.resx
index 99be3632..30e796ab 100644
--- a/v2rayN/v2rayN/Resx/ResUI.ru.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.ru.resx
@@ -505,6 +505,9 @@
Тёмный режим
+
+ следить за системной темой
+
Язык (требуется перезапуск)
diff --git a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
index 0363c124..8de8f034 100644
--- a/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
+++ b/v2rayN/v2rayN/Resx/ResUI.zh-Hans.resx
@@ -505,6 +505,9 @@
暗黑模式
+
+ 是否跟随系统主题
+
语言(重启)
diff --git a/v2rayN/v2rayN/Tool/Utils.cs b/v2rayN/v2rayN/Tool/Utils.cs
index e440c3ff..d65bebae 100644
--- a/v2rayN/v2rayN/Tool/Utils.cs
+++ b/v2rayN/v2rayN/Tool/Utils.cs
@@ -1047,6 +1047,13 @@ namespace v2rayN
DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);
}
+ public static bool IsLightTheme()
+ {
+ using var key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize");
+ var value = key?.GetValue("AppsUseLightTheme");
+ return value is int i && i > 0;
+ }
+
#endregion 杂项
#region TempPath
diff --git a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
index 7a250e96..83fe9a7d 100644
--- a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
+++ b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs
@@ -12,8 +12,10 @@ using System.Drawing;
using System.IO;
using System.Reactive;
using System.Reactive.Linq;
+using System.Runtime.InteropServices;
using System.Text;
using System.Windows;
+using System.Windows.Interop;
using System.Windows.Media;
using v2rayN.Base;
using v2rayN.Handler;
@@ -237,6 +239,9 @@ namespace v2rayN.ViewModels
[Reactive]
public int CurrentFontSize { get; set; }
+ [Reactive]
+ public bool FollowSystemTheme { get; set; }
+
[Reactive]
public string CurrentLanguage { get; set; }
@@ -244,7 +249,7 @@ namespace v2rayN.ViewModels
#region Init
- public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action updateView)
+ public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action updateView,HwndSource hwndSource)
{
_updateView = updateView;
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
@@ -309,7 +314,7 @@ namespace v2rayN.ViewModels
y => y == true)
.Subscribe(c => DoEnableTun(c));
- BindingUI();
+ BindingUI(hwndSource);
RestoreUI();
AutoHideStartup();
@@ -1665,9 +1670,10 @@ namespace v2rayN.ViewModels
{
}
- private void BindingUI()
+ private void BindingUI(HwndSource hwndSource)
{
ColorModeDark = _config.uiItem.colorModeDark;
+ FollowSystemTheme = _config.uiItem.followSystemTheme;
_swatches.AddRange(new SwatchesProvider().Swatches);
if (!_config.uiItem.colorPrimaryName.IsNullOrEmpty())
{
@@ -1690,6 +1696,57 @@ namespace v2rayN.ViewModels
}
});
+ this.WhenAnyValue(x => x.FollowSystemTheme,
+ y => y == true)
+ .Subscribe(c =>
+ {
+ if (_config.uiItem.followSystemTheme != FollowSystemTheme)
+ {
+ _config.uiItem.followSystemTheme = FollowSystemTheme;
+ if (FollowSystemTheme)
+ {
+ hwndSource.AddHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
+ {
+ const int WM_SETTINGCHANGE = 0x001A;
+ if (msg == WM_SETTINGCHANGE)
+ {
+ if (wParam == IntPtr.Zero && Marshal.PtrToStringUni(lParam) == "ImmersiveColorSet")
+ {
+ var isLightTheme = Utils.IsLightTheme();
+ ColorModeDark = !isLightTheme;
+ }
+ }
+
+ return IntPtr.Zero;
+
+ });
+
+ var isLightTheme = Utils.IsLightTheme();
+ ColorModeDark = !isLightTheme;
+ }
+ else
+ {
+ hwndSource.RemoveHook((IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) =>
+ {
+ const int WM_SETTINGCHANGE = 0x001A;
+ if (msg == WM_SETTINGCHANGE)
+ {
+ if (wParam == IntPtr.Zero && Marshal.PtrToStringUni(lParam) == "ImmersiveColorSet")
+ {
+ var isLightTheme = Utils.IsLightTheme();
+ ColorModeDark = !isLightTheme;
+ }
+ }
+
+ return IntPtr.Zero;
+
+ });
+ }
+
+ ConfigHandler.SaveConfig(ref _config);
+ }
+ });
+
this.WhenAnyValue(
x => x.SelectedSwatch,
y => y != null && !y.Name.IsNullOrEmpty())
diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml b/v2rayN/v2rayN/Views/MainWindow.xaml
index b994f28f..9aefc90e 100644
--- a/v2rayN/v2rayN/Views/MainWindow.xaml
+++ b/v2rayN/v2rayN/Views/MainWindow.xaml
@@ -301,6 +301,7 @@
+
@@ -319,17 +320,30 @@
x:Name="togDarkMode"
Grid.Row="0"
Grid.Column="1"
+ Margin="8"
+ IsEnabled="{Binding ElementName=followSystemTheme, Path=IsChecked, Converter={StaticResource InverseBooleanConverter}}"/>
+
+
+
+ Header="{x:Static resx:ResUI.menuSpeedServer}"/>