Browse Source

Fix starting up in fullscreen mode and refactor window logic and window resizing

Ruben 1 year ago
parent
commit
cd9ce511f3

+ 1 - 0
src/PicView.Avalonia.Win32/Views/AboutWindow.axaml

@@ -76,6 +76,7 @@
                     Foreground="{DynamicResource MainTextColor}"
                     Foreground="{DynamicResource MainTextColor}"
                     Height="28"
                     Height="28"
                     LineHeight="28"
                     LineHeight="28"
+                    Padding="30,0,0,0"
                     Text="{CompiledBinding About}"
                     Text="{CompiledBinding About}"
                     TextAlignment="Center"
                     TextAlignment="Center"
                     x:Name="TitleText" />
                     x:Name="TitleText" />

+ 1 - 0
src/PicView.Avalonia.Win32/Views/KeybindingsWindow.axaml

@@ -80,6 +80,7 @@
                     Classes="txt"
                     Classes="txt"
                     Foreground="{DynamicResource MainTextColor}"
                     Foreground="{DynamicResource MainTextColor}"
                     LineHeight="28"
                     LineHeight="28"
+                    Padding="30,0,0,0"
                     Text="{CompiledBinding ApplicationShortcuts}"
                     Text="{CompiledBinding ApplicationShortcuts}"
                     TextAlignment="Center"
                     TextAlignment="Center"
                     x:Name="TitleText" />
                     x:Name="TitleText" />

+ 1 - 0
src/PicView.Avalonia.Win32/Views/SettingsWindow.axaml

@@ -82,6 +82,7 @@
                     Classes="txt"
                     Classes="txt"
                     Foreground="{DynamicResource MainTextColor}"
                     Foreground="{DynamicResource MainTextColor}"
                     LineHeight="28"
                     LineHeight="28"
+                    Padding="30,0,0,0"
                     Text="{CompiledBinding Settings,
                     Text="{CompiledBinding Settings,
                                            Mode=OneWay}"
                                            Mode=OneWay}"
                     TextAlignment="Center"
                     TextAlignment="Center"

+ 6 - 25
src/PicView.Avalonia.Win32/Views/WinMainWindow.axaml.cs

@@ -3,8 +3,8 @@ using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
-using ReactiveUI;
 
 
 namespace PicView.Avalonia.Win32.Views;
 namespace PicView.Avalonia.Win32.Views;
 
 
@@ -23,31 +23,12 @@ public partial class WinMainWindow : Window
             // Keep window position when resizing
             // Keep window position when resizing
             ClientSizeProperty.Changed.Subscribe(size =>
             ClientSizeProperty.Changed.Subscribe(size =>
             {
             {
-                WindowHelper.HandleWindowResize(this, size);
-            });
-            
-            this.WhenAnyValue(x => x.WindowState).Subscribe(state =>
-            {
-                switch (state)
-                {
-                    case WindowState.Normal:
-                        SettingsHelper.Settings.WindowProperties.Maximized = false;
-                        SettingsHelper.Settings.WindowProperties.Fullscreen = false;
-                        break;
-                    case WindowState.Minimized:
-                        break;
-                    case WindowState.Maximized:
-                        WindowHelper.Maximize();
-                        break;
-                    case WindowState.FullScreen:
-                        //WindowHelper.Fullscreen(DataContext as MainViewModel, Application.Current.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
-                        break;
-                }
+                WindowResizing.HandleWindowResize(this, size);
             });
             });
             ScalingChanged += (_, _) =>
             ScalingChanged += (_, _) =>
             {
             {
                 ScreenHelper.UpdateScreenSize(this);
                 ScreenHelper.UpdateScreenSize(this);
-                WindowHelper.SetSize(DataContext as MainViewModel);
+                WindowResizing.SetSize(DataContext as MainViewModel);
             };
             };
             PointerExited += (_, _) =>
             PointerExited += (_, _) =>
             {
             {
@@ -61,14 +42,14 @@ public partial class WinMainWindow : Window
 
 
         desktop.ShutdownRequested += async (_, e) =>
         desktop.ShutdownRequested += async (_, e) =>
         {
         {
-            await WindowHelper.WindowClosingBehavior(this);
+            await WindowFunctions.WindowClosingBehavior(this);
         };
         };
     }
     }
 
 
     protected override async void OnClosing(WindowClosingEventArgs e)
     protected override async void OnClosing(WindowClosingEventArgs e)
     {
     {
         e.Cancel = true;
         e.Cancel = true;
-        await WindowHelper.WindowClosingBehavior(this);
+        await WindowFunctions.WindowClosingBehavior(this);
         base.OnClosing(e);
         base.OnClosing(e);
     }
     }
 
 
@@ -89,6 +70,6 @@ public partial class WinMainWindow : Window
             return;
             return;
         }
         }
         var wm = (MainViewModel)DataContext;
         var wm = (MainViewModel)DataContext;
-        WindowHelper.SetSize(wm);
+        WindowResizing.SetSize(wm);
     }
     }
 }
 }

+ 2 - 1
src/PicView.Avalonia.Win32/Views/WinTitleBar.axaml.cs

@@ -4,6 +4,7 @@ using Avalonia.Input;
 using Avalonia.Media;
 using Avalonia.Media;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 
 
 namespace PicView.Avalonia.Win32.Views;
 namespace PicView.Avalonia.Win32.Views;
@@ -98,6 +99,6 @@ public partial class WinTitleBar : UserControl
         {
         {
             return;
             return;
         }
         }
-        WindowHelper.WindowDragAndDoubleClickBehavior((Window)VisualRoot, e);
+        WindowFunctions.WindowDragAndDoubleClickBehavior((Window)VisualRoot, e);
     }
     }
 }
 }

+ 4 - 3
src/PicView.Avalonia/CustomControls/GalleryAnimationControl.cs

@@ -9,6 +9,7 @@ using PicView.Avalonia.Animations;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using ReactiveUI;
 using ReactiveUI;
@@ -174,7 +175,7 @@ public class GalleryAnimationControl : UserControl
         {
         {
             IsVisible = true;
             IsVisible = true;
             Opacity = 1;
             Opacity = 1;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
             UIHelper.GetGalleryView.BlurMask.BlurEnabled = false;
             UIHelper.GetGalleryView.BlurMask.BlurEnabled = false;
             vm.GalleryItemMargin = new Thickness(2,0);
             vm.GalleryItemMargin = new Thickness(2,0);
         });
         });
@@ -208,7 +209,7 @@ public class GalleryAnimationControl : UserControl
         }
         }
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
             UIHelper.GetGalleryView.BlurMask.BlurEnabled = false;
             UIHelper.GetGalleryView.BlurMask.BlurEnabled = false;
         });
         });
         
         
@@ -225,7 +226,7 @@ public class GalleryAnimationControl : UserControl
         {
         {
             Height = to;
             Height = to;
             IsVisible = false;
             IsVisible = false;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         });
         });
         _isAnimating = false;
         _isAnimating = false;
     }
     }

+ 2 - 1
src/PicView.Avalonia/Navigation/NavigationHelper.cs

@@ -8,6 +8,7 @@ using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
@@ -507,7 +508,7 @@ public static class NavigationHelper
         vm.ImageType = imageModel.ImageType;
         vm.ImageType = imageModel.ImageType;
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
-            WindowHelper.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, 0,0, imageModel.Rotation, vm);
+            WindowResizing.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, 0,0, imageModel.Rotation, vm);
         });
         });
         
         
         if (files is null)
         if (files is null)

+ 3 - 2
src/PicView.Avalonia/Navigation/QuickLoad.cs

@@ -3,6 +3,7 @@ using PicView.Avalonia.Gallery;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
@@ -46,10 +47,10 @@ public static class QuickLoad
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
             vm.ImageViewer.SetTransform(imageModel.EXIFOrientation);
             vm.ImageViewer.SetTransform(imageModel.EXIFOrientation);
-            WindowHelper.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, secondaryPreloadValue?.ImageModel?.PixelWidth ?? 0, secondaryPreloadValue?.ImageModel?.PixelHeight ?? 0, imageModel.Rotation, vm);
+            WindowResizing.SetSize(imageModel.PixelWidth, imageModel.PixelHeight, secondaryPreloadValue?.ImageModel?.PixelWidth ?? 0, secondaryPreloadValue?.ImageModel?.PixelHeight ?? 0, imageModel.Rotation, vm);
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             {
             {
-                WindowHelper.CenterWindowOnScreen();
+                WindowFunctions.CenterWindowOnScreen();
             }
             }
         }, DispatcherPriority.Send);
         }, DispatcherPriority.Send);
 
 

+ 4 - 3
src/PicView.Avalonia/Navigation/Slideshow.cs

@@ -3,6 +3,7 @@ using Avalonia.Controls.ApplicationLifetimes;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Navigation;
 using PicView.Core.Navigation;
 using Timer = System.Timers.Timer;
 using Timer = System.Timers.Timer;
@@ -43,10 +44,10 @@ public static class Slideshow
 
 
         if (!SettingsHelper.Settings.WindowProperties.Fullscreen)
         if (!SettingsHelper.Settings.WindowProperties.Fullscreen)
         {
         {
-            WindowHelper.Restore(vm, Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
+            WindowFunctions.Restore(vm, Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             {
             {
-                WindowHelper.CenterWindowOnScreen();
+                WindowFunctions.CenterWindowOnScreen();
             }
             }
         }
         }
         
         
@@ -100,7 +101,7 @@ public static class Slideshow
 
 
         if (!SettingsHelper.Settings.WindowProperties.Fullscreen)
         if (!SettingsHelper.Settings.WindowProperties.Fullscreen)
         {
         {
-            await WindowHelper.ToggleFullscreen(vm, false);
+            await WindowFunctions.ToggleFullscreen(vm, false);
         }
         }
         
         
         await vm.ImageIterator.NextIteration(NavigateTo.Next);
         await vm.ImageIterator.NextIteration(NavigateTo.Next);

+ 4 - 3
src/PicView.Avalonia/Navigation/UpdateImage.cs

@@ -6,6 +6,7 @@ using PicView.Avalonia.Gallery;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.ImageHandling;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using PicView.Core.Navigation;
 using PicView.Core.Navigation;
@@ -56,7 +57,7 @@ public static class UpdateImage
 
 
             vm.ImageType = preLoadValue.ImageModel.ImageType;
             vm.ImageType = preLoadValue.ImageModel.ImageType;
 
 
-            WindowHelper.SetSize(preLoadValue.ImageModel.PixelWidth, preLoadValue.ImageModel.PixelHeight,
+            WindowResizing.SetSize(preLoadValue.ImageModel.PixelWidth, preLoadValue.ImageModel.PixelHeight,
                 nextPreloadValue?.ImageModel?.PixelWidth ?? 0, nextPreloadValue?.ImageModel?.PixelHeight ?? 0,
                 nextPreloadValue?.ImageModel?.PixelWidth ?? 0, nextPreloadValue?.ImageModel?.PixelHeight ?? 0,
                 preLoadValue.ImageModel.Rotation, vm);
                 preLoadValue.ImageModel.Rotation, vm);
             
             
@@ -68,7 +69,7 @@ public static class UpdateImage
 
 
         if (SettingsHelper.Settings.WindowProperties.KeepCentered)
         if (SettingsHelper.Settings.WindowProperties.KeepCentered)
         {
         {
-            await Dispatcher.UIThread.InvokeAsync(() => { WindowHelper.CenterWindowOnScreen(); });
+            await Dispatcher.UIThread.InvokeAsync(() => { WindowFunctions.CenterWindowOnScreen(); });
         }
         }
         
         
         if (vm.SelectedGalleryItemIndex != index)
         if (vm.SelectedGalleryItemIndex != index)
@@ -139,7 +140,7 @@ public static class UpdateImage
 
 
         Dispatcher.UIThread.Invoke(() =>
         Dispatcher.UIThread.Invoke(() =>
         {
         {
-            WindowHelper.SetSize(width, height, 0, 0, 0, vm);
+            WindowResizing.SetSize(width, height, 0, 0, 0, vm);
         });
         });
         
         
         if (vm.RotationAngle != 0)
         if (vm.RotationAngle != 0)

+ 23 - 10
src/PicView.Avalonia/UI/FunctionsHelper.cs

@@ -11,6 +11,7 @@ using PicView.Avalonia.Gallery;
 using PicView.Avalonia.ImageTransformations;
 using PicView.Avalonia.ImageTransformations;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageDecoding;
@@ -66,6 +67,7 @@ public static class FunctionsHelper
 
 
             // Window functions
             // Window functions
             "Fullscreen" => Fullscreen,
             "Fullscreen" => Fullscreen,
+            "ToggleFullscreen" => ToggleFullscreen,
             "SetTopMost" => SetTopMost,
             "SetTopMost" => SetTopMost,
             "Close" => Close,
             "Close" => Close,
             "ToggleInterface" => ToggleInterface,
             "ToggleInterface" => ToggleInterface,
@@ -426,7 +428,7 @@ public static class FunctionsHelper
 
 
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         {
         {
-            await WindowHelper.MaximizeRestore();
+            await WindowFunctions.MaximizeRestore();
             return;
             return;
         }
         }
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
@@ -457,7 +459,7 @@ public static class FunctionsHelper
         // TODO: scroll to center when the gallery is open
         // TODO: scroll to center when the gallery is open
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
-            WindowHelper.CenterWindowOnScreen();
+            WindowFunctions.CenterWindowOnScreen();
         });
         });
     }
     }
 
 
@@ -508,36 +510,47 @@ public static class FunctionsHelper
     
     
     public static async Task Stretch()
     public static async Task Stretch()
     {
     {
-        await WindowHelper.Stretch(Vm);
+        await WindowFunctions.Stretch(Vm);
     }
     }
     public static async Task AutoFitWindow()
     public static async Task AutoFitWindow()
     {
     {
-        await WindowHelper.ToggleAutoFit(Vm);
+        await WindowFunctions.ToggleAutoFit(Vm);
     }
     }
 
 
     public static async Task AutoFitWindowAndStretch()
     public static async Task AutoFitWindowAndStretch()
     {
     {
-        await WindowHelper.AutoFitAndStretch(Vm);
+        await WindowFunctions.AutoFitAndStretch(Vm);
     }
     }
 
 
     public static async Task NormalWindow()
     public static async Task NormalWindow()
     {
     {
-        await WindowHelper.NormalWindow(Vm);
+        await WindowFunctions.NormalWindow(Vm);
     }
     }
 
 
     public static async Task NormalWindowAndStretch()
     public static async Task NormalWindowAndStretch()
     {
     {
-        await WindowHelper.NormalWindowStretch(Vm);
+        await WindowFunctions.NormalWindowStretch(Vm);
     }
     }
 
 
-    public static async Task Fullscreen()
+    public static async Task ToggleFullscreen()
     {
     {
         if (Vm is null)
         if (Vm is null)
         {
         {
             return;
             return;
         }
         }
 
 
-        await WindowHelper.ToggleFullscreen(Vm);
+        await WindowFunctions.ToggleFullscreen(Vm);
+    }
+    
+    public static Task Fullscreen()
+    {
+        if (Vm is null)
+        {
+            return Task.CompletedTask;
+        }
+
+        WindowFunctions.Fullscreen(Vm, Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime);
+        return Task.CompletedTask;
     }
     }
 
 
     public static async Task SetTopMost()
     public static async Task SetTopMost()
@@ -547,7 +560,7 @@ public static class FunctionsHelper
             return;
             return;
         }
         }
 
 
-        await WindowHelper.ToggleTopMost(Vm);
+        await WindowFunctions.ToggleTopMost(Vm);
     }
     }
 
 
     #endregion
     #endregion

+ 3 - 2
src/PicView.Avalonia/UI/HideInterfaceLogic.cs

@@ -4,6 +4,7 @@ using PicView.Avalonia.Animations;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Calculations;
 using PicView.Core.Calculations;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
@@ -85,7 +86,7 @@ public static class HideInterfaceLogic
             }
             }
         }
         }
         
         
-        WindowHelper.SetSize(vm);
+        WindowResizing.SetSize(vm);
         UIHelper.CloseMenus(vm);
         UIHelper.CloseMenus(vm);
         await SettingsHelper.SaveSettingsAsync();
         await SettingsHelper.SaveSettingsAsync();
     }
     }
@@ -111,7 +112,7 @@ public static class HideInterfaceLogic
         }
         }
         await Dispatcher.UIThread.InvokeAsync(() =>
         await Dispatcher.UIThread.InvokeAsync(() =>
         {
         {
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         });
         });
         
         
         await SettingsHelper.SaveSettingsAsync();
         await SettingsHelper.SaveSettingsAsync();

+ 12 - 4
src/PicView.Avalonia/UI/StartUpHelper.cs

@@ -2,12 +2,14 @@
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.Primitives;
 using Avalonia.Controls.Primitives;
+using Avalonia.Threading;
 using PicView.Avalonia.ColorManagement;
 using PicView.Avalonia.ColorManagement;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.SettingsManagement;
 using PicView.Avalonia.SettingsManagement;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views;
 using PicView.Avalonia.Views;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using PicView.Core.ProcessHandling;
 using PicView.Core.ProcessHandling;
@@ -38,7 +40,7 @@ public static class StartUpHelper
     {
     {
         w.Height = w.MinHeight;
         w.Height = w.MinHeight;
         w.Width = w.MinWidth;
         w.Width = w.MinWidth;
-        WindowHelper.CenterWindowOnScreen();
+        WindowFunctions.CenterWindowOnScreen();
         vm.CanResize = true;
         vm.CanResize = true;
         vm.IsAutoFit = false;
         vm.IsAutoFit = false;
     }
     }
@@ -106,11 +108,17 @@ public static class StartUpHelper
     {
     {
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         {
         {
-            WindowHelper.Fullscreen(vm, desktop);
+            // Need to delay it or it won't render properly
+            Dispatcher.UIThread.Post(() =>
+            {
+                w.Topmost = true;
+                WindowFunctions.CenterWindowOnScreen();
+                WindowFunctions.Fullscreen(vm, desktop);
+            }, DispatcherPriority.ContextIdle);
         }
         }
         else if (SettingsHelper.Settings.WindowProperties.Maximized)
         else if (SettingsHelper.Settings.WindowProperties.Maximized)
         {
         {
-            WindowHelper.Maximize();
+            WindowFunctions.Maximize();
         }
         }
         else if (SettingsHelper.Settings.WindowProperties.AutoFit)
         else if (SettingsHelper.Settings.WindowProperties.AutoFit)
         {
         {
@@ -123,7 +131,7 @@ public static class StartUpHelper
         {
         {
             vm.CanResize = true;
             vm.CanResize = true;
             vm.IsAutoFit = false;
             vm.IsAutoFit = false;
-            WindowHelper.InitializeWindowSizeAndPosition(w);
+            WindowFunctions.InitializeWindowSizeAndPosition(w);
         }
         }
     }
     }
 
 

+ 4 - 3
src/PicView.Avalonia/UI/UIHelper.cs

@@ -11,6 +11,7 @@ using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views;
 using PicView.Avalonia.Views;
 using PicView.Avalonia.Views.UC;
 using PicView.Avalonia.Views.UC;
 using PicView.Avalonia.Views.UC.Menus;
 using PicView.Avalonia.Views.UC.Menus;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Gallery;
 using PicView.Core.Gallery;
 using PicView.Core.Localization;
 using PicView.Core.Localization;
@@ -149,7 +150,7 @@ namespace PicView.Avalonia.UI
                 SettingsHelper.Settings.ImageScaling.ShowImageSideBySide = false;
                 SettingsHelper.Settings.ImageScaling.ShowImageSideBySide = false;
                 vm.IsShowingSideBySide = false;
                 vm.IsShowingSideBySide = false;
                 vm.SecondaryImageSource = null;
                 vm.SecondaryImageSource = null;
-                WindowHelper.SetSize(vm);
+                WindowResizing.SetSize(vm);
             }
             }
             else
             else
             {
             {
@@ -161,7 +162,7 @@ namespace PicView.Avalonia.UI
                     vm.SecondaryImageSource = preloadValue?.ImageModel.Image;
                     vm.SecondaryImageSource = preloadValue?.ImageModel.Image;
                     Dispatcher.UIThread.InvokeAsync(() =>
                     Dispatcher.UIThread.InvokeAsync(() =>
                     {
                     {
-                        WindowHelper.SetSize(vm.ImageWidth, vm.ImageHeight, preloadValue.ImageModel.PixelWidth,
+                        WindowResizing.SetSize(vm.ImageWidth, vm.ImageHeight, preloadValue.ImageModel.PixelWidth,
                                                 preloadValue.ImageModel.PixelHeight, vm.RotationAngle, vm);
                                                 preloadValue.ImageModel.PixelHeight, vm.RotationAngle, vm);
                     });
                     });
                 }
                 }
@@ -187,7 +188,7 @@ namespace PicView.Avalonia.UI
                 SettingsHelper.Settings.Zoom.ScrollEnabled = true;
                 SettingsHelper.Settings.Zoom.ScrollEnabled = true;
             }
             }
 
 
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         }
         }
 
 
         public static async Task Flip(MainViewModel vm)
         public static async Task Flip(MainViewModel vm)

+ 6 - 6
src/PicView.Avalonia/ViewModels/MainViewModel.cs

@@ -14,6 +14,7 @@ using PicView.Avalonia.ImageTransformations;
 using PicView.Avalonia.Interfaces;
 using PicView.Avalonia.Interfaces;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Calculations;
 using PicView.Core.Calculations;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
@@ -411,7 +412,6 @@ public class MainViewModel : ViewModelBase
     public ReactiveCommand<Unit, Unit>? MaximizeCommand { get; }
     public ReactiveCommand<Unit, Unit>? MaximizeCommand { get; }
     
     
     public ReactiveCommand<Unit, Unit>? ToggleFullscreenCommand { get; }
     public ReactiveCommand<Unit, Unit>? ToggleFullscreenCommand { get; }
-
     public ReactiveCommand<Unit, Unit>? NextCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextArrowButtonCommand { get; }
     public ReactiveCommand<Unit, Unit>? NextArrowButtonCommand { get; }
@@ -630,7 +630,7 @@ public class MainViewModel : ViewModelBase
         {
         {
             this.RaiseAndSetIfChanged(ref _isStretched, value);
             this.RaiseAndSetIfChanged(ref _isStretched, value);
             SettingsHelper.Settings.ImageScaling.StretchImage = value;
             SettingsHelper.Settings.ImageScaling.StretchImage = value;
-            WindowHelper.SetSize(this);
+            WindowResizing.SetSize(this);
         }
         }
     }
     }
 
 
@@ -1666,10 +1666,10 @@ public class MainViewModel : ViewModelBase
 
 
         #region Window commands
         #region Window commands
 
 
-        ExitCommand = ReactiveCommand.CreateFromTask(WindowHelper.Close);
-        MinimizeCommand = ReactiveCommand.CreateFromTask(WindowHelper.Minimize);
-        MaximizeCommand = ReactiveCommand.CreateFromTask(WindowHelper.MaximizeRestore);
-        ToggleFullscreenCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.Fullscreen);
+        ExitCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Close);
+        MinimizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.Minimize);
+        MaximizeCommand = ReactiveCommand.CreateFromTask(WindowFunctions.MaximizeRestore);
+        ToggleFullscreenCommand = ReactiveCommand.CreateFromTask(FunctionsHelper.ToggleFullscreen);
         NewWindowCommand = ReactiveCommand.Create(ProcessHelper.StartNewProcess);
         NewWindowCommand = ReactiveCommand.Create(ProcessHelper.StartNewProcess);
 
 
         ShowExifWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowExifWindow);
         ShowExifWindowCommand = ReactiveCommand.Create(platformSpecificService.ShowExifWindow);

+ 2 - 1
src/PicView.Avalonia/Views/BottomBar.axaml.cs

@@ -3,6 +3,7 @@ using Avalonia.Controls;
 using Avalonia.Input;
 using Avalonia.Input;
 using Avalonia.Media;
 using Avalonia.Media;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 
 
 namespace PicView.Avalonia.Views;
 namespace PicView.Avalonia.Views;
@@ -75,6 +76,6 @@ public partial class BottomBar : UserControl
     {
     {
         if (VisualRoot is null) { return; }
         if (VisualRoot is null) { return; }
 
 
-        WindowHelper.WindowDragBehavior((Window)VisualRoot, e);
+        WindowFunctions.WindowDragBehavior((Window)VisualRoot, e);
     }
     }
 }
 }

+ 3 - 2
src/PicView.Avalonia/Views/ImageViewer.axaml.cs

@@ -10,6 +10,7 @@ using Avalonia.Threading;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageDecoding;
 using PicView.Core.ImageTransformations;
 using PicView.Core.ImageTransformations;
@@ -504,7 +505,7 @@ public partial class ImageViewer : UserControl
             });
             });
         }
         }
 
 
-        WindowHelper.SetSize(vm);
+        WindowResizing.SetSize(vm);
         MainImage.InvalidateVisual();
         MainImage.InvalidateVisual();
     }
     }
     
     
@@ -515,7 +516,7 @@ public partial class ImageViewer : UserControl
             var rotateTransform = new RotateTransform(angle);
             var rotateTransform = new RotateTransform(angle);
             ImageLayoutTransformControl.LayoutTransform = rotateTransform;
             ImageLayoutTransformControl.LayoutTransform = rotateTransform;
             
             
-            WindowHelper.SetSize(DataContext as MainViewModel);
+            WindowResizing.SetSize(DataContext as MainViewModel);
             MainImage.InvalidateVisual();
             MainImage.InvalidateVisual();
         });
         });
     }
     }

+ 2 - 1
src/PicView.Avalonia/Views/MainView.axaml.cs

@@ -8,6 +8,7 @@ using PicView.Avalonia.Navigation;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.Views.UC;
 using PicView.Avalonia.Views.UC;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.Extensions;
 using PicView.Core.Extensions;
 
 
@@ -48,7 +49,7 @@ public partial class MainView : UserControl
         if (MainKeyboardShortcuts.ShiftDown)
         if (MainKeyboardShortcuts.ShiftDown)
         {
         {
             var hostWindow = (Window)VisualRoot!;
             var hostWindow = (Window)VisualRoot!;
-            WindowHelper.WindowDragBehavior(hostWindow, e);
+            WindowFunctions.WindowDragBehavior(hostWindow, e);
         }
         }
         
         
         MainKeyboardShortcuts.ClearKeyDownModifiers();
         MainKeyboardShortcuts.ClearKeyDownModifiers();

+ 2 - 1
src/PicView.Avalonia/Views/UC/BottomGalleryItemSizeSlider.axaml.cs

@@ -3,6 +3,7 @@ using Avalonia.Controls.Primitives;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 
 
 namespace PicView.Avalonia.Views.UC;
 namespace PicView.Avalonia.Views.UC;
@@ -30,7 +31,7 @@ public partial class BottomGalleryItemSizeSlider : UserControl
         {
         {
             vm.GetGalleryItemHeight = e.NewValue;
             vm.GetGalleryItemHeight = e.NewValue;
             UIHelper.GetGalleryView.Height = vm.GalleryHeight;
             UIHelper.GetGalleryView.Height = vm.GalleryHeight;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         }
         }
         
         
         // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
         // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day

+ 2 - 2
src/PicView.Avalonia/Views/UC/FullGalleryItemSizeSlider.axaml.cs

@@ -1,8 +1,8 @@
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Controls.Primitives;
 using Avalonia.Controls.Primitives;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
-using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 
 
 namespace PicView.Avalonia.Views.UC;
 namespace PicView.Avalonia.Views.UC;
@@ -29,7 +29,7 @@ public partial class FullGalleryItemSizeSlider : UserControl
         if (GalleryFunctions.IsFullGalleryOpen)
         if (GalleryFunctions.IsFullGalleryOpen)
         {
         {
             vm.GetGalleryItemHeight = vm.GetFullGalleryItemHeight;
             vm.GetGalleryItemHeight = vm.GetFullGalleryItemHeight;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         }
         }
         // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
         // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
         
         

+ 3 - 2
src/PicView.Avalonia/Views/UC/GalleryItemSizeSlider.axaml.cs

@@ -3,6 +3,7 @@ using Avalonia.Controls.Primitives;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.Gallery;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
+using PicView.Avalonia.WindowBehavior;
 using PicView.Core.Config;
 using PicView.Core.Config;
 
 
 namespace PicView.Avalonia.Views.UC;
 namespace PicView.Avalonia.Views.UC;
@@ -49,7 +50,7 @@ public partial class GalleryItemSizeSlider : UserControl
             }
             }
             vm.GetFullGalleryItemHeight = e.NewValue;
             vm.GetFullGalleryItemHeight = e.NewValue;
             vm.GetGalleryItemHeight = vm.GetFullGalleryItemHeight;
             vm.GetGalleryItemHeight = vm.GetFullGalleryItemHeight;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
             // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
             // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
         
         
             // Maybe save this on close or some other way
             // Maybe save this on close or some other way
@@ -67,7 +68,7 @@ public partial class GalleryItemSizeSlider : UserControl
         
         
             vm.GetGalleryItemHeight = e.NewValue;
             vm.GetGalleryItemHeight = e.NewValue;
             UIHelper.GetGalleryView.Height = vm.GalleryHeight;
             UIHelper.GetGalleryView.Height = vm.GalleryHeight;
-            WindowHelper.SetSize(vm);
+            WindowResizing.SetSize(vm);
         
         
             // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
             // Binding to height depends on timing of the update. Maybe find a cleaner mvvm solution one day
             // Maybe save this on close or some other way
             // Maybe save this on close or some other way

+ 138 - 381
src/PicView.Avalonia/UI/WindowHelper.cs → src/PicView.Avalonia/WindowBehavior/WindowFunctions.cs

@@ -3,157 +3,66 @@ using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Input;
 using Avalonia.Input;
-using Avalonia.Media.Imaging;
 using Avalonia.Threading;
 using Avalonia.Threading;
-using ImageMagick;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Keybindings;
 using PicView.Avalonia.Navigation;
 using PicView.Avalonia.Navigation;
+using PicView.Avalonia.UI;
 using PicView.Avalonia.ViewModels;
 using PicView.Avalonia.ViewModels;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.ArchiveHandling;
 using PicView.Core.Calculations;
 using PicView.Core.Calculations;
 using PicView.Core.Config;
 using PicView.Core.Config;
 using PicView.Core.FileHandling;
 using PicView.Core.FileHandling;
-using PicView.Core.Navigation;
 
 
-namespace PicView.Avalonia.UI;
+namespace PicView.Avalonia.WindowBehavior;
 
 
-public static class WindowHelper
+public static class WindowFunctions
 {
 {
-    #region Window Dragging and size changing
-    
-    public static void WindowDragAndDoubleClickBehavior(Window window, PointerPressedEventArgs e)
-    {
-        if (e.ClickCount == 2 && e.GetCurrentPoint(window).Properties.IsLeftButtonPressed)
-        {
-            _ = MaximizeRestore();
-            return;
-        }
-        
-        var currentScreen = ScreenHelper.ScreenSize;
-        window.BeginMoveDrag(e);
-        var screen = window.Screens.ScreenFromVisual(window);
-        if (screen != null)
-        {
-            if (screen.WorkingArea.Width != currentScreen.WorkingAreaWidth ||
-                screen.WorkingArea.Height != currentScreen.WorkingAreaHeight || screen.Scaling != currentScreen.Scaling)
-            {
-                ScreenHelper.UpdateScreenSize(window);
-                SetSize(window.DataContext as MainViewModel);
-            }
-        }
-    }
-    
-    public static void WindowDragBehavior(Window window, PointerPressedEventArgs e)
+    public static async Task WindowClosingBehavior(Window window)
     {
     {
-        var currentScreen = ScreenHelper.ScreenSize;
-        window.BeginMoveDrag(e);
-        var screen = window.Screens.ScreenFromVisual(window);
-        if (screen != null)
+        if (!SettingsHelper.Settings.WindowProperties.Maximized ||
+            !SettingsHelper.Settings.WindowProperties.Fullscreen || SettingsHelper.Settings.WindowProperties.AutoFit)
         {
         {
-            if (screen.WorkingArea.Width != currentScreen.WorkingAreaWidth ||
-                screen.WorkingArea.Height != currentScreen.WorkingAreaHeight || screen.Scaling != currentScreen.Scaling)
-            {
-                ScreenHelper.UpdateScreenSize(window);
-                SetSize(window.DataContext as MainViewModel);
-            }
+            WindowResizing.SaveSize(window);
         }
         }
-    }
 
 
-    public static void InitializeWindowSizeAndPosition(Window window)
-    {
         if (Dispatcher.UIThread.CheckAccess())
         if (Dispatcher.UIThread.CheckAccess())
         {
         {
-            window.Position = new PixelPoint((int)SettingsHelper.Settings.WindowProperties.Left, (int)SettingsHelper.Settings.WindowProperties.Top);
-            window.Width = SettingsHelper.Settings.WindowProperties.Width;
-            window.Height = SettingsHelper.Settings.WindowProperties.Height;
+            window.Hide();
         }
         }
         else
         else
         {
         {
-            Dispatcher.UIThread.InvokeAsync(() =>
-            {
-                window.Position = new PixelPoint((int)SettingsHelper.Settings.WindowProperties.Left, (int)SettingsHelper.Settings.WindowProperties.Top);
-                window.Width = SettingsHelper.Settings.WindowProperties.Width;
-                window.Height = SettingsHelper.Settings.WindowProperties.Height;
-            });
-        }
-    }
-
-    public static void HandleWindowResize(Window window, AvaloniaPropertyChangedEventArgs<Size> size)
-    {
-        if (!SettingsHelper.Settings.WindowProperties.AutoFit)
-        {
-            return;
-        }
-
-        if (!size.OldValue.HasValue || !size.NewValue.HasValue)
-        {
-            return;
-        }
-
-        if (size.OldValue.Value.Width == 0 || size.OldValue.Value.Height == 0 ||
-            size.NewValue.Value.Width == 0 || size.NewValue.Value.Height == 0)
-        {
-            return;
+            await Dispatcher.UIThread.InvokeAsync(window.Hide);
         }
         }
 
 
-        if (size.Sender != window)
+        var vm = window.DataContext as MainViewModel;
+        string lastFile;
+        if (NavigationHelper.CanNavigate(vm))
         {
         {
-            return;
+            if (!string.IsNullOrEmpty(ArchiveExtraction.LastOpenedArchive))
+            {
+                lastFile = ArchiveExtraction.LastOpenedArchive;
+            }
+            else
+            {
+                lastFile = vm?.FileInfo?.FullName ?? FileHistoryNavigation.GetLastFile();
+            }
         }
         }
-
-        var x = (size.OldValue.Value.Width - size.NewValue.Value.Width) / 2;
-        var y = (size.OldValue.Value.Height - size.NewValue.Value.Height) / 2;
-
-        window.Position = new PixelPoint(window.Position.X + (int)x, window.Position.Y + (int)y);
-    }
-
-    public static void CenterWindowOnScreen(bool horizontal = true)
-    {
-        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+        else
         {
         {
-            return;
+            var url = vm?.Title.GetURL();
+            lastFile = !string.IsNullOrWhiteSpace(url) ? url : FileHistoryNavigation.GetLastFile();
         }
         }
-        
-        Dispatcher.UIThread.Post(() =>
-        {
-            var window = desktop.MainWindow;
-            
-            // Get the screen that the window is currently on
-            var screens = window.Screens;
-            var screen = screens.ScreenFromVisual(window);
-
-            if (screen == null)
-            {
-                return; // No screen found (edge case)
-            }
-
-            // Get the scaling factor of the screen (DPI scaling)
-            var scalingFactor = screen.Scaling;
 
 
-            // Get the current screen's bounds (in physical pixels, not adjusted for scaling)
-            var screenBounds = screen.WorkingArea;
-
-            // Calculate the actual bounds in logical units (adjusting for scaling)
-            var screenWidth = screenBounds.Width / scalingFactor;
-            var screenHeight = screenBounds.Height / scalingFactor;
-
-            // Get the size of the window
-            var windowSize = window.ClientSize;
-
-            // Calculate the position to center the window on the screen
-            var centeredX = screenBounds.X + (screenWidth - windowSize.Width) / 2;
-            var centeredY = screenBounds.Y + (screenHeight - windowSize.Height) / 2;
-
-            // Set the window's new position
-            window.Position = horizontal ?
-                new PixelPoint((int)centeredX, (int)centeredY) :
-                new PixelPoint(window.Position.X, (int)centeredY);
-        });
+        SettingsHelper.Settings.StartUp.LastFile = lastFile;
+        await SettingsHelper.SaveSettingsAsync();
+        await KeybindingsHelper.UpdateKeyBindingsFile(); // Save keybindings
+        FileDeletionHelper.DeleteTempFiles();
+        FileHistoryNavigation.WriteToFile();
+        ArchiveExtraction.Cleanup();
+        Environment.Exit(0);
     }
     }
 
 
-    #endregion Window Dragging and size changing
-
-    #region Change window behavior
+    #region Window State Management
 
 
     public static async Task ToggleTopMost(MainViewModel vm)
     public static async Task ToggleTopMost(MainViewModel vm)
     {
     {
@@ -194,7 +103,8 @@ public static class WindowHelper
             SettingsHelper.Settings.WindowProperties.AutoFit = true;
             SettingsHelper.Settings.WindowProperties.AutoFit = true;
             vm.IsAutoFit = true;
             vm.IsAutoFit = true;
         }
         }
-        SetSize(vm);
+
+        WindowResizing.SetSize(vm);
         await Dispatcher.UIThread.InvokeAsync(() => CenterWindowOnScreen(false));
         await Dispatcher.UIThread.InvokeAsync(() => CenterWindowOnScreen(false));
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
@@ -209,7 +119,6 @@ public static class WindowHelper
             SettingsHelper.Settings.ImageScaling.StretchImage = false;
             SettingsHelper.Settings.ImageScaling.StretchImage = false;
             vm.IsStretched = false;
             vm.IsStretched = false;
             vm.IsAutoFit = false;
             vm.IsAutoFit = false;
-            
         }
         }
         else
         else
         {
         {
@@ -220,7 +129,8 @@ public static class WindowHelper
             vm.IsAutoFit = true;
             vm.IsAutoFit = true;
             vm.IsStretched = true;
             vm.IsStretched = true;
         }
         }
-        SetSize(vm);
+
+        WindowResizing.SetSize(vm);
         await Dispatcher.UIThread.InvokeAsync(() => CenterWindowOnScreen(false));
         await Dispatcher.UIThread.InvokeAsync(() => CenterWindowOnScreen(false));
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
@@ -230,11 +140,11 @@ public static class WindowHelper
         vm.SizeToContent = SizeToContent.Manual;
         vm.SizeToContent = SizeToContent.Manual;
         vm.CanResize = true;
         vm.CanResize = true;
         SettingsHelper.Settings.WindowProperties.AutoFit = false;
         SettingsHelper.Settings.WindowProperties.AutoFit = false;
-        SetSize(vm);
+        WindowResizing.SetSize(vm);
         vm.ImageViewer.MainImage.InvalidateVisual();
         vm.ImageViewer.MainImage.InvalidateVisual();
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
-    
+
     public static async Task NormalWindowStretch(MainViewModel vm)
     public static async Task NormalWindowStretch(MainViewModel vm)
     {
     {
         vm.SizeToContent = SizeToContent.Manual;
         vm.SizeToContent = SizeToContent.Manual;
@@ -242,16 +152,16 @@ public static class WindowHelper
         SettingsHelper.Settings.WindowProperties.AutoFit = false;
         SettingsHelper.Settings.WindowProperties.AutoFit = false;
         SettingsHelper.Settings.ImageScaling.StretchImage = true;
         SettingsHelper.Settings.ImageScaling.StretchImage = true;
         vm.IsStretched = true;
         vm.IsStretched = true;
-        SetSize(vm);
+        WindowResizing.SetSize(vm);
         vm.ImageViewer.MainImage.InvalidateVisual();
         vm.ImageViewer.MainImage.InvalidateVisual();
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
-    
+
     public static async Task Stretch(MainViewModel vm)
     public static async Task Stretch(MainViewModel vm)
     {
     {
         SettingsHelper.Settings.ImageScaling.StretchImage = true;
         SettingsHelper.Settings.ImageScaling.StretchImage = true;
         vm.IsStretched = true;
         vm.IsStretched = true;
-        SetSize(vm);
+        WindowResizing.SetSize(vm);
         vm.ImageViewer.MainImage.InvalidateVisual();
         vm.ImageViewer.MainImage.InvalidateVisual();
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
@@ -266,22 +176,22 @@ public static class WindowHelper
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         if (SettingsHelper.Settings.WindowProperties.Fullscreen)
         {
         {
             vm.IsFullscreen = false;
             vm.IsFullscreen = false;
-            await Dispatcher.UIThread.InvokeAsync(() => 
+            await Dispatcher.UIThread.InvokeAsync(() =>
                 desktop.MainWindow.WindowState = WindowState.Normal);
                 desktop.MainWindow.WindowState = WindowState.Normal);
             if (saveSettings)
             if (saveSettings)
             {
             {
                 SettingsHelper.Settings.WindowProperties.Fullscreen = false;
                 SettingsHelper.Settings.WindowProperties.Fullscreen = false;
             }
             }
-            
+
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
             {
             {
-                RestoreSize(desktop.MainWindow);
+                WindowResizing.RestoreSize(desktop.MainWindow);
                 Restore(vm, desktop);
                 Restore(vm, desktop);
             }
             }
         }
         }
         else
         else
         {
         {
-            SaveSize(desktop.MainWindow);
+            WindowResizing.SaveSize(desktop.MainWindow);
             Fullscreen(vm, desktop);
             Fullscreen(vm, desktop);
             if (saveSettings)
             if (saveSettings)
             {
             {
@@ -291,13 +201,14 @@ public static class WindowHelper
 
 
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
-    
+
     public static async Task MaximizeRestore()
     public static async Task MaximizeRestore()
     {
     {
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         {
         {
             return;
             return;
         }
         }
+
         var vm = desktop.MainWindow.DataContext as MainViewModel;
         var vm = desktop.MainWindow.DataContext as MainViewModel;
         // Restore
         // Restore
         if (desktop.MainWindow.WindowState is WindowState.Maximized or WindowState.FullScreen)
         if (desktop.MainWindow.WindowState is WindowState.Maximized or WindowState.FullScreen)
@@ -309,11 +220,12 @@ public static class WindowHelper
         {
         {
             if (!SettingsHelper.Settings.WindowProperties.AutoFit)
             if (!SettingsHelper.Settings.WindowProperties.AutoFit)
             {
             {
-                SaveSize(desktop.MainWindow);
+                WindowResizing.SaveSize(desktop.MainWindow);
             }
             }
+
             Maximize();
             Maximize();
         }
         }
-        
+
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
         await SettingsHelper.SaveSettingsAsync().ConfigureAwait(false);
     }
     }
 
 
@@ -330,16 +242,18 @@ public static class WindowHelper
                     vm.IsBottomToolbarShown = true;
                     vm.IsBottomToolbarShown = true;
                     vm.BottombarHeight = SizeDefaults.BottombarHeight;
                     vm.BottombarHeight = SizeDefaults.BottombarHeight;
                 }
                 }
+
                 vm.IsUIShown = true;
                 vm.IsUIShown = true;
             }
             }
         }
         }
-        Dispatcher.UIThread.InvokeAsync(() => 
+
+        Dispatcher.UIThread.InvokeAsync(() =>
             desktop.MainWindow.WindowState = WindowState.Normal);
             desktop.MainWindow.WindowState = WindowState.Normal);
         SettingsHelper.Settings.WindowProperties.Maximized = false;
         SettingsHelper.Settings.WindowProperties.Maximized = false;
         SettingsHelper.Settings.WindowProperties.Fullscreen = false;
         SettingsHelper.Settings.WindowProperties.Fullscreen = false;
         vm.IsUIShown = SettingsHelper.Settings.UIProperties.ShowInterface;
         vm.IsUIShown = SettingsHelper.Settings.UIProperties.ShowInterface;
         InitializeWindowSizeAndPosition(desktop.MainWindow);
         InitializeWindowSizeAndPosition(desktop.MainWindow);
-        SetSize(vm);
+        WindowResizing.SetSize(vm);
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         if (SettingsHelper.Settings.WindowProperties.AutoFit)
         {
         {
             vm.SizeToContent = SizeToContent.WidthAndHeight;
             vm.SizeToContent = SizeToContent.WidthAndHeight;
@@ -355,7 +269,7 @@ public static class WindowHelper
     public static void Maximize()
     public static void Maximize()
     {
     {
         // TODO: Fix incorrect size for bottom button bar
         // TODO: Fix incorrect size for bottom button bar
-        
+
         if (Dispatcher.UIThread.CheckAccess())
         if (Dispatcher.UIThread.CheckAccess())
         {
         {
             Set();
             Set();
@@ -366,12 +280,14 @@ public static class WindowHelper
         }
         }
 
 
         return;
         return;
+
         void Set()
         void Set()
         {
         {
             if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
             if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
             {
             {
                 return;
                 return;
             }
             }
+
             var vm = desktop.MainWindow.DataContext as MainViewModel;
             var vm = desktop.MainWindow.DataContext as MainViewModel;
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             if (SettingsHelper.Settings.WindowProperties.AutoFit)
             {
             {
@@ -380,7 +296,7 @@ public static class WindowHelper
             }
             }
 
 
             desktop.MainWindow.WindowState = WindowState.Maximized;
             desktop.MainWindow.WindowState = WindowState.Maximized;
-            SetSize(desktop.MainWindow.DataContext as MainViewModel);
+            WindowResizing.SetSize(desktop.MainWindow.DataContext as MainViewModel);
             SettingsHelper.Settings.WindowProperties.Maximized = true;
             SettingsHelper.Settings.WindowProperties.Maximized = true;
         }
         }
     }
     }
@@ -398,7 +314,7 @@ public static class WindowHelper
         {
         {
             Dispatcher.UIThread.Invoke(() => desktop.MainWindow.WindowState = WindowState.FullScreen);
             Dispatcher.UIThread.Invoke(() => desktop.MainWindow.WindowState = WindowState.FullScreen);
         }
         }
-            
+
         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
         if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
         {
         {
             vm.IsTopToolbarShown = false; // Hide interface in fullscreen. Remember to turn back when exiting fullscreen
             vm.IsTopToolbarShown = false; // Hide interface in fullscreen. Remember to turn back when exiting fullscreen
@@ -446,6 +362,7 @@ public static class WindowHelper
                 // TODO go to macOS fullscreen mode when auto fit is on
                 // TODO go to macOS fullscreen mode when auto fit is on
             }
             }
         }
         }
+
         vm.GalleryWidth = double.NaN;
         vm.GalleryWidth = double.NaN;
     }
     }
 
 
@@ -455,292 +372,132 @@ public static class WindowHelper
         {
         {
             return;
             return;
         }
         }
-        await Dispatcher.UIThread.InvokeAsync(() => 
+
+        await Dispatcher.UIThread.InvokeAsync(() =>
             desktop.MainWindow.WindowState = WindowState.Minimized);
             desktop.MainWindow.WindowState = WindowState.Minimized);
     }
     }
-    
+
     public static async Task Close()
     public static async Task Close()
     {
     {
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         {
         {
             return;
             return;
         }
         }
-        await Dispatcher.UIThread.InvokeAsync(() => 
+
+        await Dispatcher.UIThread.InvokeAsync(() =>
             desktop.MainWindow.Close());
             desktop.MainWindow.Close());
     }
     }
 
 
-    #endregion Change window behavior
+    #endregion
 
 
-    #region Set and save Size
+    #region Window Size and Position
 
 
-    public static void SetSize(MainViewModel vm)
+    public static void CenterWindowOnScreen(bool horizontal = true)
     {
     {
-        double firstWidth, firstHeight;
-        var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue();
-        if (preloadValue == null)
-        {
-            if (vm.FileInfo is null)
-            {
-                if (vm.ImageSource is Bitmap bitmap)
-                {
-                    firstWidth = bitmap.PixelSize.Width;
-                    firstHeight = bitmap.PixelSize.Height;
-                }
-                else 
-                    return;
-            }
-            else
-            {
-                var magickImage = new MagickImage();
-                magickImage.Ping(vm.FileInfo);
-                firstWidth = magickImage.Width;
-                firstHeight = magickImage.Height;
-            }
-        }
-        else
+        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
         {
         {
-            firstWidth = GetWidth(preloadValue);
-            firstHeight = GetHeight(preloadValue);
+            return;
         }
         }
-        if (SettingsHelper.Settings.ImageScaling.ShowImageSideBySide)
-        {
-            var secondaryPreloadValue = vm.ImageIterator?.GetNextPreLoadValue();
-            double secondWidth, secondHeight;
-            if (secondaryPreloadValue != null)
-            {
-                secondWidth = GetWidth(secondaryPreloadValue);
-                secondHeight = GetHeight(secondaryPreloadValue);
-            }
-            else if (vm.ImageIterator is not null)
-            {
-                var nextIndex = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex, vm.ImageIterator.IsReversed ? NavigateTo.Previous : NavigateTo.Next);
-                var magickImage = new MagickImage();
-                magickImage.Ping(vm.ImageIterator.ImagePaths[nextIndex]);
-                secondWidth = magickImage.Width;
-                secondHeight = magickImage.Height;
-            }
-            else
-            {
-                secondWidth = 0;
-                secondHeight = 0;
-            }
 
 
-            if (Dispatcher.UIThread.CheckAccess())
-            {
-                SetSize(firstWidth, firstHeight, secondWidth, secondHeight, vm.RotationAngle, vm);
-            }
-            else
-            {
-                Dispatcher.UIThread.InvokeAsync(() => SetSize(firstWidth, firstHeight, secondWidth, secondHeight, vm.RotationAngle, vm));
-            }
-        }
-        else
+        Dispatcher.UIThread.Post(() =>
         {
         {
-            if (Dispatcher.UIThread.CheckAccess())
-            {
-                SetSize(firstWidth, firstHeight, 0, 0, vm.RotationAngle, vm);
-            }
-            else
+            var window = desktop.MainWindow;
+
+            // Get the screen that the window is currently on
+            var screens = window.Screens;
+            var screen = screens.ScreenFromVisual(window);
+
+            if (screen == null)
             {
             {
-                Dispatcher.UIThread.InvokeAsync(() => SetSize(firstWidth, firstHeight, 0, 0, vm.RotationAngle, vm));
+                return; // No screen found (edge case)
             }
             }
-        }
 
 
-        return;
-        double GetWidth(PreLoader.PreLoadValue preloadValue)
-        {
-            return preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth;
-        }
-        
-        double GetHeight(PreLoader.PreLoadValue preloadValue)
-        {
-            return preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight;
-        }
-    }
-    
-    public static void SetSize(double width, double height, double secondWidth, double secondHeight, double rotation, MainViewModel vm)
-    {
-        width = width == 0 ? vm.ImageWidth : width;
-        height = height == 0 ? vm.ImageHeight : height;
-        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
-        {
-            return;
-        }
+            // Get the scaling factor of the screen (DPI scaling)
+            var scalingFactor = screen.Scaling;
 
 
-        var mainView = UIHelper.GetMainView;
-        if (mainView is null)
-        {
-            return;
-        }
+            // Get the current screen's bounds (in physical pixels, not adjusted for scaling)
+            var screenBounds = screen.WorkingArea;
 
 
-        const int padding = 45;
-        var screenSize = ScreenHelper.ScreenSize;
-        double desktopMinWidth = 0, desktopMinHeight = 0, containerWidth = 0, containerHeight = 0;
-        desktopMinWidth = desktop.MainWindow.MinWidth;
-        desktopMinHeight = desktop.MainWindow.MinHeight;
-        containerWidth = mainView.Bounds.Width;
-        containerHeight = mainView.Bounds.Height;
+            // Calculate the actual bounds in logical units (adjusting for scaling)
+            var screenWidth = screenBounds.Width / scalingFactor;
+            var screenHeight = screenBounds.Height / scalingFactor;
 
 
-        if (double.IsNaN(containerWidth) || double.IsNaN(containerHeight) || double.IsNaN(width) || double.IsNaN(height))
-        {
-            return;
-        }
-        ImageSizeCalculationHelper.ImageSize size;
-        if (SettingsHelper.Settings.ImageScaling.ShowImageSideBySide && secondWidth > 0 && secondHeight > 0)
-        {
-            size = ImageSizeCalculationHelper.GetImageSize(
-                width,
-                height,
-                secondWidth,
-                secondHeight,
-                screenSize.WorkingAreaWidth,
-                screenSize.WorkingAreaHeight,
-                desktopMinWidth,
-                desktopMinHeight,
-                ImageSizeCalculationHelper.GetInterfaceSize(),
-                rotation,
-                padding,
-                screenSize.Scaling,
-                vm.TitlebarHeight,
-                vm.BottombarHeight,
-                vm.GalleryHeight,
-                containerWidth,
-                containerHeight);
-        }
-        else
-        {
-            size = ImageSizeCalculationHelper.GetImageSize(
-                width,
-                height,
-                screenSize.WorkingAreaWidth,
-                screenSize.WorkingAreaHeight,
-                desktopMinWidth,
-                desktopMinHeight,
-                ImageSizeCalculationHelper.GetInterfaceSize(),
-                rotation,
-                padding,
-                screenSize.Scaling,
-                vm.TitlebarHeight,
-                vm.BottombarHeight,
-                vm.GalleryHeight,
-                containerWidth,
-                containerHeight);
-        }
-        
-        vm.TitleMaxWidth = size.TitleMaxWidth;
-        vm.ImageWidth = size.Width;
-        vm.SecondaryImageWidth = size.SecondaryWidth;
-        vm.ImageHeight = size.Height;
-        vm.GalleryMargin = new Thickness(0, 0, 0, size.Margin);
-        
-        vm.ScrollViewerWidth = size.ScrollViewerWidth;
-        vm.ScrollViewerHeight = size.ScrollViewerHeight;
+            // Get the size of the window
+            var windowSize = window.ClientSize;
 
 
-        if (SettingsHelper.Settings.WindowProperties.AutoFit)
-        {
-            if (SettingsHelper.Settings.WindowProperties.Fullscreen || SettingsHelper.Settings.WindowProperties.Maximized)
-            {
-                vm.GalleryWidth = double.NaN;
-            }
-            else
-            {
-                vm.GalleryWidth = vm.RotationAngle is 90 or 270 ?
-                    Math.Max(size.Height, desktopMinHeight) :
-                    Math.Max(size.Width, desktopMinWidth);
-            }
-        }
-        else
-        {
-            vm.GalleryWidth = double.NaN;;
-        }
-    }
-    
-    public static void SaveSize(Window window)
-    {
-        if (Dispatcher.UIThread.CheckAccess())
-        {
-            Set();
-        }
-        else
-        {
-            Dispatcher.UIThread.InvokeAsync(Set);
-        }
+            // Calculate the position to center the window on the screen
+            var centeredX = screenBounds.X + (screenWidth - windowSize.Width) / 2;
+            var centeredY = screenBounds.Y + (screenHeight - windowSize.Height) / 2;
 
 
-        return;
-        void Set()
-        {
-            var top = window.Position.Y;
-            var left = window.Position.X;
-            SettingsHelper.Settings.WindowProperties.Top = top;
-            SettingsHelper.Settings.WindowProperties.Left = left;
-            SettingsHelper.Settings.WindowProperties.Width = window.Width;
-            SettingsHelper.Settings.WindowProperties.Height = window.Height;
-        }
+            // Set the window's new position
+            window.Position = horizontal
+                ? new PixelPoint((int)centeredX, (int)centeredY)
+                : new PixelPoint(window.Position.X, (int)centeredY);
+        });
     }
     }
-    
-    public static void RestoreSize(Window window)
+
+    public static void InitializeWindowSizeAndPosition(Window window)
     {
     {
         if (Dispatcher.UIThread.CheckAccess())
         if (Dispatcher.UIThread.CheckAccess())
         {
         {
-            Set();
+            window.Position = new PixelPoint((int)SettingsHelper.Settings.WindowProperties.Left,
+                (int)SettingsHelper.Settings.WindowProperties.Top);
+            window.Width = SettingsHelper.Settings.WindowProperties.Width;
+            window.Height = SettingsHelper.Settings.WindowProperties.Height;
         }
         }
         else
         else
         {
         {
-            Dispatcher.UIThread.InvokeAsync(Set);
-        }
-
-        return;
-        void Set()
-        {
-            var x = (int)SettingsHelper.Settings.WindowProperties.Left;
-            var y = (int)SettingsHelper.Settings.WindowProperties.Top;
-            window.Position = new PixelPoint(x, y);
-            window.Width = SettingsHelper.Settings.WindowProperties.Width;
-            window.Height = SettingsHelper.Settings.WindowProperties.Height;
+            Dispatcher.UIThread.InvokeAsync(() =>
+            {
+                window.Position = new PixelPoint((int)SettingsHelper.Settings.WindowProperties.Left,
+                    (int)SettingsHelper.Settings.WindowProperties.Top);
+                window.Width = SettingsHelper.Settings.WindowProperties.Width;
+                window.Height = SettingsHelper.Settings.WindowProperties.Height;
+            });
         }
         }
     }
     }
 
 
     #endregion
     #endregion
 
 
-    public static async Task WindowClosingBehavior(Window window)
+    #region Window Drag and Behavior
+
+    public static void WindowDragAndDoubleClickBehavior(Window window, PointerPressedEventArgs e)
     {
     {
-        if (Dispatcher.UIThread.CheckAccess())
-        {
-            window.Hide();
-        }
-        else
+        if (e.ClickCount == 2 && e.GetCurrentPoint(window).Properties.IsLeftButtonPressed)
         {
         {
-            await Dispatcher.UIThread.InvokeAsync(window.Hide);
+            _ = MaximizeRestore();
+            return;
         }
         }
 
 
-        if (!SettingsHelper.Settings.WindowProperties.Maximized || !SettingsHelper.Settings.WindowProperties.Fullscreen || SettingsHelper.Settings.WindowProperties.AutoFit)
-        {
-            SaveSize(window);
-        }
-        var vm = window.DataContext as MainViewModel;
-        string lastFile;
-        if (NavigationHelper.CanNavigate(vm))
+        var currentScreen = ScreenHelper.ScreenSize;
+        window.BeginMoveDrag(e);
+        var screen = window.Screens.ScreenFromVisual(window);
+        if (screen != null)
         {
         {
-            if (!string.IsNullOrEmpty(ArchiveExtraction.LastOpenedArchive))
-            {
-                lastFile = ArchiveExtraction.LastOpenedArchive;
-            }
-            else
+            if (screen.WorkingArea.Width != currentScreen.WorkingAreaWidth ||
+                screen.WorkingArea.Height != currentScreen.WorkingAreaHeight || screen.Scaling != currentScreen.Scaling)
             {
             {
-                lastFile = vm?.FileInfo?.FullName ?? FileHistoryNavigation.GetLastFile();
+                ScreenHelper.UpdateScreenSize(window);
+                WindowResizing.SetSize(window.DataContext as MainViewModel);
             }
             }
         }
         }
-        else
+    }
+
+    public static void WindowDragBehavior(Window window, PointerPressedEventArgs e)
+    {
+        var currentScreen = ScreenHelper.ScreenSize;
+        window.BeginMoveDrag(e);
+        var screen = window.Screens.ScreenFromVisual(window);
+        if (screen != null)
         {
         {
-            var url = vm?.Title.GetURL();
-            lastFile = !string.IsNullOrWhiteSpace(url) ? url : FileHistoryNavigation.GetLastFile();
+            if (screen.WorkingArea.Width != currentScreen.WorkingAreaWidth ||
+                screen.WorkingArea.Height != currentScreen.WorkingAreaHeight || screen.Scaling != currentScreen.Scaling)
+            {
+                ScreenHelper.UpdateScreenSize(window);
+                WindowResizing.SetSize(window.DataContext as MainViewModel);
+            }
         }
         }
-        SettingsHelper.Settings.StartUp.LastFile = lastFile;
-        await SettingsHelper.SaveSettingsAsync();
-        await KeybindingsHelper.UpdateKeyBindingsFile(); // Save keybindings
-        FileDeletionHelper.DeleteTempFiles();
-        FileHistoryNavigation.WriteToFile();
-        ArchiveExtraction.Cleanup();
-        Environment.Exit(0);
     }
     }
+
+    #endregion
 }
 }

+ 294 - 0
src/PicView.Avalonia/WindowBehavior/WindowResizing.cs

@@ -0,0 +1,294 @@
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Media.Imaging;
+using Avalonia.Threading;
+using ImageMagick;
+using PicView.Avalonia.Navigation;
+using PicView.Avalonia.UI;
+using PicView.Avalonia.ViewModels;
+using PicView.Core.Calculations;
+using PicView.Core.Config;
+using PicView.Core.Navigation;
+
+namespace PicView.Avalonia.WindowBehavior;
+
+public static class WindowResizing
+{
+    #region Window Resize Handling
+
+    public static void HandleWindowResize(Window window, AvaloniaPropertyChangedEventArgs<Size> size)
+    {
+        if (!SettingsHelper.Settings.WindowProperties.AutoFit)
+        {
+            return;
+        }
+
+        if (!size.OldValue.HasValue || !size.NewValue.HasValue)
+        {
+            return;
+        }
+
+        if (size.OldValue.Value.Width == 0 || size.OldValue.Value.Height == 0 ||
+            size.NewValue.Value.Width == 0 || size.NewValue.Value.Height == 0)
+        {
+            return;
+        }
+
+        if (size.Sender != window)
+        {
+            return;
+        }
+
+        var x = (size.OldValue.Value.Width - size.NewValue.Value.Width) / 2;
+        var y = (size.OldValue.Value.Height - size.NewValue.Value.Height) / 2;
+
+        window.Position = new PixelPoint(window.Position.X + (int)x, window.Position.Y + (int)y);
+    }
+
+    #endregion
+
+    #region Set Window Size
+
+    public static void SetSize(MainViewModel vm)
+    {
+        double firstWidth, firstHeight;
+        var preloadValue = vm.ImageIterator?.GetCurrentPreLoadValue();
+        if (preloadValue == null)
+        {
+            if (vm.FileInfo is null)
+            {
+                if (vm.ImageSource is Bitmap bitmap)
+                {
+                    firstWidth = bitmap.PixelSize.Width;
+                    firstHeight = bitmap.PixelSize.Height;
+                }
+                else
+                {
+                    return;
+                }
+            }
+            else
+            {
+                var magickImage = new MagickImage();
+                magickImage.Ping(vm.FileInfo);
+                firstWidth = magickImage.Width;
+                firstHeight = magickImage.Height;
+            }
+        }
+        else
+        {
+            firstWidth = GetWidth(preloadValue);
+            firstHeight = GetHeight(preloadValue);
+        }
+
+        if (SettingsHelper.Settings.ImageScaling.ShowImageSideBySide)
+        {
+            var secondaryPreloadValue = vm.ImageIterator?.GetNextPreLoadValue();
+            double secondWidth, secondHeight;
+            if (secondaryPreloadValue != null)
+            {
+                secondWidth = GetWidth(secondaryPreloadValue);
+                secondHeight = GetHeight(secondaryPreloadValue);
+            }
+            else if (vm.ImageIterator is not null)
+            {
+                var nextIndex = vm.ImageIterator.GetIteration(vm.ImageIterator.CurrentIndex,
+                    vm.ImageIterator.IsReversed ? NavigateTo.Previous : NavigateTo.Next);
+                var magickImage = new MagickImage();
+                magickImage.Ping(vm.ImageIterator.ImagePaths[nextIndex]);
+                secondWidth = magickImage.Width;
+                secondHeight = magickImage.Height;
+            }
+            else
+            {
+                secondWidth = 0;
+                secondHeight = 0;
+            }
+
+            if (Dispatcher.UIThread.CheckAccess())
+            {
+                SetSize(firstWidth, firstHeight, secondWidth, secondHeight, vm.RotationAngle, vm);
+            }
+            else
+            {
+                Dispatcher.UIThread.InvokeAsync(() =>
+                    SetSize(firstWidth, firstHeight, secondWidth, secondHeight, vm.RotationAngle, vm));
+            }
+        }
+        else
+        {
+            if (Dispatcher.UIThread.CheckAccess())
+            {
+                SetSize(firstWidth, firstHeight, 0, 0, vm.RotationAngle, vm);
+            }
+            else
+            {
+                Dispatcher.UIThread.InvokeAsync(() => SetSize(firstWidth, firstHeight, 0, 0, vm.RotationAngle, vm));
+            }
+        }
+
+        return;
+
+        double GetWidth(PreLoader.PreLoadValue preloadValue)
+        {
+            return preloadValue?.ImageModel?.PixelWidth ?? vm.ImageWidth;
+        }
+
+        double GetHeight(PreLoader.PreLoadValue preloadValue)
+        {
+            return preloadValue?.ImageModel?.PixelHeight ?? vm.ImageHeight;
+        }
+    }
+
+    public static void SetSize(double width, double height, double secondWidth, double secondHeight, double rotation,
+        MainViewModel vm)
+    {
+        width = width == 0 ? vm.ImageWidth : width;
+        height = height == 0 ? vm.ImageHeight : height;
+        if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
+        {
+            return;
+        }
+
+        var mainView = UIHelper.GetMainView;
+        if (mainView is null)
+        {
+            return;
+        }
+
+        const int padding = 45;
+        var screenSize = ScreenHelper.ScreenSize;
+        double desktopMinWidth = 0, desktopMinHeight = 0, containerWidth = 0, containerHeight = 0;
+        desktopMinWidth = desktop.MainWindow.MinWidth;
+        desktopMinHeight = desktop.MainWindow.MinHeight;
+        containerWidth = mainView.Bounds.Width;
+        containerHeight = mainView.Bounds.Height;
+
+        if (double.IsNaN(containerWidth) || double.IsNaN(containerHeight) || double.IsNaN(width) ||
+            double.IsNaN(height))
+        {
+            return;
+        }
+
+        ImageSizeCalculationHelper.ImageSize size;
+        if (SettingsHelper.Settings.ImageScaling.ShowImageSideBySide && secondWidth > 0 && secondHeight > 0)
+        {
+            size = ImageSizeCalculationHelper.GetImageSize(
+                width,
+                height,
+                secondWidth,
+                secondHeight,
+                screenSize.WorkingAreaWidth,
+                screenSize.WorkingAreaHeight,
+                desktopMinWidth,
+                desktopMinHeight,
+                ImageSizeCalculationHelper.GetInterfaceSize(),
+                rotation,
+                padding,
+                screenSize.Scaling,
+                vm.TitlebarHeight,
+                vm.BottombarHeight,
+                vm.GalleryHeight,
+                containerWidth,
+                containerHeight);
+        }
+        else
+        {
+            size = ImageSizeCalculationHelper.GetImageSize(
+                width,
+                height,
+                screenSize.WorkingAreaWidth,
+                screenSize.WorkingAreaHeight,
+                desktopMinWidth,
+                desktopMinHeight,
+                ImageSizeCalculationHelper.GetInterfaceSize(),
+                rotation,
+                padding,
+                screenSize.Scaling,
+                vm.TitlebarHeight,
+                vm.BottombarHeight,
+                vm.GalleryHeight,
+                containerWidth,
+                containerHeight);
+        }
+
+        vm.TitleMaxWidth = size.TitleMaxWidth;
+        vm.ImageWidth = size.Width;
+        vm.SecondaryImageWidth = size.SecondaryWidth;
+        vm.ImageHeight = size.Height;
+        vm.GalleryMargin = new Thickness(0, 0, 0, size.Margin);
+
+        vm.ScrollViewerWidth = size.ScrollViewerWidth;
+        vm.ScrollViewerHeight = size.ScrollViewerHeight;
+
+        if (SettingsHelper.Settings.WindowProperties.AutoFit)
+        {
+            if (SettingsHelper.Settings.WindowProperties.Fullscreen ||
+                SettingsHelper.Settings.WindowProperties.Maximized)
+            {
+                vm.GalleryWidth = double.NaN;
+            }
+            else
+            {
+                vm.GalleryWidth = vm.RotationAngle is 90 or 270
+                    ? Math.Max(size.Height, desktopMinHeight)
+                    : Math.Max(size.Width, desktopMinWidth);
+            }
+        }
+        else
+        {
+            vm.GalleryWidth = double.NaN;
+            ;
+        }
+    }
+
+    public static void SaveSize(Window window)
+    {
+        if (Dispatcher.UIThread.CheckAccess())
+        {
+            Set();
+        }
+        else
+        {
+            Dispatcher.UIThread.InvokeAsync(Set);
+        }
+
+        return;
+
+        void Set()
+        {
+            var top = window.Position.Y;
+            var left = window.Position.X;
+            SettingsHelper.Settings.WindowProperties.Top = top;
+            SettingsHelper.Settings.WindowProperties.Left = left;
+            SettingsHelper.Settings.WindowProperties.Width = window.Width;
+            SettingsHelper.Settings.WindowProperties.Height = window.Height;
+        }
+    }
+
+    public static void RestoreSize(Window window)
+    {
+        if (Dispatcher.UIThread.CheckAccess())
+        {
+            Set();
+        }
+        else
+        {
+            Dispatcher.UIThread.InvokeAsync(Set);
+        }
+
+        return;
+
+        void Set()
+        {
+            var x = (int)SettingsHelper.Settings.WindowProperties.Left;
+            var y = (int)SettingsHelper.Settings.WindowProperties.Top;
+            window.Position = new PixelPoint(x, y);
+            window.Width = SettingsHelper.Settings.WindowProperties.Width;
+            window.Height = SettingsHelper.Settings.WindowProperties.Height;
+        }
+    }
+
+    #endregion
+}