From c57a142b3bfa40e67fea294b5030c14e8e9cbe39 Mon Sep 17 00:00:00 2001 From: YsLtr Date: Wed, 25 Mar 2026 10:47:43 +0800 Subject: [PATCH] Fix Linux desktop title bar theming --- v2rayN/v2rayN.Desktop/Views/MainWindow.axaml | 76 ++++++++++++++++- .../v2rayN.Desktop/Views/MainWindow.axaml.cs | 83 +++++++++++++++++++ 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml index 8d9a5f85..dd4d96cb 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml @@ -8,6 +8,7 @@ xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:view="using:v2rayN.Desktop.Views" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib" + x:Name="mainWindow" Title="v2rayN" Width="1200" Height="800" @@ -17,11 +18,84 @@ ShowInTaskbar="True" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> + + + + + - + + + + + + + + + + + + + + + + + diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 996e7c83..97612f0c 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -10,6 +10,7 @@ public partial class MainWindow : WindowBase { private static Config _config; private readonly WindowNotificationManager? _manager; + private IDisposable? _linuxWindowStateSubscription; private CheckUpdateView? _checkUpdateView; private BackupAndRestoreView? _backupAndRestoreView; private bool _blCloseByUser = false; @@ -162,6 +163,7 @@ public partial class MainWindow : WindowBase else { Title = $"{Utils.GetVersion()}"; + ConfigureLinuxTitleBar(); } menuAddServerViaScan.IsVisible = false; @@ -388,6 +390,81 @@ public partial class MainWindow : WindowBase await AppManager.Instance.AppExitAsync(true); } + private void ConfigureLinuxTitleBar() + { + if (!Utils.IsLinux()) + { + return; + } + + linuxTitleBar.IsVisible = true; + SystemDecorations = SystemDecorations.BorderOnly; + btnLinuxMaximizeRestore.IsVisible = CanResize; + + _linuxWindowStateSubscription = this + .GetObservable(WindowStateProperty) + .Subscribe(_ => UpdateLinuxTitleBarWindowState()); + UpdateLinuxTitleBarWindowState(); + } + + private void UpdateLinuxTitleBarWindowState() + { + txtLinuxMaximizeRestore.Text = WindowState == WindowState.Maximized ? "❐" : "□"; + } + + private void LinuxTitleBar_PointerPressed(object? sender, PointerPressedEventArgs e) + { + if (!Utils.IsLinux() || e.GetCurrentPoint(this).Properties.IsLeftButtonPressed == false) + { + return; + } + + BeginMoveDrag(e); + } + + private void LinuxTitleBar_DoubleTapped(object? sender, TappedEventArgs e) + { + if (!Utils.IsLinux() || !CanResize) + { + return; + } + + ToggleLinuxWindowState(); + } + + private void BtnLinuxMinimize_Click(object? sender, RoutedEventArgs e) + { + WindowState = WindowState.Minimized; + } + + private void BtnLinuxMaximizeRestore_Click(object? sender, RoutedEventArgs e) + { + ToggleLinuxWindowState(); + } + + private void BtnLinuxClose_Click(object? sender, RoutedEventArgs e) + { + HideToTray(); + } + + private void ToggleLinuxWindowState() + { + WindowState = WindowState == WindowState.Maximized + ? WindowState.Normal + : WindowState.Maximized; + } + + private void HideToTray() + { + foreach (var ownedWindow in OwnedWindows) + { + ownedWindow.Close(); + } + + Hide(); + AppManager.Instance.ShowInTaskbar = false; + } + private void Shutdown(bool obj) { if (obj is bool b && _blCloseByUser == false) @@ -450,6 +527,12 @@ public partial class MainWindow : WindowBase RestoreUI(); } + protected override void OnClosed(EventArgs e) + { + _linuxWindowStateSubscription?.Dispose(); + base.OnClosed(e); + } + private void RestoreUI() { if (_config.UiItem.MainGirdHeight1 > 0 && _config.UiItem.MainGirdHeight2 > 0)