Pārlūkot izejas kodu

CHange startup procedure to load image first and the rest later #125

Ruben 1 gadu atpakaļ
vecāks
revīzija
ed95e6b314

+ 132 - 0
src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs

@@ -0,0 +1,132 @@
+namespace PicView.Core.Calculations;
+
+/// <summary>
+/// Provides methods for calculating image size based on monitor dimensions, rotation angle, and stretch parameter.
+/// </summary>
+public static class ImageSizeCalculationHelper
+{
+    /// <summary>
+    /// Represents the dimensions of an image.
+    /// </summary>
+    public struct ImageSize
+    {
+        /// <summary>
+        /// Gets the width of the image.
+        /// </summary>
+        public double Width { get; private set; }
+
+        /// <summary>
+        /// Gets the height of the image.
+        /// </summary>
+        public double Height { get; private set; }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ImageSize"/> struct with the specified width and height.
+        /// </summary>
+        /// <param name="width">The width of the image.</param>
+        /// <param name="height">The height of the image.</param>
+        public ImageSize(double width, double height)
+        {
+            Width = width;
+            Height = height;
+        }
+    }
+
+    /// <summary>
+    /// Calculates the adjusted image size based on specified parameters.
+    /// </summary>
+    /// <param name="width">The original width of the image.</param>
+    /// <param name="height">The original height of the image.</param>
+    /// <param name="monitorWidth">The width of the monitor.</param>
+    /// <param name="monitorHeight">The height of the monitor.</param>
+    /// <param name="rotationAngle">The rotation angle of the image in degrees.</param>
+    /// <param name="stretch">A boolean indicating whether to stretch the image to fit the container.</param>
+    /// <param name="padding">The padding applied to the image.</param>
+    /// <param name="dpiScaling">The DPI scaling factor of the monitor.</param>
+    /// <param name="fullscreen">A boolean indicating whether the image is displayed in fullscreen mode.</param>
+    /// <param name="uiTopSize">The size of the top UI element.</param>
+    /// <param name="uiBottomSize">The size of the bottom UI element.</param>
+    /// <param name="galleryHeight">The height of the gallery.</param>
+    /// <param name="autoFit">A boolean indicating whether to automatically fit the image within the monitor.</param>
+    /// <param name="containerWidth">The width of the container.</param>
+    /// <param name="containerHeight">The height of the container.</param>
+    /// <param name="scrollEnabled">A boolean indicating whether scrolling is enabled.</param>
+    /// <returns>An <see cref="ImageSize"/> struct representing the adjusted image size.</returns>
+    public static ImageSize GetImageSize(double width,
+        double height,
+        double monitorWidth,
+        double monitorHeight,
+        int rotationAngle,
+        bool stretch,
+        double padding,
+        double dpiScaling,
+        bool fullscreen,
+        double uiTopSize,
+        double uiBottomSize,
+        double galleryHeight,
+        bool autoFit,
+        double containerWidth,
+        double containerHeight,
+        bool scrollEnabled)
+    {
+        if (width <= 0 || height <= 0 || rotationAngle > 360 || rotationAngle < 0)
+        {
+            // Invalid input, return zero-sized image
+            return new ImageSize(0, 0);
+        }
+
+        double aspectRatio;
+        double maxWidth, maxHeight;
+
+        var borderSpaceHeight = fullscreen ? 0 : uiTopSize + uiBottomSize + galleryHeight;
+        var borderSpaceWidth = fullscreen ? 0 : padding;
+
+        var workAreaWidth = (monitorWidth * dpiScaling) - borderSpaceWidth;
+        var workAreaHeight = (monitorHeight * dpiScaling) - borderSpaceHeight;
+
+        if (autoFit)
+        {
+            maxWidth = stretch ? workAreaWidth : Math.Min(workAreaWidth - padding, width);
+            maxHeight = stretch ? workAreaHeight : Math.Min(workAreaHeight - padding, height);
+        }
+        else
+        {
+            maxWidth = stretch ? containerWidth : Math.Min(containerWidth, width);
+            if (scrollEnabled)
+            {
+                maxHeight = stretch ? containerHeight : height;
+            }
+            else
+            {
+                maxHeight = stretch
+                    ? containerHeight - galleryHeight
+                    : Math.Min(containerHeight - galleryHeight, height);
+            }
+        }
+
+        // aspect ratio calculation
+        switch (rotationAngle)
+        {
+            case 0:
+            case 180:
+                aspectRatio = Math.Min(maxWidth / width, maxHeight / height);
+                break;
+
+            case 90:
+            case 270:
+                aspectRatio = Math.Min(maxWidth / height, maxHeight / width);
+                break;
+
+            default:
+                var rotationRadians = rotationAngle * Math.PI / 180;
+                var newWidth = Math.Abs(width * Math.Cos(rotationRadians)) +
+                               Math.Abs(height * Math.Sin(rotationRadians));
+                var newHeight = Math.Abs(width * Math.Sin(rotationRadians)) +
+                                Math.Abs(height * Math.Cos(rotationRadians));
+                aspectRatio = Math.Min(maxWidth / newWidth, maxHeight / newHeight);
+                break;
+        }
+
+        return new ImageSize(width * aspectRatio, height * aspectRatio);
+    }
+}

+ 1 - 1
src/PicView.WPF/App.xaml

@@ -2,7 +2,7 @@
     x:Class="PicView.WPF.App"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    StartupUri="/Views/Windows/MainWindow.xaml">
+    StartupUri="/Views/Windows/Startup-Window.xaml">
     <Application.Resources>
         <ResourceDictionary>
             <ResourceDictionary.MergedDictionaries>

+ 4 - 0
src/PicView.WPF/ChangeImage/ErrorHandling.cs

@@ -25,6 +25,10 @@ namespace PicView.WPF.ChangeImage
         /// <returns>True if not intended to change image or index is not valid</returns>
         internal static bool CheckOutOfRange()
         {
+            if (Pics is null)
+            {
+                return true;
+            }
             var value = true;
             ConfigureWindows.GetMainWindow.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)(() =>
             {

+ 42 - 34
src/PicView.WPF/ChangeImage/QuickLoad.cs

@@ -8,6 +8,7 @@ using System.Diagnostics;
 using System.IO;
 using System.Windows;
 using System.Windows.Input;
+using System.Windows.Media.Imaging;
 using System.Windows.Threading;
 using XamlAnimatedGif;
 using static PicView.WPF.ChangeImage.LoadPic;
@@ -25,29 +26,29 @@ namespace PicView.WPF.ChangeImage
         /// Load Image from blank values and show loading preview
         /// </summary>
         /// <param name="file"></param>
-        internal static async Task QuickLoadAsync(string file) => await Task.Run(async () =>
+        internal static async Task QuickLoadAsync(string file, FileInfo? fileInfo = null, BitmapSource? preparedSource = null) => await Task.Run(async () =>
         {
             var mainWindow = ConfigureWindows.GetMainWindow;
-
-            var fileInfo = new FileInfo(file);
-            if (!fileInfo.Exists) // If not file, try to load if URL, base64 or directory
+            fileInfo ??= new FileInfo(file);
+            if (preparedSource is not null)
             {
-                await LoadPicFromStringAsync(file, fileInfo).ConfigureAwait(false);
-                return;
-            }
+                if (!fileInfo.Exists) // If not file, try to load if URL, base64 or directory
+                {
+                    await LoadPicFromStringAsync(file, fileInfo).ConfigureAwait(false);
+                    return;
+                }
 
-            if (file.IsArchive()) // Handle if file exist and is archive
-            {
-                await LoadPicFromArchiveAsync(file).ConfigureAwait(false);
-                return;
+                if (file.IsArchive()) // Handle if file exist and is archive
+                {
+                    await LoadPicFromArchiveAsync(file).ConfigureAwait(false);
+                    return;
+                }
             }
 
-            var bitmapSource = await Image2BitmapSource.ReturnBitmapSourceAsync(fileInfo).ConfigureAwait(false);
+            var bitmapSource = preparedSource ?? await Image2BitmapSource.ReturnBitmapSourceAsync(fileInfo).ConfigureAwait(false);
             await mainWindow.MainImage.Dispatcher.InvokeAsync(() =>
             {
                 mainWindow.MainImage.Source = bitmapSource;
-
-                FitImage(bitmapSource.Width, bitmapSource.Height);
             }, DispatcherPriority.Send);
 
             if (fileInfo.Extension.Equals(".gif", StringComparison.OrdinalIgnoreCase))
@@ -73,6 +74,10 @@ namespace PicView.WPF.ChangeImage
                 if (Settings.Default.IsBottomGalleryShown)
                 {
                     GalleryToggle.ShowBottomGallery();
+                }
+
+                if (preparedSource is not null)
+                {
                     FitImage(bitmapSource.Width, bitmapSource.Height);
                 }
             }, DispatcherPriority.Normal);
@@ -87,32 +92,35 @@ namespace PicView.WPF.ChangeImage
 
             if (Settings.Default.IsBottomGalleryShown)
             {
-                try
+                _ = Task.Run(async () =>
                 {
-                    await GalleryLoad.LoadAsync().ConfigureAwait(false);
-                    // Update gallery selections
-                    await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                    try
+                    {
+                        await GalleryLoad.LoadAsync().ConfigureAwait(false);
+                        // Update gallery selections
+                        await UC.GetPicGallery.Dispatcher.InvokeAsync(() =>
+                        {
+                            // Select current item
+                            GalleryNavigation.SetSelected(FolderIndex, true);
+                            GalleryNavigation.SelectedGalleryItem = FolderIndex;
+                            GalleryNavigation.ScrollToGalleryCenter();
+                        });
+                    }
+                    catch (TaskCanceledException exception)
                     {
-                        // Select current item
-                        GalleryNavigation.SetSelected(FolderIndex, true);
-                        GalleryNavigation.SelectedGalleryItem = FolderIndex;
-                        GalleryNavigation.ScrollToGalleryCenter();
-                    });
-                }
-                catch (TaskCanceledException exception)
-                {
 #if DEBUG
-                    Trace.WriteLine($"{nameof(QuickLoadAsync)}  exception:\n{exception.Message}");
+                        Trace.WriteLine($"{nameof(QuickLoadAsync)}  exception:\n{exception.Message}");
 #endif
-                    if (ConfigureWindows.GetMainWindow.Visibility == Visibility.Hidden)
+                        if (ConfigureWindows.GetMainWindow.Visibility == Visibility.Hidden)
+                        {
+                            Environment.Exit(0);
+                        }
+                    }
+                    catch (Exception)
                     {
-                        Environment.Exit(0);
+                        //
                     }
-                }
-                catch (Exception)
-                {
-                    //
-                }
+                });
             }
 
             // Add recent files, except when browsing archive

+ 8 - 1
src/PicView.WPF/ChangeTitlebar/EditTitleBar.cs

@@ -20,7 +20,14 @@ namespace PicView.WPF.ChangeTitlebar
                 return;
             }
 
-            WindowSizing.Move(sender, e);
+            try
+            {
+                WindowSizing.Move(sender, e);
+            }
+            catch (Exception)
+            {
+                //
+            }
             Refocus();
             e.Handled = true; // Disable text clicking
         }

+ 0 - 1
src/PicView.WPF/PicView.WPF.csproj

@@ -319,7 +319,6 @@
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\PicView.Core\PicView.Core.csproj" />
-    <ProjectReference Include="..\PicView.Tools\PicView.Tools.csproj" />
     <ProjectReference Include="..\XamlAnimatedGif\XamlAnimatedGif.csproj" />
   </ItemGroup>
   <ItemGroup>

+ 15 - 8
src/PicView.WPF/SystemIntegration/MonitorSize.cs

@@ -80,25 +80,32 @@ namespace PicView.WPF.SystemIntegration
         /// Gets the size and DPI scaling of the current monitor screen.
         /// </summary>
         /// <returns>A new instance of the <see cref="MonitorSize"/> struct representing the current monitor screen.</returns>
-        internal static MonitorSize GetMonitorSize()
+        internal static MonitorSize GetMonitorSize(Window? window)
         {
-            if (Application.Current is null) // Fixes bug when closing window
+            if (Application.Current is null || window is null) // Fixes bug when closing window
                 return new MonitorSize(SystemParameters.WorkArea.Width, SystemParameters.WorkArea.Height, 1,
                     SystemParameters.WorkArea);
 
             Screen? currentMonitor = null;
             PresentationSource? source;
             double dpiScaling = 0;
-            ConfigureWindows.GetMainWindow.Dispatcher.Invoke(DispatcherPriority.Send, () => // Avoid threading errors
+            window?.Dispatcher.Invoke(DispatcherPriority.Send, () => // Avoid threading errors
             {
                 // Get the current monitor screen information
-                currentMonitor = Screen.FromHandle(new WindowInteropHelper(Application.Current.MainWindow!).Handle);
+                currentMonitor = Screen.FromHandle(new WindowInteropHelper(Application.Current.MainWindow ?? window).Handle);
 
                 // Find out if the app is being scaled by the monitor
-                source = PresentationSource.FromVisual(Application.Current.MainWindow!);
-                dpiScaling = source is { CompositionTarget: not null }
-                    ? source.CompositionTarget.TransformFromDevice.M11
-                    : 1;
+                try
+                {
+                    source = PresentationSource.FromVisual(window);
+                    dpiScaling = source is { CompositionTarget: not null }
+                        ? source.CompositionTarget.TransformFromDevice.M11
+                        : 1;
+                }
+                catch (Exception)
+                {
+                    //
+                }
             });
 
             var monitorWidth = currentMonitor.Bounds.Width * dpiScaling;

+ 1 - 1
src/PicView.WPF/UILogic/ConfigureWindows.cs

@@ -16,7 +16,7 @@ namespace PicView.WPF.UILogic
         /// <summary>
         /// The Main Window?
         /// </summary>
-        internal static readonly MainWindow GetMainWindow = (MainWindow)Application.Current.MainWindow;
+        internal static MainWindow GetMainWindow { get; set; }
 
         /// <summary>
         /// Primary ContextMenu

+ 12 - 2
src/PicView.WPF/UILogic/DragAndDrop/Image_DragAndDrop.cs

@@ -188,7 +188,17 @@ namespace PicView.WPF.UILogic.DragAndDrop
             await Task.Run(async () =>
             {
                 InitialPath = files[0];
-                await QuickLoad.QuickLoadAsync(files[0]).ConfigureAwait(false);
+                var fileInfo = new FileInfo(files[0]);
+
+                //detect whether its a directory or file
+                if (fileInfo.Attributes.HasFlag(FileAttributes.Directory))
+                {
+                    await LoadPic.LoadPicFromFolderAsync(fileInfo).ConfigureAwait(false);
+                }
+                else
+                {
+                    await QuickLoad.QuickLoadAsync(files[0], fileInfo).ConfigureAwait(false);
+                }
 
                 // Open additional windows if multiple files dropped
                 foreach (var file in files.Skip(1))
@@ -230,7 +240,7 @@ namespace PicView.WPF.UILogic.DragAndDrop
 
             try
             {
-                _dropOverlay.UpdateContent(element);
+                _dropOverlay?.UpdateContent(element);
             }
             catch (Exception)
             {

+ 0 - 6
src/PicView.WPF/UILogic/Loading/LoadControls.cs

@@ -305,11 +305,5 @@ namespace PicView.WPF.UILogic.Loading
             Trace.WriteLine(nameof(GetQuickResize) + " loaded ");
 #endif
         }
-
-        internal static void LoadSpinWaiter()
-        {
-            GetSpinWaiter = new SpinWaiter();
-            ConfigureWindows.GetMainWindow.ParentContainer.Children.Add(GetSpinWaiter);
-        }
     }
 }

+ 116 - 38
src/PicView.WPF/UILogic/Loading/StartLoading.cs

@@ -1,10 +1,19 @@
-using System.Windows;
+using System.IO;
+using System.Windows;
 using System.Windows.Controls;
+using ImageMagick;
+using System.Windows.Media.Imaging;
+using System.Windows.Media;
+using System.Windows.Threading;
 using PicView.WPF.ChangeImage;
 using PicView.WPF.ConfigureSettings;
+using PicView.WPF.ImageHandling;
 using PicView.WPF.Properties;
 using PicView.WPF.Shortcuts;
 using PicView.WPF.SystemIntegration;
+using PicView.WPF.UILogic.Sizing;
+using PicView.WPF.Views.UserControls.Misc;
+using PicView.WPF.Views.Windows;
 using static PicView.WPF.ChangeImage.Navigation;
 using static PicView.WPF.UILogic.Loading.LoadContextMenus;
 using static PicView.WPF.UILogic.Loading.LoadControls;
@@ -16,13 +25,88 @@ namespace PicView.WPF.UILogic.Loading
 {
     internal static class StartLoading
     {
-        internal static async Task LoadedEvent()
+        internal static async Task LoadedEvent(Startup_Window startupWindow)
         {
-            Pics = new List<string>();
-
+            var spinner = GetSpinWaiter;
+            spinner = new SpinWaiter();
+            startupWindow.TheGrid.Children.Add(spinner);
+            Panel.SetZIndex(spinner, 99);
+            BitmapSource? bitmapSource = null;
+            var image = new Image
+            {
+                Stretch = Stretch.Uniform,
+            };
             // Load sizing properties
-            MonitorInfo = MonitorSize.GetMonitorSize();
+            MonitorInfo = MonitorSize.GetMonitorSize(startupWindow);
+            if (Settings.Default.AutoFitWindow == false && Settings.Default.Fullscreen == false)
+            {
+                SetLastWindowSize(startupWindow);
+            }
+
+            var args = Environment.GetCommandLineArgs();
 
+            if (args.Length > 1)
+            {
+                await Task.Run(async () =>
+                {
+                    using var magickImage = new MagickImage();
+                    magickImage.Ping(args[1]);
+                    var thumb = magickImage.GetExifProfile()?.CreateThumbnail();
+                    var bitmapThumb = thumb?.ToBitmapSource();
+                    bitmapThumb?.Freeze();
+                    await startupWindow.Dispatcher.InvokeAsync(() =>
+                    {
+                        image.Source = bitmapThumb;
+                        startupWindow.TheGrid.Children.Add(image);
+                    });
+                });
+                bitmapSource = await Image2BitmapSource.ReturnBitmapSourceAsync(new FileInfo(args[1])).ConfigureAwait(false);
+                await startupWindow.Dispatcher.InvokeAsync(() =>
+                {
+                    if (Settings.Default.AutoFitWindow)
+                    {
+                        var size = Core.Calculations.ImageSizeCalculationHelper.GetImageSize(
+                            bitmapSource.PixelWidth,
+                            bitmapSource.PixelHeight,
+                            MonitorInfo.WorkArea.Width,
+                            MonitorInfo.WorkArea.Height,
+                            0,
+                            Settings.Default.FillImage,
+                            20 * MonitorInfo.DpiScaling,
+                            MonitorInfo.DpiScaling,
+                            Settings.Default.Fullscreen,
+                            30 * MonitorInfo.DpiScaling,
+                            25 * MonitorInfo.DpiScaling,
+                            Settings.Default.IsBottomGalleryShown ? Settings.Default.BottomGalleryItemSize : 0,
+                            true,
+                            ConfigureWindows.GetMainWindow.ParentContainer.Width,
+                            ConfigureWindows.GetMainWindow.ParentContainer.Height,
+                            Settings.Default.ScrollEnabled
+                            );
+                        image.Stretch = Stretch.Fill;
+                        image.Width = startupWindow.Width = size.Width;
+                        image.Height = startupWindow.Height = size.Height;
+                        CenterWindowOnScreen(startupWindow);
+                    }
+                    image.Source = bitmapSource;
+                });
+            }
+
+            await startupWindow.Dispatcher.InvokeAsync(() =>
+            {
+                startupWindow.TheGrid.Children.Remove(spinner);
+                var mainWindow = new MainWindow();
+                ConfigureWindows.GetMainWindow = mainWindow;
+                // Determine preferred UI for startup
+                if (Settings.Default.AutoFitWindow == false)
+                {
+                    SetLastWindowSize(mainWindow);
+                }
+                mainWindow.MainImage.Source = image.Source;
+                GetSpinWaiter = spinner;
+                mainWindow.ParentContainer.Children.Add(spinner);
+            });
+            Pics = new List<string>();
             await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
             {
                 // Set min size to DPI scaling
@@ -31,7 +115,7 @@ namespace PicView.WPF.UILogic.Loading
 
                 SetWindowBehavior();
                 if (Settings.Default.AutoFitWindow == false)
-                    SetLastWindowSize();
+                    SetLastWindowSize(ConfigureWindows.GetMainWindow);
 
                 ConfigureWindows.GetMainWindow.Scroller.VerticalScrollBarVisibility = Settings.Default.ScrollEnabled
                     ? ScrollBarVisibility.Auto
@@ -49,45 +133,39 @@ namespace PicView.WPF.UILogic.Loading
                         = Visibility.Collapsed;
                 }
             });
-            await CustomKeybindings.LoadKeybindings().ConfigureAwait(false);
-            ConfigColors.UpdateColor();
-
-            var args = Environment.GetCommandLineArgs();
-
-            // Determine preferred UI for startup
-            if (Settings.Default.Fullscreen)
+            if (args.Length > 1)
             {
-                if (args.Length < 2)
-                {
-                    Settings.Default.Fullscreen = false;
-                }
-                else
-                {
-                    await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
-                    {
-                        Fullscreen_Restore(true);
-                    });
-                }
+                await QuickLoad.QuickLoadAsync(args[1], null, bitmapSource).ConfigureAwait(false);
+            }
+            else
+            {
+                ErrorHandling.Unload(true);
             }
 
-            // Load image if possible
-            if (args.Length < 2)
+            await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
             {
-                await ConfigureWindows.GetMainWindow.Dispatcher.InvokeAsync(() =>
+                ConfigureWindows.GetMainWindow.Show();
+                if (Settings.Default.Fullscreen)
                 {
-                    // Make sure to fix loading spinner showing up
-                    if (ConfigureWindows.GetMainWindow.MainImage.Source is null)
+                    if (args.Length < 2)
                     {
-                        GetSpinWaiter.Visibility = Visibility.Collapsed;
+                        Settings.Default.Fullscreen = false;
                     }
-                });
-                ErrorHandling.Unload(true);
-            }
-            else
-            {
-                InitialPath = args[1];
-                await QuickLoad.QuickLoadAsync(args[1]).ConfigureAwait(false);
-            }
+                    else
+                    {
+                        Fullscreen_Restore(true);
+                    }
+                }
+                if (Settings.Default.AutoFitWindow)
+                {
+                    ScaleImage.TryFitImage();
+                }
+                startupWindow.Close();
+            });
+
+            await CustomKeybindings.LoadKeybindings().ConfigureAwait(false);
+
+            ConfigColors.UpdateColor();
         }
 
         internal static void AddDictionaries()

+ 3 - 3
src/PicView.WPF/UILogic/Sizing/ScaleImage.cs

@@ -220,8 +220,8 @@ namespace PicView.WPF.UILogic.Sizing
 
             if (Settings.Default.AutoFitWindow)
             {
-                CenterWindowOnScreen(Settings.Default
-                    .KeepCentered); // Vertically center or vertically and horizontally center
+                // Vertically center or vertically and horizontally center
+                CenterWindowOnScreen(GetMainWindow, Settings.Default.KeepCentered);
 
                 var titleBarMaxWidth = RotationAngle is 0 or 180
                     ? Math.Max(XWidth, GetMainWindow.MinWidth)
@@ -241,7 +241,7 @@ namespace PicView.WPF.UILogic.Sizing
             else
             {
                 // Fix title width to window size
-                GetMainWindow.TitleText.MaxWidth = GetMainWindow.ActualWidth - interfaceSize;
+                GetMainWindow.TitleText.MaxWidth = GetMainWindow.ActualWidth - interfaceSize <= 0 ? 0 : GetMainWindow.ActualWidth - interfaceSize;
             }
         }
 

+ 56 - 38
src/PicView.WPF/UILogic/Sizing/WindowSizing.cs

@@ -1,4 +1,5 @@
-using System.Windows;
+using System.Diagnostics;
+using System.Windows;
 using System.Windows.Input;
 using PicView.WPF.ChangeImage;
 using PicView.WPF.FileHandling;
@@ -114,13 +115,22 @@ namespace PicView.WPF.UILogic.Sizing
             }
             else
             {
-                if (e.LeftButton != MouseButtonState.Pressed) return;
-                GetMainWindow.DragMove();
-                // Update info for possible new screen, needs more engineering
-                // Seems to work
-                MonitorInfo = MonitorSize.GetMonitorSize();
+                if (e.LeftButton != MouseButtonState.Pressed)
+                    return;
+                try
+                {
+                    GetMainWindow.DragMove();
+                    // Update info for possible new screen, needs more engineering
+                    // Seems to work
+                    MonitorInfo = MonitorSize.GetMonitorSize(GetMainWindow);
 
-                SetWindowSize();
+                    SetWindowSize(GetMainWindow);
+                }
+                catch (Exception exception)
+                {
+                    Trace.WriteLine(exception);
+                    throw;
+                }
             }
         }
 
@@ -134,11 +144,19 @@ namespace PicView.WPF.UILogic.Sizing
                 return;
             }
 
-            if (e.LeftButton != MouseButtonState.Pressed) return;
-            GetMainWindow.DragMove();
-            MonitorInfo = MonitorSize.GetMonitorSize();
+            if (e.LeftButton != MouseButtonState.Pressed)
+                return;
+            try
+            {
+                GetMainWindow.DragMove();
+                MonitorInfo = MonitorSize.GetMonitorSize(GetMainWindow);
 
-            SetWindowSize();
+                SetWindowSize(GetMainWindow);
+            }
+            catch (Exception exception)
+            {
+                Trace.WriteLine(exception);
+            }
         }
 
         /// <summary>
@@ -156,7 +174,7 @@ namespace PicView.WPF.UILogic.Sizing
             GetMainWindow.TitleBar.Margin = new Thickness(0);
             GetMainWindow.LowerBar.Margin = new Thickness(0);
 
-            SetWindowSize();
+            SetWindowSize(ConfigureWindows.GetMainWindow);
         }
 
         /// <summary>
@@ -175,8 +193,8 @@ namespace PicView.WPF.UILogic.Sizing
                 return;
             }
 
-            SetWindowSize(); // Fixes popping up on wrong monitor?
-            MonitorInfo = MonitorSize.GetMonitorSize();
+            SetWindowSize(ConfigureWindows.GetMainWindow); // Fixes popping up on wrong monitor?
+            MonitorInfo = MonitorSize.GetMonitorSize(GetMainWindow);
 
             if (GetMainWindow.WindowState == WindowState.Maximized || gotoFullscreen)
             {
@@ -226,7 +244,7 @@ namespace PicView.WPF.UILogic.Sizing
 
                 if (Settings.Default.AutoFitWindow == false)
                 {
-                    SetLastWindowSize();
+                    SetLastWindowSize(GetMainWindow);
                 }
 
                 if (Slideshow.SlideTimer != null && Slideshow.SlideTimer.Enabled)
@@ -249,50 +267,50 @@ namespace PicView.WPF.UILogic.Sizing
 
             TryFitImage();
 
-            CenterWindowOnScreen();
+            CenterWindowOnScreen(GetMainWindow);
         }
 
         /// <summary>
         /// Centers on the current monitor
         /// </summary>
-        internal static void CenterWindowOnScreen(bool horizontal = true)
+        internal static void CenterWindowOnScreen(Window window, bool horizontal = true)
         {
-            GetMainWindow.Top =
-                ((MonitorInfo.WorkArea.Height * MonitorInfo.DpiScaling) - GetMainWindow.ActualHeight) / 2 +
+            window.Top =
+                ((MonitorInfo.WorkArea.Height * MonitorInfo.DpiScaling) - window.ActualHeight) / 2 +
                 MonitorInfo.WorkArea.Top;
             if (horizontal)
-                GetMainWindow.Left =
-                    ((MonitorInfo.WorkArea.Width * MonitorInfo.DpiScaling) - GetMainWindow.ActualWidth) / 2 +
+                window.Left =
+                    ((MonitorInfo.WorkArea.Width * MonitorInfo.DpiScaling) - window.ActualWidth) / 2 +
                     MonitorInfo.WorkArea.Left;
         }
 
-        internal static void SetLastWindowSize()
+        internal static void SetLastWindowSize(Window window)
         {
-            GetMainWindow.Dispatcher.Invoke(() =>
+            window.Dispatcher.Invoke(() =>
             {
-                GetMainWindow.Top = Settings.Default.Top;
-                GetMainWindow.Left = Settings.Default.Left;
-                GetMainWindow.Width = double.IsNaN(Settings.Default.Width) ? GetMainWindow.Width :
-                    double.IsNaN(Settings.Default.Width) ? GetMainWindow.ActualWidth : Settings.Default.Width;
-                GetMainWindow.Height = double.IsNaN(Settings.Default.Height) ? GetMainWindow.Height :
-                    double.IsNaN(Settings.Default.Height) ? GetMainWindow.ActualHeight : Settings.Default.Height;
+                window.Top = Settings.Default.Top;
+                window.Left = Settings.Default.Left;
+                window.Width = double.IsNaN(Settings.Default.Width) ? window.Width :
+                    double.IsNaN(Settings.Default.Width) ? window.ActualWidth : Settings.Default.Width;
+                window.Height = double.IsNaN(Settings.Default.Height) ? window.Height :
+                    double.IsNaN(Settings.Default.Height) ? window.ActualHeight : Settings.Default.Height;
             });
         }
 
-        internal static void SetWindowSize()
+        internal static void SetWindowSize(Window window)
         {
             if (Settings.Default.AutoFitWindow && Settings.Default.Fullscreen)
                 return;
 
-            GetMainWindow.Dispatcher.Invoke(() =>
+            window?.Dispatcher.Invoke(() =>
             {
-                if (GetMainWindow.WindowState == WindowState.Maximized || Settings.Default.Fullscreen)
+                if (window.WindowState == WindowState.Maximized || Settings.Default.Fullscreen)
                     return;
 
-                Settings.Default.Top = GetMainWindow.Top;
-                Settings.Default.Left = GetMainWindow.Left;
-                Settings.Default.Height = GetMainWindow.ActualHeight;
-                Settings.Default.Width = GetMainWindow.ActualWidth;
+                Settings.Default.Top = window.Top;
+                Settings.Default.Left = window.Left;
+                Settings.Default.Height = window.ActualHeight;
+                Settings.Default.Width = window.ActualWidth;
 
                 Settings.Default.Save();
             });
@@ -323,7 +341,7 @@ namespace PicView.WPF.UILogic.Sizing
         internal static void SystemEvents_DisplaySettingsChanged()
         {
             // Update size when screen resolution changes
-            MonitorInfo = MonitorSize.GetMonitorSize();
+            MonitorInfo = MonitorSize.GetMonitorSize(GetMainWindow);
             TryFitImage();
         }
 
@@ -336,7 +354,7 @@ namespace PicView.WPF.UILogic.Sizing
         {
             GetMainWindow.Hide(); // Make it feel faster
 
-            SetWindowSize();
+            SetWindowSize(ConfigureWindows.GetMainWindow);
 
             Navigation.Pics?.Clear(); // Make it cancel task
 

+ 1 - 1
src/PicView.WPF/UILogic/UIHelper.cs

@@ -1108,7 +1108,7 @@ namespace PicView.WPF.UILogic
             {
                 await GetMainWindow.Dispatcher.InvokeAsync(() =>
                 {
-                    WindowSizing.CenterWindowOnScreen();
+                    WindowSizing.CenterWindowOnScreen(GetMainWindow);
                 });
             }
         }

+ 1 - 1
src/PicView.WPF/Views/Windows/AboutWindow.xaml.cs

@@ -35,7 +35,7 @@ namespace PicView.WPF.Views.Windows
 
             MaxWidth = MinWidth = 565 * WindowSizing.MonitorInfo.DpiScaling;
             if (!double.IsNaN(Width)) return; // Fixes if user opens window when loading from startup
-            WindowSizing.MonitorInfo = MonitorSize.GetMonitorSize();
+            WindowSizing.MonitorInfo = MonitorSize.GetMonitorSize(this);
             MaxHeight = WindowSizing.MonitorInfo.WorkArea.Height;
             Width *= WindowSizing.MonitorInfo.DpiScaling;
             MaxWidth = MinWidth = 565 * WindowSizing.MonitorInfo.DpiScaling;

+ 1 - 1
src/PicView.WPF/Views/Windows/EffectsWindows.xaml.cs

@@ -24,7 +24,7 @@ namespace PicView.WPF.Views.Windows
             Width *= WindowSizing.MonitorInfo.DpiScaling;
             if (double.IsNaN(Width)) // Fixes if user opens window when loading from startup
             {
-                WindowSizing.MonitorInfo = MonitorSize.GetMonitorSize();
+                WindowSizing.MonitorInfo = MonitorSize.GetMonitorSize(this);
                 MaxHeight = WindowSizing.MonitorInfo.WorkArea.Height;
                 Width *= WindowSizing.MonitorInfo.DpiScaling;
             }

+ 4 - 3
src/PicView.WPF/Views/Windows/MainWindow.xaml.cs

@@ -43,7 +43,6 @@ namespace PicView.WPF.Views.Windows
             }
 
             InitializeComponent();
-            LoadControls.LoadSpinWaiter();
 
             if (Settings.Default.AutoFitWindow == false)
             {
@@ -53,8 +52,6 @@ namespace PicView.WPF.Views.Windows
 
             Topmost = Settings.Default.TopMost;
 
-            Loaded += async (_, _) => await StartLoading.LoadedEvent().ConfigureAwait(false);
-
             ContentRendered += delegate
             {
                 WindowBlur.EnableBlur(this);
@@ -175,6 +172,10 @@ namespace PicView.WPF.Views.Windows
                 }
 
                 var w = ConfigureWindows.GetMainWindow;
+                if (w is null)
+                {
+                    return;
+                }
                 GetStartUpUC?.ResponsiveSize(w.Width);
                 if (w.WindowState == WindowState.Maximized)
                 {

+ 1 - 1
src/PicView.WPF/Views/Windows/ResizeWindow.xaml.cs

@@ -30,7 +30,7 @@ namespace PicView.WPF.Views.Windows
             Width *= MonitorInfo.DpiScaling;
             if (double.IsNaN(Width)) // Fixes if user opens window when loading from startup
             {
-                MonitorInfo = MonitorSize.GetMonitorSize();
+                MonitorInfo = MonitorSize.GetMonitorSize(this);
                 MaxHeight = MonitorInfo.WorkArea.Height;
                 Width *= MonitorInfo.DpiScaling;
             }

+ 13 - 0
src/PicView.WPF/Views/Windows/Startup-Window.xaml

@@ -0,0 +1,13 @@
+<Window
+    x:Class="PicView.WPF.Views.Windows.Startup_Window"
+    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+    Title="Loading..."
+    Width="500"
+    Height="450"
+    AllowsTransparency="True"
+    Background="Transparent"
+    WindowStartupLocation="CenterScreen"
+    WindowStyle="None">
+    <Grid x:Name="TheGrid" />
+</Window>

+ 13 - 0
src/PicView.WPF/Views/Windows/Startup-Window.xaml.cs

@@ -0,0 +1,13 @@
+using PicView.WPF.UILogic.Loading;
+
+namespace PicView.WPF.Views.Windows;
+
+public partial class Startup_Window
+{
+    public Startup_Window()
+    {
+        InitializeComponent();
+
+        ContentRendered += async (_, _) => await StartLoading.LoadedEvent(this).ConfigureAwait(false);
+    }
+}