diff --git a/v2rayN/ServiceLib/Common/Utils.cs b/v2rayN/ServiceLib/Common/Utils.cs index 3907b1a7..2a00560a 100644 --- a/v2rayN/ServiceLib/Common/Utils.cs +++ b/v2rayN/ServiceLib/Common/Utils.cs @@ -1101,6 +1101,13 @@ public class Utils public static bool IsLinux() => OperatingSystem.IsLinux(); + public static bool IsWayland() => + OperatingSystem.IsLinux() + && ( + Environment.GetEnvironmentVariable("WAYLAND_DISPLAY").IsNotEmpty() + || string.Equals(Environment.GetEnvironmentVariable("XDG_SESSION_TYPE"), "wayland", StringComparison.OrdinalIgnoreCase) + ); + public static bool IsMacOS() => OperatingSystem.IsMacOS(); public static bool IsNonWindows() => !OperatingSystem.IsWindows(); diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index 6e7e183c..65dd938e 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -156,7 +156,7 @@ public class ProfilesViewModel : MyReactiveObject { await MoveServer(EMove.Bottom); }, canEditRemove); - MoveToGroupCmd = ReactiveCommand.CreateFromTask(async sub => + MoveToGroupCmd = ReactiveCommand.Create(sub => { SelectedMoveToGroup = sub; }); diff --git a/v2rayN/v2rayN.Desktop/App.axaml b/v2rayN/v2rayN.Desktop/App.axaml index 21204f60..fd648056 100644 --- a/v2rayN/v2rayN.Desktop/App.axaml +++ b/v2rayN/v2rayN.Desktop/App.axaml @@ -22,6 +22,24 @@ + + + diff --git a/v2rayN/v2rayN.Desktop/Base/WindowBase.cs b/v2rayN/v2rayN.Desktop/Base/WindowBase.cs index d1419b30..26fadc77 100644 --- a/v2rayN/v2rayN.Desktop/Base/WindowBase.cs +++ b/v2rayN/v2rayN.Desktop/Base/WindowBase.cs @@ -2,8 +2,17 @@ namespace v2rayN.Desktop.Base; public class WindowBase : ReactiveWindow where TViewModel : class { + private Border? _linuxTitleBar; + private Control? _linuxTitleBarDragRegion; + private Button? _linuxTitleBarCloseButton; + public WindowBase() { + if (Utils.IsWayland()) + { + SystemDecorations = SystemDecorations.BorderOnly; + } + Loaded += OnLoaded; } @@ -34,10 +43,13 @@ public class WindowBase : ReactiveWindow where TViewMode Position = new PixelPoint((int)x, (int)y); } catch { } + + ConfigureLinuxTitleBar(); } protected override void OnClosed(EventArgs e) { + ReleaseLinuxTitleBar(); base.OnClosed(e); try { @@ -45,4 +57,67 @@ public class WindowBase : ReactiveWindow where TViewMode } catch { } } + + protected virtual void HandleLinuxTitleBarClose() + { + Close(); + } + + private void ConfigureLinuxTitleBar() + { + if (!Utils.IsWayland()) + { + return; + } + + _linuxTitleBar ??= this.FindControl("linuxTitleBar"); + if (_linuxTitleBar == null) + { + return; + } + + _linuxTitleBar.IsVisible = true; + + _linuxTitleBarDragRegion ??= this.FindControl("linuxTitleBarDragRegion"); + if (_linuxTitleBarDragRegion != null) + { + _linuxTitleBarDragRegion.PointerPressed -= LinuxTitleBar_PointerPressed; + _linuxTitleBarDragRegion.PointerPressed += LinuxTitleBar_PointerPressed; + } + + _linuxTitleBarCloseButton ??= this.FindControl + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/AddServer2Window.axaml b/v2rayN/v2rayN.Desktop/Views/AddServer2Window.axaml index 0c9d89a4..b7517329 100644 --- a/v2rayN/v2rayN.Desktop/Views/AddServer2Window.axaml +++ b/v2rayN/v2rayN.Desktop/Views/AddServer2Window.axaml @@ -13,7 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml index 4dc378b4..f7712dc9 100644 --- a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml @@ -14,7 +14,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml index 3335785b..fda5aac2 100644 --- a/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml @@ -14,7 +14,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/FullConfigTemplateWindow.axaml b/v2rayN/v2rayN.Desktop/Views/FullConfigTemplateWindow.axaml index 1a2b482c..ddd4b614 100644 --- a/v2rayN/v2rayN.Desktop/Views/FullConfigTemplateWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/FullConfigTemplateWindow.axaml @@ -14,7 +14,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/GlobalHotkeySettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/GlobalHotkeySettingWindow.axaml index 8eb3b473..ae67bc8f 100644 --- a/v2rayN/v2rayN.Desktop/Views/GlobalHotkeySettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/GlobalHotkeySettingWindow.axaml @@ -13,7 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml index 8d9a5f85..74af4d43 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" @@ -21,7 +22,43 @@ Background="Gray" CloseOnClickAway="True" DisableOpeningAnimation="True"> - + + + + + + + + + + + + + + + diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index 996e7c83..9ab5ee3d 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -280,7 +280,14 @@ public partial class MainWindow : WindowBase { case WindowCloseReason.OwnerWindowClosing or WindowCloseReason.WindowClosing: e.Cancel = true; - ShowHideWindow(false); + if (Utils.IsLinux()) + { + HideToTray(); + } + else + { + ShowHideWindow(false); + } break; case WindowCloseReason.ApplicationShutdown or WindowCloseReason.OSShutdown: @@ -388,6 +395,22 @@ public partial class MainWindow : WindowBase await AppManager.Instance.AppExitAsync(true); } + protected override void HandleLinuxTitleBarClose() + { + HideToTray(); + } + + 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) @@ -426,7 +449,7 @@ public partial class MainWindow : WindowBase { if (Utils.IsLinux() && _config.UiItem.Hide2TrayWhenClose == false) { - WindowState = WindowState.Minimized; + HideToTray(); return; } diff --git a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml index 7d80088a..0507c52c 100644 --- a/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/OptionSettingWindow.axaml @@ -13,7 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml index 2dd44b54..a467a12c 100644 --- a/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/ProfilesSelectWindow.axaml @@ -12,8 +12,37 @@ x:DataType="vms:ProfilesSelectViewModel" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml index 30f74a14..b62ad64d 100644 --- a/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/RoutingRuleDetailsWindow.axaml @@ -13,7 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml index a770b3ed..e75fef56 100644 --- a/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/RoutingRuleSettingWindow.axaml @@ -13,7 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + @@ -253,5 +283,6 @@ - + + diff --git a/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml index a9155f7d..a39f6767 100644 --- a/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/RoutingSettingWindow.axaml @@ -13,8 +13,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - - + + + + + + + + + + + + + + @@ -138,5 +167,6 @@ - + + diff --git a/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml b/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml index 79216921..b9089de4 100644 --- a/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/SubEditWindow.axaml @@ -12,7 +12,37 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - + + + + + + + + + + + + + + - + + diff --git a/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml b/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml index 04870d4a..4b63fa2b 100644 --- a/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml +++ b/v2rayN/v2rayN.Desktop/Views/SubSettingWindow.axaml @@ -14,12 +14,43 @@ ShowInTaskbar="False" WindowStartupLocation="CenterScreen" mc:Ignorable="d"> - - + + + + + + + + + + + + + + + @@ -75,6 +106,7 @@ Header="{x:Static resx:ResUI.LvSort}" /> - - + + +