Browse Source

Fix window restoring and maximizing/fullscreen issues on macOS

Ruben 3 months ago
parent
commit
e778bbc337

+ 4 - 2
src/PicView.Avalonia.MacOS/Views/MacMainWindow.axaml.cs

@@ -28,7 +28,9 @@ public partial class MacMainWindow : Window
             {
                 return;
             }
-            Observable.EveryValueChanged(this, x => x.WindowState, _frameProvider).SubscribeAwait(async (state, _) =>
+            Observable.EveryValueChanged(this, x => x.WindowState, _frameProvider)
+                .Skip(1)
+                .SubscribeAwait(async (state, _) =>
             {
                 switch (state)
                 {
@@ -40,7 +42,7 @@ public partial class MacMainWindow : Window
 
                         break;
                     case WindowState.Maximized:
-                        if (!Settings.WindowProperties.Maximized)
+                        if (!Settings.WindowProperties.Maximized && !Settings.WindowProperties.Fullscreen)
                         {
                             await MacOSWindow.Maximize(this, vm);
                         }

+ 51 - 45
src/PicView.Avalonia.MacOS/WindowImpl/MacOSWindow.cs

@@ -1,4 +1,5 @@
 using Avalonia.Controls;
+using Avalonia.Threading;
 using PicView.Avalonia.MacOS.Views;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.WindowBehavior;
@@ -21,7 +22,7 @@ public static class MacOSWindow
     
     public static async Task ToggleMaximize(MacMainWindow? window, MainViewModel? vm, bool saveSettings = true)
     {
-        if (Settings.WindowProperties.Maximized)
+        if (window.WindowState == WindowState.Maximized || Settings.WindowProperties.Maximized)
         {
             await Restore(window, vm, saveSettings); 
         }
@@ -36,35 +37,44 @@ public static class MacOSWindow
         // Update settings
         Settings.WindowProperties.Maximized = false;
         Settings.WindowProperties.Fullscreen = false;
-        
-        window.WindowState = WindowState.Normal;
-        window.Topmost = Settings.WindowProperties.TopMost;
 
-        if (Settings.UIProperties.ShowInterface)
-        {
-            vm.MainWindow.IsTopToolbarShown.Value = true;
-            vm.MainWindow.IsBottomToolbarShown.Value = Settings.UIProperties.ShowBottomNavBar;
-            vm.MainWindow.IsUIShown.Value = true;
-        }
-        else
-        {
-            vm.MainWindow.IsTopToolbarShown.Value = false;
-            vm.MainWindow.IsUIShown.Value = false;
-        }
+        // Update UI state
+        vm.MainWindow.IsMaximized.Value = false;
+        vm.MainWindow.IsFullscreen.Value = false;
+
+        WindowFunctions.RestoreInterface(vm);
 
-        if (Settings.WindowProperties.AutoFit)
+        // Update window state
+        await Dispatcher.UIThread.InvokeAsync(() =>
         {
-            vm.MainWindow.SizeToContent.Value = SizeToContent.WidthAndHeight;
-            vm.MainWindow.CanResize.Value = false;
-            await WindowResizing.SetSizeAsync(vm);
+            window.WindowState = WindowState.Normal;
+            
+            if (Settings.WindowProperties.AutoFit)
+            {
+                vm.MainWindow.SizeToContent.Value = SizeToContent.WidthAndHeight;
+                vm.MainWindow.CanResize.Value = false;
+                vm.GlobalSettings.IsAutoFit.Value = true;
+                window.SizeToContent = SizeToContent.WidthAndHeight; // Fixes sizeToContent not being applied
+            }
+            else
+            {
+                vm.MainWindow.SizeToContent.Value = SizeToContent.Manual;
+                vm.MainWindow.CanResize.Value = true;
+                vm.GlobalSettings.IsAutoFit.Value = false;
+            }
+        });
+        
+        await WindowResizing.SetSizeAsync(vm);
+        
+        if (Settings.WindowProperties.KeepCentered)
+        {
+            WindowFunctions.CenterWindowOnScreen();
         }
         else
         {
-            vm.MainWindow.SizeToContent.Value = SizeToContent.Manual;
-            vm.MainWindow.CanResize.Value = true;
             WindowFunctions.InitializeWindowSizeAndPosition(window);
         }
-        
+
         if (saveSettings)
         {
             await SaveSettingsAsync().ConfigureAwait(false);
@@ -73,17 +83,21 @@ public static class MacOSWindow
 
     public static async Task Fullscreen(MacMainWindow? window, MainViewModel? vm, bool saveSettings = true)
     {
+        // Save window size, so that restoring it will return to the same size and position
+        WindowResizing.SaveSize(window);
+        
         Settings.WindowProperties.Maximized = false;
         Settings.WindowProperties.Fullscreen = true;
         
-        window.WindowState = WindowState.FullScreen;
-        
         vm.MainWindow.IsTopToolbarShown.Value = false;
         vm.MainWindow.IsBottomToolbarShown.Value = false;
         
         vm.MainWindow.IsFullscreen.Value = true;
         vm.MainWindow.IsMaximized.Value = false;
         vm.MainWindow.CanResize.Value = false;
+        
+        window.WindowState = WindowState.FullScreen;
+        
         await WindowResizing.SetSizeAsync(vm);
         
         if (saveSettings)
@@ -94,34 +108,26 @@ public static class MacOSWindow
 
     public static async Task Maximize(MacMainWindow? window, MainViewModel? vm, bool saveSettings = true)
     {
-        var isAutoFit = Settings.WindowProperties.AutoFit;
-        Settings.WindowProperties.AutoFit = false;
-        
-        if (!isAutoFit)
+        await Dispatcher.UIThread.InvokeAsync(() =>
         {
             // Save window size, so that restoring it will return to the same size and position
             WindowResizing.SaveSize(window);
-        }
-        
-        // Update settings
-        Settings.WindowProperties.Maximized = true;
-        Settings.WindowProperties.Fullscreen = false;
-        
-        vm.MainWindow.SizeToContent.Value = SizeToContent.Manual;
+            
+            if (Settings.WindowProperties.AutoFit || window.SizeToContent == SizeToContent.WidthAndHeight)
+            {
+                vm.MainWindow.SizeToContent.Value = SizeToContent.Manual;
+            }
+
+            window.WindowState = WindowState.Maximized;
+            Settings.WindowProperties.Maximized = true;
+            WindowResizing.SetSize(vm);
+            WindowFunctions.CenterWindowOnScreen();
+        });
+
         vm.MainWindow.IsMaximized.Value = true;
         vm.MainWindow.IsFullscreen.Value = false;
         vm.MainWindow.CanResize.Value = false;
-        
-        window.WindowState = WindowState.Maximized;
-        
 
-        await WindowResizing.SetSizeAsync(vm);
-        
-        if (isAutoFit)
-        {
-            Settings.WindowProperties.AutoFit = true;
-        }
-        
         if (saveSettings)
         {
             await SaveSettingsAsync().ConfigureAwait(false);

+ 25 - 0
src/PicView.Avalonia/WindowBehavior/WindowFunctions.cs

@@ -12,6 +12,7 @@ using PicView.Avalonia.ViewModels;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHistory;
+using PicView.Core.Sizing;
 
 // ReSharper disable CompareOfFloatsByEqualityOperator
 
@@ -70,6 +71,30 @@ public static class WindowFunctions
 
     #region Window State
     
+    /// <summary>
+    /// Restores the interface based on settings
+    /// </summary>
+    public static void RestoreInterface(MainViewModel vm)
+    {
+        vm.MainWindow.IsUIShown.Value = Settings.UIProperties.ShowInterface;
+
+        if (!Settings.UIProperties.ShowInterface)
+        {
+            return;
+        }
+
+        vm.MainWindow.IsTopToolbarShown.Value = true;
+        vm.MainWindow.TitlebarHeight.Value = SizeDefaults.MainTitlebarHeight;
+
+        if (!Settings.UIProperties.ShowBottomNavBar)
+        {
+            return;
+        }
+
+        vm.MainWindow.IsBottomToolbarShown.Value = true;
+        vm.MainWindow.BottombarHeight.Value = SizeDefaults.BottombarHeight;
+    }
+    
     public static async Task ResizeAndFixRenderingError(MainViewModel vm)
     {
         await Dispatcher.UIThread.InvokeAsync(() =>