Add Windows system chrome patchers (Harmony)

Introduce support for toggling the system chrome on Windows using Harmony patchers. Adds Lib.Harmony.Thin to package props and project, new patcher infrastructure (ChromePatchState, PatcherEntrance) and two Harmony patches that disable FluentAvalonia's Windows chrome when configured. Program.cs now loads the chrome setting and installs patchers conditionally on Windows/x86-x64. Settings viewmodel and view updated: expose IsWindowsOs, require restart on appearance changes, migrate SettingsWindow to FAAppWindow and adapt titlebar/layout (include Windows caption placeholder and footer menu items). Also add a .gitkeep and a build log file.
This commit is contained in:
lincube
2026-05-04 02:31:25 +08:00
parent 458494d131
commit 3a8516334a
12 changed files with 266 additions and 112 deletions

1
.cursor/skills/.gitkeep Normal file
View File

@@ -0,0 +1 @@

View File

@@ -16,6 +16,7 @@
<PackageVersion Include="Downloader" Version="5.4.0" /> <PackageVersion Include="Downloader" Version="5.4.0" />
<PackageVersion Include="FluentAvaloniaUI" Version="3.0.0-preview2" /> <PackageVersion Include="FluentAvaloniaUI" Version="3.0.0-preview2" />
<PackageVersion Include="FluentIcons.Avalonia" Version="2.1.325" /> <PackageVersion Include="FluentIcons.Avalonia" Version="2.1.325" />
<PackageVersion Include="Lib.Harmony.Thin" Version="2.4.2" />
<PackageVersion Include="Material.Avalonia" Version="3.16.1" /> <PackageVersion Include="Material.Avalonia" Version="3.16.1" />
<PackageVersion Include="MaterialColorUtilities" Version="0.3.0" /> <PackageVersion Include="MaterialColorUtilities" Version="0.3.0" />
<PackageVersion Include="Material.Icons.Avalonia" Version="3.0.3-nightly.0.2" /> <PackageVersion Include="Material.Icons.Avalonia" Version="3.0.3-nightly.0.2" />

View File

@@ -56,6 +56,7 @@
<PackageReference Include="Downloader" /> <PackageReference Include="Downloader" />
<PackageReference Include="FluentAvaloniaUI" /> <PackageReference Include="FluentAvaloniaUI" />
<PackageReference Include="FluentIcons.Avalonia" /> <PackageReference Include="FluentIcons.Avalonia" />
<PackageReference Include="Lib.Harmony.Thin" />
<PackageReference Include="Material.Avalonia" /> <PackageReference Include="Material.Avalonia" />
<PackageReference Include="Material.Icons.Avalonia" /> <PackageReference Include="Material.Icons.Avalonia" />
<PackageReference Include="ClassIsland.Markdown.Avalonia" /> <PackageReference Include="ClassIsland.Markdown.Avalonia" />

View File

@@ -0,0 +1,6 @@
namespace LanMountainDesktop.Platform.Windows;
internal static class ChromePatchState
{
public static bool UseSystemChrome { get; set; }
}

View File

@@ -0,0 +1,12 @@
using HarmonyLib;
namespace LanMountainDesktop.Platform.Windows;
internal static class PatcherEntrance
{
public static void InstallPatchers()
{
var harmony = new Harmony("dev.lanmountain.desktop.patchers");
harmony.PatchAll(typeof(PatcherEntrance).Assembly);
}
}

View File

@@ -0,0 +1,25 @@
using System.Runtime.CompilerServices;
using Avalonia;
using Avalonia.Controls;
using FluentAvalonia.UI.Windowing;
using LanMountainDesktop.Platform.Windows;
using HarmonyLib;
namespace LanMountainDesktop.Platform.Windows.Patches;
[HarmonyPatch(typeof(FAAppWindow), "InitializeAppWindow")]
internal class AppWindowInitializeAppWindowPatcher
{
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "get_PseudoClasses")]
private static extern IPseudoClasses GetPseudoClasses(StyledElement window);
[UnsafeAccessor(UnsafeAccessorKind.Method, Name = "set_IsWindows")]
private static extern void SetIsWindowsProperty(FAAppWindow window, bool v);
static void Postfix(FAAppWindow __instance)
{
if (!ChromePatchState.UseSystemChrome) return;
GetPseudoClasses(__instance).Remove(":windows");
SetIsWindowsProperty(__instance, false);
}
}

View File

@@ -0,0 +1,21 @@
using FluentAvalonia.UI.Windowing;
using HarmonyLib;
using LanMountainDesktop.Platform.Windows;
namespace LanMountainDesktop.Platform.Windows.Patches;
[HarmonyPatch]
internal class Win32WindowManagerConstructorPatcher
{
[HarmonyTargetMethod]
static System.Reflection.MethodBase TargetMethod()
{
var type = AccessTools.TypeByName("FluentAvalonia.UI.Windowing.Win32WindowManager");
return AccessTools.Constructor(type!, [typeof(FAAppWindow)]);
}
static bool Prefix(FAAppWindow window)
{
return !ChromePatchState.UseSystemChrome;
}
}

View File

@@ -87,6 +87,8 @@ public sealed class Program
AppLogger.Info("SingleInstance", "Activation acknowledged before Avalonia App was ready."); AppLogger.Info("SingleInstance", "Activation acknowledged before Avalonia App was ready.");
}); });
LoadChromePatchState();
InstallChromePatchersIfNeeded();
BuildAvaloniaApp(renderMode).StartWithClassicDesktopLifetime(args); BuildAvaloniaApp(renderMode).StartWithClassicDesktopLifetime(args);
AppLogger.Info("Startup", "Application exited normally."); AppLogger.Info("Startup", "Application exited normally.");
} }
@@ -198,6 +200,49 @@ public sealed class Program
} }
} }
private static void LoadChromePatchState()
{
try
{
var snapshot = HostSettingsFacadeProvider.GetOrCreate()
.Settings
.LoadSnapshot<AppSettingsSnapshot>(LanMountainDesktop.PluginSdk.SettingsScope.App);
if (OperatingSystem.IsWindows())
{
LanMountainDesktop.Platform.Windows.ChromePatchState.UseSystemChrome = snapshot.UseSystemChrome;
}
}
catch (Exception ex)
{
AppLogger.Warn("Startup", "Failed to load chrome patch state. Falling back to FA chrome.", ex);
}
}
private static void InstallChromePatchersIfNeeded()
{
if (!OperatingSystem.IsWindows())
{
return;
}
var arch = System.Runtime.InteropServices.RuntimeInformation.OSArchitecture;
if (arch != System.Runtime.InteropServices.Architecture.X64 &&
arch != System.Runtime.InteropServices.Architecture.X86)
{
return;
}
try
{
LanMountainDesktop.Platform.Windows.PatcherEntrance.InstallPatchers();
AppLogger.Info("Startup", $"Chrome patchers installed. UseSystemChrome={LanMountainDesktop.Platform.Windows.ChromePatchState.UseSystemChrome}.");
}
catch (Exception ex)
{
AppLogger.Warn("Startup", "Failed to install chrome patchers.", ex);
}
}
private static void WaitForRestartParentExit(int processId, DateTime deadlineUtc) private static void WaitForRestartParentExit(int processId, DateTime deadlineUtc)
{ {
try try

View File

@@ -31,12 +31,14 @@ public sealed partial class SettingsWindowViewModel : ViewModelBase
{ {
_localizationService = new(); _localizationService = new();
_languageCode = "zh-CN"; _languageCode = "zh-CN";
IsWindowsOs = OperatingSystem.IsWindows();
} }
public SettingsWindowViewModel(LocalizationService localizationService, string languageCode) public SettingsWindowViewModel(LocalizationService localizationService, string languageCode)
{ {
_localizationService = localizationService; _localizationService = localizationService;
_languageCode = languageCode; _languageCode = languageCode;
IsWindowsOs = OperatingSystem.IsWindows();
} }
private string L(string key) => _localizationService.GetString(_languageCode, key, key); private string L(string key) => _localizationService.GetString(_languageCode, key, key);
@@ -86,6 +88,10 @@ public sealed partial class SettingsWindowViewModel : ViewModelBase
[ObservableProperty] [ObservableProperty]
private bool _isDrawerOpen; private bool _isDrawerOpen;
/// <summary>用于标题栏右侧系统按钮占位(与 SecRandom / ClassIsland 一致,仅 Windows 显示)。</summary>
[ObservableProperty]
private bool _isWindowsOs;
public SettingsWindowViewModel Initialize() public SettingsWindowViewModel Initialize()
{ {
RefreshLanguage(_languageCode); RefreshLanguage(_languageCode);
@@ -855,7 +861,7 @@ public sealed partial class AppearanceSettingsPageViewModel : ViewModelBase
return; return;
} }
PersistCurrentState(restartRequired: false); PersistCurrentState(restartRequired: true);
} }
partial void OnSelectedCornerRadiusStyleChanged(SelectionOption? value) partial void OnSelectedCornerRadiusStyleChanged(SelectionOption? value)

View File

@@ -1,26 +1,26 @@
<Window xmlns="https://github.com/avaloniaui" <faWindowing:FAAppWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:LanMountainDesktop.ViewModels" xmlns:vm="using:LanMountainDesktop.ViewModels"
xmlns:ui="using:FluentAvalonia.UI.Controls" xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:fi="using:FluentIcons.Avalonia" xmlns:fi="using:FluentIcons.Avalonia"
x:Class="LanMountainDesktop.Views.SettingsWindow" xmlns:faWindowing="using:FluentAvalonia.UI.Windowing"
x:DataType="vm:SettingsWindowViewModel" x:Class="LanMountainDesktop.Views.SettingsWindow"
Width="1120" x:DataType="vm:SettingsWindowViewModel"
Height="760" Width="1120"
MinWidth="560" Height="760"
MinHeight="480" MinWidth="560"
CanResize="True" MinHeight="480"
WindowStartupLocation="Manual" CanResize="True"
WindowDecorations="BorderOnly" WindowStartupLocation="Manual"
FontFamily="{DynamicResource AppFontFamily}" FontFamily="{DynamicResource AppFontFamily}"
Background="Transparent" Background="Transparent"
Title="{Binding Title}"> Title="{Binding Title}">
<Window.Resources> <faWindowing:FAAppWindow.Resources>
<x:Double x:Key="SettingsContainerMaxWidth">960</x:Double> <x:Double x:Key="SettingsContainerMaxWidth">960</x:Double>
</Window.Resources> </faWindowing:FAAppWindow.Resources>
<Window.Styles> <faWindowing:FAAppWindow.Styles>
<Style Selector="Grid.page-title-container"> <Style Selector="Grid.page-title-container">
<Setter Property="Margin" Value="0,16,0,0" /> <Setter Property="Margin" Value="0,16,0,0" />
<Setter Property="MaxWidth" Value="{DynamicResource SettingsContainerMaxWidth}" /> <Setter Property="MaxWidth" Value="{DynamicResource SettingsContainerMaxWidth}" />
@@ -34,94 +34,107 @@
<Style Selector="TextBlock.page-title-text:narrow"> <Style Selector="TextBlock.page-title-text:narrow">
<Setter Property="FontSize" Value="24" /> <Setter Property="FontSize" Value="24" />
</Style> </Style>
</Window.Styles> </faWindowing:FAAppWindow.Styles>
<Grid x:Name="RootGrid" <Grid x:Name="RootGrid"
Classes="settings-scope" Classes="settings-scope"
Background="{DynamicResource AdaptiveSettingsWindowBackgroundBrush}" Background="{DynamicResource AdaptiveSettingsWindowBackgroundBrush}"
RowDefinitions="Auto,*"> RowDefinitions="Auto,*">
<!-- 顶栏布局对齐 SecRandom折叠/品牌/标题)+ 中(透明拖窗区)+ 右(重启 / Windows caption 占位) -->
<Border x:Name="WindowTitleBarHost" <Border x:Name="WindowTitleBarHost"
Height="48" Height="48"
Padding="12,0,12,0" Background="Transparent"
Background="{DynamicResource AdaptiveSettingsWindowBackgroundBrush}"
BorderBrush="{DynamicResource AdaptiveSettingsWindowBorderBrush}" BorderBrush="{DynamicResource AdaptiveSettingsWindowBorderBrush}"
BorderThickness="0,0,0,1" BorderThickness="0,0,0,1">
PointerPressed="OnWindowTitleBarPointerPressed"> <Grid ColumnDefinitions="Auto,*,Auto"
<Grid ColumnDefinitions="Auto,Auto,*,Auto,Auto" VerticalAlignment="Stretch">
ColumnSpacing="8" <StackPanel Grid.Column="0"
VerticalAlignment="Center">
<Button x:Name="TogglePaneButton"
Classes="pane-toggle-button"
Click="OnTogglePaneButtonClick">
<Grid>
<fi:FluentIcon x:Name="TogglePaneButtonIcon"
Icon="Navigation"
IconVariant="Regular"
FontSize="16" />
</Grid>
</Button>
<fi:FluentIcon x:Name="WindowBrandIcon"
Grid.Column="1"
Margin="6,0,2,0"
Icon="Settings"
IconVariant="Filled"
IsHitTestVisible="False"
VerticalAlignment="Center" />
<StackPanel Grid.Column="2"
Orientation="Horizontal" Orientation="Horizontal"
Margin="8,0,8,0"
Spacing="8"
VerticalAlignment="Center">
<Button x:Name="TogglePaneButton"
Classes="pane-toggle-button"
Margin="-7,-8,-8,-8"
MinWidth="40"
Width="48"
VerticalAlignment="Center" VerticalAlignment="Center"
Spacing="10"> IsVisible="{Binding !#RootNavigationView.IsPaneToggleButtonVisible}"
Click="OnTogglePaneButtonClick">
<Grid>
<fi:FluentIcon x:Name="TogglePaneButtonIcon"
Icon="Navigation"
IconVariant="Regular"
FontSize="16" />
</Grid>
</Button>
<fi:FluentIcon x:Name="WindowBrandIcon"
Margin="0,0,0,0"
Icon="Settings"
IconVariant="Filled"
IsHitTestVisible="False"
VerticalAlignment="Center" />
<TextBlock x:Name="WindowTitleTextBlock" <TextBlock x:Name="WindowTitleTextBlock"
FontSize="12" FontSize="12"
FontWeight="SemiBold" FontWeight="SemiBold"
Margin="8,0,0,0"
VerticalAlignment="Center"
IsHitTestVisible="False" IsHitTestVisible="False"
Text="{Binding Title}" /> Text="{Binding Title}" />
</StackPanel> </StackPanel>
<Button x:Name="RestartNowButton" <Border x:Name="TitleBarDragZone"
Grid.Column="3" Grid.Column="1"
Padding="10,6"
Margin="0,0,4,0"
Background="Transparent" Background="Transparent"
IsVisible="{Binding IsRestartRequested}" PointerPressed="OnTitleBarDragZonePointerPressed" />
Click="OnRestartNowClick">
<StackPanel Orientation="Horizontal"
Spacing="6">
<fi:FluentIcon x:Name="RestartButtonIcon"
Icon="ArrowSync"
IconVariant="Regular" />
<TextBlock x:Name="RestartButtonTextBlock"
Text="{Binding RestartButtonText}" />
</StackPanel>
</Button>
<Button x:Name="CloseWindowButton" <StackPanel Grid.Column="2"
Grid.Column="4" Orientation="Horizontal"
Width="40" Spacing="8"
Height="32" VerticalAlignment="Center"
Padding="0" Margin="0,0,8,0">
Background="Transparent" <Button x:Name="RestartNowButton"
BorderThickness="0" Padding="10,6"
Click="OnCloseWindowClick"> Margin="0,-8,0,-8"
<fi:FluentIcon x:Name="CloseWindowButtonIcon" VerticalAlignment="Center"
Icon="Dismiss" Background="Transparent"
IconVariant="Regular" /> IsVisible="{Binding IsRestartRequested}"
</Button> Click="OnRestartNowClick">
<StackPanel Orientation="Horizontal"
Spacing="6">
<fi:FluentIcon x:Name="RestartButtonIcon"
Icon="ArrowSync"
IconVariant="Regular" />
<TextBlock x:Name="RestartButtonTextBlock"
Text="{Binding RestartButtonText}" />
</StackPanel>
</Button>
<Border Width="140"
Background="Transparent"
IsHitTestVisible="False"
IsVisible="{Binding IsWindowsOs}" />
</StackPanel>
</Grid> </Grid>
</Border> </Border>
<ui:FANavigationView x:Name="RootNavigationView" <ui:FANavigationView x:Name="RootNavigationView"
Grid.Row="1" Grid.Row="1"
Margin="0,8,0,0" Margin="0"
Background="Transparent" Background="Transparent"
PaneDisplayMode="Auto" PaneDisplayMode="Auto"
OpenPaneLength="283" OpenPaneLength="283"
IsSettingsVisible="False" IsSettingsVisible="False"
IsPaneToggleButtonVisible="False"
IsBackButtonVisible="False" IsBackButtonVisible="False"
SelectionChanged="OnNavigationSelectionChanged"> SelectionChanged="OnNavigationSelectionChanged">
<ui:FANavigationView.Styles>
<Style Selector="ui|FANavigationView#RootNavigationView:minimal">
<Setter Property="IsPaneToggleButtonVisible" Value="False"/>
</Style>
</ui:FANavigationView.Styles>
<ui:FANavigationView.Resources> <ui:FANavigationView.Resources>
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" /> <SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
<SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" /> <SolidColorBrush x:Key="NavigationViewContentGridBorderBrush" Color="Transparent" />
@@ -182,4 +195,4 @@
</Grid> </Grid>
</ui:FANavigationView> </ui:FANavigationView>
</Grid> </Grid>
</Window> </faWindowing:FAAppWindow>

View File

@@ -5,9 +5,10 @@ using System.Threading.Tasks;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Platform; using Avalonia.Media;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using LanMountainDesktop.PluginSdk; using LanMountainDesktop.PluginSdk;
using LanMountainDesktop.Services; using LanMountainDesktop.Services;
using LanMountainDesktop.Services.Settings; using LanMountainDesktop.Services.Settings;
@@ -16,7 +17,7 @@ using Symbol = FluentIcons.Common.Symbol;
namespace LanMountainDesktop.Views; namespace LanMountainDesktop.Views;
public partial class SettingsWindow : Window, ISettingsPageHostContext public partial class SettingsWindow : FAAppWindow, ISettingsPageHostContext
{ {
private const double BaseSettingsContainerWidth = 960d; private const double BaseSettingsContainerWidth = 960d;
private const double MinSettingsContentWidth = 320d; private const double MinSettingsContentWidth = 320d;
@@ -56,7 +57,7 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
_hostApplicationLifecycle = hostApplicationLifecycle; _hostApplicationLifecycle = hostApplicationLifecycle;
DataContext = ViewModel; DataContext = ViewModel;
InitializeComponent(); InitializeComponent();
Icon = _appLogoService.CreateWindowIcon(); SetValue(Window.IconProperty, _appLogoService.CreateWindowIcon());
ApplyChromeMode(useSystemChrome); ApplyChromeMode(useSystemChrome);
if (RootNavigationView is not null) if (RootNavigationView is not null)
@@ -75,6 +76,14 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
private void OnLoaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e) private void OnLoaded(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{ {
TitleBar.Height = 48;
TitleBar.ExtendsContentIntoTitleBar = true;
// SecRandom MainWindow标题栏按钮悬停/按下/非活动色,与系统 caption 更一致
TitleBar.ButtonHoverBackgroundColor = Color.FromArgb(23, 0, 0, 0);
TitleBar.ButtonPressedBackgroundColor = Color.FromArgb(52, 0, 0, 0);
TitleBar.ButtonInactiveForegroundColor = Colors.Gray;
SyncPendingRestartState(); SyncPendingRestartState();
SyncTitleText(); SyncTitleText();
UpdateChromeMetrics(); UpdateChromeMetrics();
@@ -160,11 +169,11 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
{ {
_useSystemChrome = useSystemChrome || OperatingSystem.IsMacOS(); _useSystemChrome = useSystemChrome || OperatingSystem.IsMacOS();
ExtendClientAreaToDecorationsHint = true;
WindowDecorations = WindowDecorations.Full;
if (_useSystemChrome) if (_useSystemChrome)
{ {
ExtendClientAreaToDecorationsHint = true;
WindowDecorations = WindowDecorations.Full;
if (WindowTitleBarHost is { }) if (WindowTitleBarHost is { })
{ {
WindowTitleBarHost.IsVisible = false; WindowTitleBarHost.IsVisible = false;
@@ -172,9 +181,6 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
return; return;
} }
WindowDecorations = WindowDecorations.BorderOnly;
ExtendClientAreaToDecorationsHint = true;
if (WindowTitleBarHost is { }) if (WindowTitleBarHost is { })
{ {
WindowTitleBarHost.IsVisible = true; WindowTitleBarHost.IsVisible = true;
@@ -195,21 +201,32 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
} }
RootNavigationView.MenuItems.Clear(); RootNavigationView.MenuItems.Clear();
RootNavigationView.FooterMenuItems.Clear();
SettingsPageCategory? previousCategory = null; SettingsPageCategory? previousCategory = null;
foreach (var page in ViewModel.Pages) foreach (var page in ViewModel.Pages)
{ {
var item = new FANavigationViewItem
{
Content = page.Title,
Tag = page.PageId,
IconSource = CreateSettingsIconSource(MapIcon(page.IconKey))
};
if (page.Category == SettingsPageCategory.About ||
page.Category == SettingsPageCategory.Dev)
{
RootNavigationView.FooterMenuItems.Add(item);
continue;
}
if (previousCategory is not null && previousCategory != page.Category) if (previousCategory is not null && previousCategory != page.Category)
{ {
RootNavigationView.MenuItems.Add(new FANavigationViewItemSeparator()); RootNavigationView.MenuItems.Add(new FANavigationViewItemSeparator());
} }
RootNavigationView.MenuItems.Add(new FANavigationViewItem RootNavigationView.MenuItems.Add(item);
{
Content = page.Title,
Tag = page.PageId,
IconSource = CreateSettingsIconSource(MapIcon(page.IconKey))
});
previousCategory = page.Category; previousCategory = page.Category;
} }
@@ -293,7 +310,10 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
return; return;
} }
foreach (var item in RootNavigationView.MenuItems.OfType<FANavigationViewItem>()) var allItems = RootNavigationView.MenuItems.OfType<FANavigationViewItem>()
.Concat(RootNavigationView.FooterMenuItems.OfType<FANavigationViewItem>());
foreach (var item in allItems)
{ {
if (string.Equals(item.Tag as string, pageId, StringComparison.OrdinalIgnoreCase)) if (string.Equals(item.Tag as string, pageId, StringComparison.OrdinalIgnoreCase))
{ {
@@ -494,7 +514,7 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
TelemetryServices.Usage?.TrackSettingsWindowClosed("SettingsWindow.OnClosed", ViewModel.CurrentPageId); TelemetryServices.Usage?.TrackSettingsWindowClosed("SettingsWindow.OnClosed", ViewModel.CurrentPageId);
} }
private void OnWindowTitleBarPointerPressed(object? sender, PointerPressedEventArgs e) private void OnTitleBarDragZonePointerPressed(object? sender, PointerPressedEventArgs e)
{ {
_ = sender; _ = sender;
if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed) if (e.GetCurrentPoint(this).Properties.IsLeftButtonPressed)
@@ -518,13 +538,6 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
RequestResponsiveLayoutRefresh(); RequestResponsiveLayoutRefresh();
} }
private void OnCloseWindowClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
{
_ = sender;
_ = e;
Close();
}
private void OnRootNavigationViewPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e) private void OnRootNavigationViewPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{ {
_ = sender; _ = sender;
@@ -573,6 +586,10 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
{ {
return; return;
} }
TogglePaneButtonIcon.Icon = RootNavigationView.IsPaneOpen
? FluentIcons.Common.Icon.LineHorizontal3
: FluentIcons.Common.Icon.Navigation;
} }
private void UpdateChromeMetrics() private void UpdateChromeMetrics()
@@ -594,8 +611,6 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
RestartNowButton is null || RestartNowButton is null ||
RestartButtonIcon is null || RestartButtonIcon is null ||
RestartButtonTextBlock is null || RestartButtonTextBlock is null ||
CloseWindowButton is null ||
CloseWindowButtonIcon is null ||
DrawerTitleTextBlock is null || DrawerTitleTextBlock is null ||
RootNavigationView is null) RootNavigationView is null)
{ {
@@ -606,7 +621,7 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
var height = Bounds.Height > 1 ? Bounds.Height : Math.Max(Height, MinHeight); var height = Bounds.Height > 1 ? Bounds.Height : Math.Max(Height, MinHeight);
var layoutScale = Math.Clamp(Math.Min(width / 1120d, height / 760d), 0.90, 1.18); var layoutScale = Math.Clamp(Math.Min(width / 1120d, height / 760d), 0.90, 1.18);
var titleBarHeight = Math.Clamp(48d * layoutScale, 44d, 58d); const double titleBarHeight = 48d;
var titleBarButtonWidth = Math.Clamp(40d * layoutScale, 36d, 48d); var titleBarButtonWidth = Math.Clamp(40d * layoutScale, 36d, 48d);
var titleBarButtonHeight = Math.Clamp(32d * layoutScale, 30d, 38d); var titleBarButtonHeight = Math.Clamp(32d * layoutScale, 30d, 38d);
var titleFontSize = Math.Clamp(12d * layoutScale, 11d, 14d); var titleFontSize = Math.Clamp(12d * layoutScale, 11d, 14d);
@@ -618,7 +633,6 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
ExtendClientAreaTitleBarHeightHint = titleBarHeight; ExtendClientAreaTitleBarHeightHint = titleBarHeight;
WindowTitleBarHost.Height = titleBarHeight; WindowTitleBarHost.Height = titleBarHeight;
WindowTitleBarHost.Padding = new Thickness(chromePadding, 0, chromePadding, 0);
TogglePaneButton.Width = titleBarButtonWidth; TogglePaneButton.Width = titleBarButtonWidth;
TogglePaneButton.Height = titleBarButtonHeight; TogglePaneButton.Height = titleBarButtonHeight;
@@ -636,10 +650,6 @@ public partial class SettingsWindow : Window, ISettingsPageHostContext
RestartButtonIcon.FontSize = titleBarIconSize; RestartButtonIcon.FontSize = titleBarIconSize;
RestartButtonTextBlock.FontSize = titleFontSize; RestartButtonTextBlock.FontSize = titleFontSize;
CloseWindowButton.Width = titleBarButtonWidth;
CloseWindowButton.Height = titleBarButtonHeight;
CloseWindowButtonIcon.FontSize = titleBarIconSize;
DrawerTitleTextBlock.FontSize = drawerTitleFontSize; DrawerTitleTextBlock.FontSize = drawerTitleFontSize;
} }

13
_b.txt Normal file
View File

@@ -0,0 +1,13 @@
正在确定要还原的项目…
已还原 D:\github\LanMountainDesktop\LanMountainDesktop.PluginIsolation.Contracts\LanMountainDesktop.PluginIsolation.Contracts.csproj (用时 265 毫秒)。
已还原 D:\github\LanMountainDesktop\LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj (用时 597 毫秒)。
已还原 D:\github\LanMountainDesktop\LanMountainDesktop.Shared.IPC\LanMountainDesktop.Shared.IPC.csproj (用时 264 毫秒)。
C:\Program Files\dotnet\sdk\10.0.201\NuGet.targets(196,5): error : 磁盘空间不足。 [D:\github\LanMountainDesktop\LanMountainDesktop\LanMountainDesktop.csproj]
生成失败。
C:\Program Files\dotnet\sdk\10.0.201\NuGet.targets(196,5): error : 磁盘空间不足。 [D:\github\LanMountainDesktop\LanMountainDesktop\LanMountainDesktop.csproj]
0 个警告
1 个错误
已用时间 00:00:07.94