From 11130cfdb3233a7cfcb3631a9df1d782b12d52dd Mon Sep 17 00:00:00 2001 From: lincube Date: Thu, 9 Apr 2026 19:15:06 +0800 Subject: [PATCH] =?UTF-8?q?feat.=E6=9B=B4=E6=96=B0=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E5=A4=9A=E6=A0=87=E9=A2=98=E4=BF=AE=E5=A4=8D=E3=80=82=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BA=86=EF=BC=8C=E5=BA=94=E7=94=A8=E5=90=AF=E5=8A=A8?= =?UTF-8?q?=E5=8F=B0=E4=B8=8D=E6=98=BE=E7=A4=BA=E5=BA=94=E7=94=A8=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E8=83=8C=E6=99=AF=E3=80=82=E3=80=82=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 30 ++++++++++++++- LanMountainDesktop/Localization/en-US.json | 4 ++ LanMountainDesktop/Localization/zh-CN.json | 4 ++ .../Models/LauncherSettingsSnapshot.cs | 2 + .../Services/PowerManagementService.cs | 30 ++++++--------- .../LauncherSettingsPageViewModel.cs | 36 ++++++++++++++++++ .../Views/MainWindow.ComponentSystem.cs | 17 ++++----- .../Views/MainWindow.DesktopPaging.cs | 38 +++++++++++++++++-- .../Views/MainWindow.SettingsHardCut.Stubs.cs | 17 +++++++++ .../SettingsPages/LauncherSettingsPage.axaml | 27 ++++++++++++- .../SettingsPages/UpdateSettingsPage.axaml | 5 --- 11 files changed, 171 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 531cc75..5ad52ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,33 @@ --- +## [0.8.3.2] - 2026-04-09 + +### 新增 (Added) +- ✨ **应用启动台图标卡片显示选项**: 新增应用启动台图标卡片显示设置 + - 用户可在设置中选择是否显示应用图标的专属卡片背景 + - 关闭后仅显示应用图标本身,更加简洁 + - 支持动态切换,实时预览效果 + +### 变更 (Changed) +- 无 + +### 修复 (Fixed) +- 🐛 **应用启动台文件夹应用数量限制**: 修复了应用启动台文件夹无法查看超过12个应用的问题 + - 问题原因: 文件夹弹窗未实现滚动功能,应用列表超出显示区域后被截断 + - 修复方案: 为文件夹内容区域添加滚动支持,允许用户滚动查看所有应用 +- 🐛 **电源菜单重启导致关机问题**: 修复了点击电源菜单"重启"选项却触发关机的问题 + - 问题原因: `SlideToShutDown.exe` 仅支持关机操作,不支持重启,错误地将其用于重启功能 + - 修复方案: 重启操作改为使用标准的二次确认对话框(所有平台统一),仅关机操作使用 SlideToShutDown 滑动界面 +- 🐛 **课表组件字体显示问题**: 修复了日间模式下课表组件字体颜色与背景色相近导致看不清的问题 + - 问题原因: 主题切换时增量更新逻辑未同步更新文字颜色 + - 修复方案: 在 `IncrementalUpdateItems()` 方法中同步更新课程项的文字颜色 + +### 移除 (Removed) +- 🗑️ **更新页面重复标题**: 移除了更新页面中重复的更新标题,优化页面布局 + +--- + ## [0.8.3.1] - 2026-04-08 ### 新增 (Added) @@ -78,5 +105,6 @@ ## 链接 -[Unreleased]: https://github.com/yourorg/LanMountainDesktop/compare/v0.8.3.1...HEAD +[Unreleased]: https://github.com/yourorg/LanMountainDesktop/compare/v0.8.3.2...HEAD +[0.8.3.2]: https://github.com/yourorg/LanMountainDesktop/releases/tag/v0.8.3.2 [0.8.3.1]: https://github.com/yourorg/LanMountainDesktop/releases/tag/v0.8.3.1 diff --git a/LanMountainDesktop/Localization/en-US.json b/LanMountainDesktop/Localization/en-US.json index 041d488..4ba11f1 100644 --- a/LanMountainDesktop/Localization/en-US.json +++ b/LanMountainDesktop/Localization/en-US.json @@ -564,6 +564,10 @@ "settings.launcher.hidden_type_folder": "Folder", "settings.launcher.hidden_type_shortcut": "App", "settings.launcher.restore_button": "Unhide", + "settings.launcher.appearance_header": "Appearance", + "settings.launcher.appearance_desc": "Customize the appearance of the App Launcher.", + "settings.launcher.show_tile_background_header": "Show tile background", + "settings.launcher.show_tile_background_desc": "Display a background card behind each app icon. When turned off, only the icon is shown for a cleaner look.", "settings.plugins.title": "Plugins", "settings.plugins.runtime_header": "Plugin Runtime", "settings.plugins.runtime_desc": "Review plugin runtime state and load results.", diff --git a/LanMountainDesktop/Localization/zh-CN.json b/LanMountainDesktop/Localization/zh-CN.json index 281a316..bcb757e 100644 --- a/LanMountainDesktop/Localization/zh-CN.json +++ b/LanMountainDesktop/Localization/zh-CN.json @@ -558,6 +558,10 @@ "settings.launcher.hidden_type_folder": "文件夹", "settings.launcher.hidden_type_shortcut": "应用", "settings.launcher.restore_button": "取消隐藏", + "settings.launcher.appearance_header": "外观", + "settings.launcher.appearance_desc": "自定义应用启动台的外观样式。", + "settings.launcher.show_tile_background_header": "显示图标卡片背景", + "settings.launcher.show_tile_background_desc": "在应用图标后显示卡片背景,关闭后仅显示图标更加简洁。", "settings.plugins.title": "插件", "settings.plugins.runtime_header": "插件运行时", "settings.plugins.runtime_desc": "查看插件运行时状态、加载结果与诊断信息。", diff --git a/LanMountainDesktop/Models/LauncherSettingsSnapshot.cs b/LanMountainDesktop/Models/LauncherSettingsSnapshot.cs index 7be9834..8e27d94 100644 --- a/LanMountainDesktop/Models/LauncherSettingsSnapshot.cs +++ b/LanMountainDesktop/Models/LauncherSettingsSnapshot.cs @@ -8,6 +8,8 @@ public sealed class LauncherSettingsSnapshot public List HiddenLauncherAppPaths { get; set; } = []; + public bool ShowTileBackground { get; set; } = true; + public LauncherSettingsSnapshot Clone() { var clone = (LauncherSettingsSnapshot)MemberwiseClone(); diff --git a/LanMountainDesktop/Services/PowerManagementService.cs b/LanMountainDesktop/Services/PowerManagementService.cs index c6b4187..2adc836 100644 --- a/LanMountainDesktop/Services/PowerManagementService.cs +++ b/LanMountainDesktop/Services/PowerManagementService.cs @@ -113,6 +113,11 @@ internal sealed class WindowsPowerManagementService : IPowerManagementService public void ShowNativePowerUI(PowerAction action) { + // SlideToShutDown.exe 只支持关机,不支持重启 + // 重启操作应该通过 RestartAsync() 使用 shutdown /r 命令 + if (action != PowerAction.Shutdown) + return; + var slideToShutDownPath = Environment.ExpandEnvironmentVariables(@"%windir%\System32\SlideToShutDown.exe"); if (System.IO.File.Exists(slideToShutDownPath)) { @@ -124,26 +129,13 @@ internal sealed class WindowsPowerManagementService : IPowerManagementService return; } - switch (action) + // 回退到标准关机命令 + Process.Start(new ProcessStartInfo { - case PowerAction.Shutdown: - Process.Start(new ProcessStartInfo - { - FileName = "shutdown", - Arguments = "/s /t 5 /c \"LanMountainDesktop: Shutting down...\"", - UseShellExecute = true - }); - break; - - case PowerAction.Restart: - Process.Start(new ProcessStartInfo - { - FileName = "shutdown", - Arguments = "/r /t 5 /c \"LanMountainDesktop: Restarting...\"", - UseShellExecute = true - }); - break; - } + FileName = "shutdown", + Arguments = "/s /t 5 /c \"LanMountainDesktop: Shutting down...\"", + UseShellExecute = true + }); } [DllImport("user32.dll", SetLastError = true)] diff --git a/LanMountainDesktop/ViewModels/LauncherSettingsPageViewModel.cs b/LanMountainDesktop/ViewModels/LauncherSettingsPageViewModel.cs index f776f33..1480737 100644 --- a/LanMountainDesktop/ViewModels/LauncherSettingsPageViewModel.cs +++ b/LanMountainDesktop/ViewModels/LauncherSettingsPageViewModel.cs @@ -117,6 +117,36 @@ public sealed partial class LauncherSettingsPageViewModel : ViewModelBase, IDisp [ObservableProperty] private bool _isHiddenItemsEmpty = true; + [ObservableProperty] + private string _appearanceHeader = string.Empty; + + [ObservableProperty] + private string _appearanceDescription = string.Empty; + + [ObservableProperty] + private string _showTileBackgroundHeader = string.Empty; + + [ObservableProperty] + private string _showTileBackgroundDescription = string.Empty; + + [ObservableProperty] + private bool _showTileBackground; + + partial void OnShowTileBackgroundChanged(bool value) + { + SaveShowTileBackgroundSetting(value); + } + + private void SaveShowTileBackgroundSetting(bool value) + { + var snapshot = _settingsFacade.LauncherPolicy.Get()?.Clone() ?? new LauncherSettingsSnapshot(); + snapshot.ShowTileBackground = value; + _settingsFacade.Settings.SaveSnapshot( + SettingsScope.Launcher, + snapshot, + changedKeys: [nameof(LauncherSettingsSnapshot.ShowTileBackground)]); + } + public void Dispose() { if (_disposed) @@ -157,6 +187,8 @@ public sealed partial class LauncherSettingsPageViewModel : ViewModelBase, IDisp ResolveCulture(), L("settings.launcher.hidden_summary_format", "{0} hidden items"), HiddenItems.Count); + + ShowTileBackground = snapshot.ShowTileBackground; } private StartMenuFolderNode LoadCatalogSafe() @@ -317,6 +349,10 @@ public sealed partial class LauncherSettingsPageViewModel : ViewModelBase, IDisp HiddenDescription = L("settings.launcher.hidden_desc", "Review hidden launcher entries and show them again."); HiddenHint = L("settings.launcher.hidden_hint", "In desktop edit mode, select a launcher icon and click Hide. Hidden entries appear here."); HiddenEmptyText = L("settings.launcher.hidden_empty", "No hidden items."); + AppearanceHeader = L("settings.launcher.appearance_header", "Appearance"); + AppearanceDescription = L("settings.launcher.appearance_desc", "Customize the appearance of the App Launcher."); + ShowTileBackgroundHeader = L("settings.launcher.show_tile_background_header", "Show tile background"); + ShowTileBackgroundDescription = L("settings.launcher.show_tile_background_desc", "Display a background card behind each app icon in the launcher."); } private CultureInfo ResolveCulture() diff --git a/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs b/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs index a00256d..7c8cd72 100644 --- a/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs +++ b/LanMountainDesktop/Views/MainWindow.ComponentSystem.cs @@ -400,10 +400,12 @@ public partial class MainWindow if (OperatingSystem.IsWindows()) { + // Windows: 使用 SlideToShutDown 滑动关机界面 _powerService.ShowNativePowerUI(PowerAction.Shutdown); } else { + // Linux: 二次确认对话框 await ShowPowerConfirmDialogAsync(L("power.shutdown_confirm_title", "Shutdown"), L("power.shutdown_confirm_message", "Are you sure you want to shut down this computer?"), () => _powerService.ShutdownAsync()); @@ -416,16 +418,11 @@ public partial class MainWindow _ = e; ClosePopupIfOpen(); - if (OperatingSystem.IsWindows()) - { - _powerService.ShowNativePowerUI(PowerAction.Restart); - } - else - { - await ShowPowerConfirmDialogAsync(L("power.restart_confirm_title", "Restart"), - L("power.restart_confirm_message", "Are you sure you want to restart this computer?"), - () => _powerService.RestartAsync()); - } + // 所有平台:统一使用二次确认对话框 + // Note: SlideToShutDown.exe 只支持关机,不支持重启 + await ShowPowerConfirmDialogAsync(L("power.restart_confirm_title", "Restart"), + L("power.restart_confirm_message", "Are you sure you want to restart this computer?"), + () => _powerService.RestartAsync()); } private async void OnPowerLogoutClick(object? sender, RoutedEventArgs e) diff --git a/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs b/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs index b066de4..33efce2 100644 --- a/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs +++ b/LanMountainDesktop/Views/MainWindow.DesktopPaging.cs @@ -47,6 +47,7 @@ public partial class MainWindow private readonly Stack _launcherFolderStack = []; private readonly HashSet _hiddenLauncherFolderPaths = new(StringComparer.OrdinalIgnoreCase); private readonly HashSet _hiddenLauncherAppPaths = new(StringComparer.OrdinalIgnoreCase); + private bool _showLauncherTileBackground = true; private Button? _selectedLauncherTileButton; private LauncherEntryKind? _selectedLauncherEntryKind; private string? _selectedLauncherEntryKey; @@ -116,6 +117,8 @@ public partial class MainWindow } } } + + _showLauncherTileBackground = snapshot.ShowTileBackground; } private void InitializeDesktopSurfaceSwipeHandlers() @@ -1137,7 +1140,6 @@ public partial class MainWindow var button = new Button { - Classes = { "glass-panel" }, Margin = new Thickness(0, 0, 12, 12), BorderThickness = new Thickness(0), BorderBrush = Brushes.Transparent, @@ -1146,6 +1148,16 @@ public partial class MainWindow Content = content // 不设置固定 Width 和 Height,由 UpdateLauncherTileLayout 动态设置 }; + + // 根据设置决定是否显示背景 + if (_showLauncherTileBackground) + { + button.Classes.Add("glass-panel"); + } + else + { + button.Background = Brushes.Transparent; + } button.Click += (_, _) => { if (_isComponentLibraryOpen) @@ -1676,7 +1688,6 @@ public partial class MainWindow var button = new Button { - Classes = { "glass-panel" }, HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, BorderThickness = new Thickness(0), @@ -1684,6 +1695,17 @@ public partial class MainWindow Padding = new Thickness(8, 8, 8, 6), Content = content }; + + // 根据设置决定是否显示背景 + if (_showLauncherTileBackground) + { + button.Classes.Add("glass-panel"); + } + else + { + button.Background = Brushes.Transparent; + } + button.Click += (_, _) => { if (_isComponentLibraryOpen) @@ -1745,7 +1767,6 @@ public partial class MainWindow var button = new Button { - Classes = { "glass-panel" }, HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, BorderThickness = new Thickness(0), @@ -1753,6 +1774,17 @@ public partial class MainWindow Padding = new Thickness(8, 8, 8, 6), Content = content }; + + // 根据设置决定是否显示背景 + if (_showLauncherTileBackground) + { + button.Classes.Add("glass-panel"); + } + else + { + button.Background = Brushes.Transparent; + } + button.Click += (_, _) => { if (_isComponentLibraryOpen) diff --git a/LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs b/LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs index 61ab1cc..bede200 100644 --- a/LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs +++ b/LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs @@ -44,6 +44,23 @@ public partial class MainWindow return; } + // 启动台设置变化时,重新渲染启动台图标 + if (e.Scope == SettingsScope.Launcher && e.ChangedKeys is { Count: > 0 }) + { + var changedKeys = e.ChangedKeys.ToArray(); + if (changedKeys.Any(key => + string.Equals(key, nameof(LauncherSettingsSnapshot.ShowTileBackground), StringComparison.OrdinalIgnoreCase))) + { + Dispatcher.UIThread.Post(() => + { + var launcherSnapshot = _settingsService.LoadSnapshot(SettingsScope.Launcher); + InitializeLauncherVisibilitySettings(launcherSnapshot); + RenderLauncherRootTiles(); + }, DispatcherPriority.Background); + return; + } + } + if (e.Scope == SettingsScope.App && e.ChangedKeys is { Count: > 0 }) { var changedKeys = e.ChangedKeys.ToArray(); diff --git a/LanMountainDesktop/Views/SettingsPages/LauncherSettingsPage.axaml b/LanMountainDesktop/Views/SettingsPages/LauncherSettingsPage.axaml index 405f6bf..e6ce7c0 100644 --- a/LanMountainDesktop/Views/SettingsPages/LauncherSettingsPage.axaml +++ b/LanMountainDesktop/Views/SettingsPages/LauncherSettingsPage.axaml @@ -4,6 +4,7 @@ xmlns:controls="using:LanMountainDesktop.Controls" xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:fi="using:FluentIcons.Avalonia.Fluent" + xmlns:symbol="using:FluentIcons.Common" x:Class="LanMountainDesktop.Views.SettingsPages.LauncherSettingsPage" x:DataType="vm:LauncherSettingsPageViewModel"> @@ -52,9 +53,33 @@ + + + + + + + + + + + + + + + + + - - -