diff --git a/Actions/AdvancedShutdownAction.cs b/Actions/AdvancedShutdownAction.cs
index ef5a366..bf7699f 100644
--- a/Actions/AdvancedShutdownAction.cs
+++ b/Actions/AdvancedShutdownAction.cs
@@ -455,6 +455,8 @@ private void ShowOrUpdateFloatingWindow()
Topmost = true,
ShowInTaskbar = false,
SystemDecorations = SystemDecorations.None,
+ Background = Brushes.Transparent,
+ TransparencyLevelHint = [WindowTransparencyLevel.Transparent],
Content = new Border
{
CornerRadius = new CornerRadius(10),
diff --git a/ConfigHandlers/MainConfigData.cs b/ConfigHandlers/MainConfigData.cs
index 8981084..c7f861c 100644
--- a/ConfigHandlers/MainConfigData.cs
+++ b/ConfigHandlers/MainConfigData.cs
@@ -100,6 +100,21 @@ public bool AutoMatchMainBackgroundTheme
OnPropertyChanged();
}
}
+
+
+ bool _autoHideMainWindowWhenOccluded;
+
+ [JsonPropertyName("autoHideMainWindowWhenOccluded")]
+ public bool AutoHideMainWindowWhenOccluded
+ {
+ get => _autoHideMainWindowWhenOccluded;
+ set
+ {
+ if (value == _autoHideMainWindowWhenOccluded) return;
+ _autoHideMainWindowWhenOccluded = value;
+ OnPropertyChanged();
+ }
+ }
// ========== 公告相关 ==========
/*string _lastAcceptedAnnouncement = string.Empty;
diff --git a/Controls/InTimePeriodRuleSettingsControl.axaml b/Controls/InTimePeriodRuleSettingsControl.axaml
new file mode 100644
index 0000000..dfe0e05
--- /dev/null
+++ b/Controls/InTimePeriodRuleSettingsControl.axaml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Controls/InTimePeriodRuleSettingsControl.cs b/Controls/InTimePeriodRuleSettingsControl.cs
index 99f563f..8f5723f 100644
--- a/Controls/InTimePeriodRuleSettingsControl.cs
+++ b/Controls/InTimePeriodRuleSettingsControl.cs
@@ -1,91 +1,51 @@
+using System;
using Avalonia.Controls;
-using Avalonia.Layout;
+using Avalonia.Markup.Xaml;
using ClassIsland.Core.Abstractions.Controls;
-using System;
using SystemTools.Rules;
namespace SystemTools.Controls;
-
-public class InTimePeriodRuleSettingsControl : RuleSettingsControlBase
+public partial class InTimePeriodRuleSettingsControl : RuleSettingsControlBase
{
- private readonly TimePicker _startTimePicker;
- private readonly TimePicker _endTimePicker;
-
public InTimePeriodRuleSettingsControl()
{
- var panel = new StackPanel { Spacing = 10 };
- var row = new Grid
- {
- ColumnDefinitions = new ColumnDefinitions("Auto,*,Auto,*,Auto"),
- ColumnSpacing = 8,
- VerticalAlignment = VerticalAlignment.Center
- };
-
- row.Children.Add(new TextBlock { Text = "从", VerticalAlignment = VerticalAlignment.Center });
-
- _startTimePicker = new TimePicker
- {
- ClockIdentifier = "24HourClock",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- };
- Grid.SetColumn(_startTimePicker, 1);
- row.Children.Add(_startTimePicker);
-
- var sep = new TextBlock { Text = "至", VerticalAlignment = VerticalAlignment.Center };
- Grid.SetColumn(sep, 2);
- row.Children.Add(sep);
+ InitializeComponent();
- _endTimePicker = new TimePicker
- {
- ClockIdentifier = "24HourClock",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center
- };
- Grid.SetColumn(_endTimePicker, 3);
- row.Children.Add(_endTimePicker);
-
- var hint = new TextBlock
- {
- Text = "提示:若起始晚于结束 将按跨天处理",
- TextWrapping = Avalonia.Media.TextWrapping.Wrap,
- Foreground = Avalonia.Media.Brushes.Gray,
- FontSize = 12
- };
- panel.Children.Add(row);
- panel.Children.Add(hint);
- Content = panel;
+ StartTimePicker.SelectedTimeChanged += (_, _) => SyncSettings();
+ EndTimePicker.SelectedTimeChanged += (_, _) => SyncSettings();
+ }
- _startTimePicker.SelectedTimeChanged += (s, e) => SyncSettings();
- _endTimePicker.SelectedTimeChanged += (s, e) => SyncSettings();
+ private void InitializeComponent()
+ {
+ AvaloniaXamlLoader.Load(this);
}
protected override void OnInitialized()
{
base.OnInitialized();
-
+
if (TimeSpan.TryParse(Settings.StartTime, out var start))
{
- _startTimePicker.SelectedTime = start;
+ StartTimePicker.SelectedTime = start;
}
-
+
if (TimeSpan.TryParse(Settings.EndTime, out var end))
{
- _endTimePicker.SelectedTime = end;
+ EndTimePicker.SelectedTime = end;
}
}
private void SyncSettings()
{
- if (_startTimePicker.SelectedTime.HasValue)
+ if (StartTimePicker.SelectedTime.HasValue)
{
- Settings.StartTime = _startTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
+ Settings.StartTime = StartTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
}
- if (_endTimePicker.SelectedTime.HasValue)
+ if (EndTimePicker.SelectedTime.HasValue)
{
- Settings.EndTime = _endTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
+ Settings.EndTime = EndTimePicker.SelectedTime.Value.ToString(@"hh\:mm\:ss");
}
}
}
diff --git a/Services/AdaptiveThemeSyncService.cs b/Services/AdaptiveThemeSyncService.cs
index b7baa6b..97378da 100644
--- a/Services/AdaptiveThemeSyncService.cs
+++ b/Services/AdaptiveThemeSyncService.cs
@@ -6,6 +6,7 @@
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
+using System.Windows.Forms;
using ClassIsland.Shared;
using SystemTools.Shared;
@@ -48,7 +49,7 @@ private void OnTick(object? sender, EventArgs e)
try
{
- var targetTheme = DetectThemeByMainWindowBackground();
+ var targetTheme = DetectThemeByScreenBackground();
if (targetTheme == null || targetTheme == _lastAppliedTheme)
{
return;
@@ -62,7 +63,7 @@ private void OnTick(object? sender, EventArgs e)
themeService.SetTheme(targetTheme.Value, null);
_lastAppliedTheme = targetTheme;
- _logger.LogDebug("已自动匹配主题为:{Theme}", targetTheme == 2 ? "黑暗" : "明亮");
+ _logger.LogDebug("已自动匹配主题为:{Theme}", targetTheme == 1 ? "黑暗" : "明亮");
}
catch (Exception ex)
{
@@ -70,44 +71,58 @@ private void OnTick(object? sender, EventArgs e)
}
}
- private static int? DetectThemeByMainWindowBackground()
+ private static int? DetectThemeByScreenBackground()
{
var handle = Process.GetCurrentProcess().MainWindowHandle;
- if (handle == IntPtr.Zero)
+ if (handle == IntPtr.Zero || !GetWindowRect(handle, out var rect))
{
return null;
}
- if (!GetWindowRect(handle, out var rect))
- {
- return null;
- }
-
- var width = Math.Max(1, rect.Right - rect.Left);
- var height = Math.Max(1, rect.Bottom - rect.Top);
+ var mainWindow = Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom);
+ var screen = Screen.FromRectangle(mainWindow);
+ var captureRect = BuildTargetArea(screen.Bounds, mainWindow);
- using var bitmap = new Bitmap(width, height);
+ using var bitmap = new Bitmap(captureRect.Width, captureRect.Height);
using var graphics = Graphics.FromImage(bitmap);
- graphics.CopyFromScreen(rect.Left, rect.Top, 0, 0, new Size(width, height));
+ graphics.CopyFromScreen(captureRect.Left, captureRect.Top, 0, 0, captureRect.Size);
- var samples = new (int X, int Y)[]
+ double luminance = 0;
+ long samples = 0;
+ const int grid = 8;
+ var stepX = Math.Max(1, captureRect.Width / grid);
+ var stepY = Math.Max(1, captureRect.Height / grid);
+
+ for (var y = 0; y < captureRect.Height; y += stepY)
{
- (width / 2, height / 2),
- (Math.Max(0, width / 4), Math.Max(0, height / 4)),
- (Math.Max(0, width * 3 / 4), Math.Max(0, height / 4)),
- (Math.Max(0, width / 4), Math.Max(0, height * 3 / 4)),
- (Math.Max(0, width * 3 / 4), Math.Max(0, height * 3 / 4)),
- };
+ for (var x = 0; x < captureRect.Width; x += stepX)
+ {
+ var color = bitmap.GetPixel(Math.Clamp(x, 0, captureRect.Width - 1), Math.Clamp(y, 0, captureRect.Height - 1));
+ luminance += 0.299 * color.R + 0.587 * color.G + 0.114 * color.B;
+ samples++;
+ }
+ }
- double luminance = 0;
- foreach (var sample in samples)
+ if (samples == 0)
{
- var color = bitmap.GetPixel(Math.Clamp(sample.X, 0, width - 1), Math.Clamp(sample.Y, 0, height - 1));
- luminance += 0.299 * color.R + 0.587 * color.G + 0.114 * color.B;
+ return null;
}
- luminance /= samples.Length;
- return luminance < 128 ? 2 : 1; // 2=黑暗,1=明亮
+ luminance /= samples;
+
+ // 与 ClassIsland 的主题模式保持一致:0=明亮,1=黑暗。
+ return luminance < 128 ? 1 : 0;
+ }
+
+ private static Rectangle BuildTargetArea(Rectangle screenBounds, Rectangle mainWindow)
+ {
+ var topHeight = Math.Max(1, screenBounds.Height / 5);
+ var bottomY = screenBounds.Bottom - topHeight;
+
+ var isTop = mainWindow.Top + mainWindow.Height / 2 <= screenBounds.Top + screenBounds.Height / 2;
+ return isTop
+ ? new Rectangle(screenBounds.Left, screenBounds.Top, screenBounds.Width, topHeight)
+ : new Rectangle(screenBounds.Left, bottomY, screenBounds.Width, topHeight);
}
[DllImport("user32.dll")]
diff --git a/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml b/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml
index 8dc1b25..ae3c504 100644
--- a/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml
+++ b/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml
@@ -8,13 +8,14 @@
+ Description="每 2 秒检测屏幕顶部/底部五分之一亮度:偏黑切换黑暗,偏白切换明亮。">
+
diff --git a/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml.cs b/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml.cs
index a15fc34..17e53f6 100644
--- a/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml.cs
+++ b/SettingsPage/MoreFeaturesOptionsSettingsPage.axaml.cs
@@ -28,4 +28,5 @@ private void AutoMatchThemeToggle_OnChanged(object? sender, RoutedEventArgs e)
GlobalConstants.MainConfig?.Save();
}
+
}
diff --git a/SettingsPage/SystemToolsSettingsPage.axaml b/SettingsPage/SystemToolsSettingsPage.axaml
index 1d6bb2c..ab896fd 100644
--- a/SettingsPage/SystemToolsSettingsPage.axaml
+++ b/SettingsPage/SystemToolsSettingsPage.axaml
@@ -167,17 +167,8 @@
-
-
-
-
-
-
-
-
+
+