Преглед изворни кода

[Avalonia] Multi monitor DPI adjustments #26

Ruben пре 1 година
родитељ
комит
657b81c638

+ 5 - 0
src/PicView.Avalonia.Win32/Views/WinMainWindow.axaml.cs

@@ -44,6 +44,11 @@ public partial class WinMainWindow : Window
                         break;
                 }
             });
+            ScalingChanged += (_, _) =>
+            {
+                ScreenHelper.ScreenSize = ScreenHelper.GetScreenSize(this);
+                WindowHelper.SetSize(DataContext as MainViewModel);
+            };
             PointerExited += (_, _) =>
             {
                 MainView.RemoveDragDropView();

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

@@ -29,6 +29,6 @@ public partial class WinTitleBar : UserControl
         {
             return;
         }
-        WindowHelper.WindowDragBehavior((Window)VisualRoot, e);
+        WindowHelper.WindowDragAndDoubleClickBehavior((Window)VisualRoot, e);
     }
 }

+ 8 - 17
src/PicView.Avalonia/UI/ScreenHelper.cs

@@ -2,38 +2,29 @@
 
 namespace PicView.Avalonia.UI;
 
-public readonly struct ScreenSize(int width, int height, int workingAreaWidth, int workingAreaHeight, int x, int y, double scaling)
+public class ScreenSize(double workingAreaWidth, double workingAreaHeight, double scaling)
 {
-    public int Width { get; init; } = width;
-    public int Height { get; init; } = height;
     public double WorkingAreaWidth { get; init; } = workingAreaWidth;
     public double WorkingAreaHeight { get; init; } = workingAreaHeight;
     public double Scaling { get; init; } = scaling;
-    
-    public int X { get; init; }
-    public int Y { get; init; }
 }
 
 public static class ScreenHelper
 {
-    public static ScreenSize ScreenSize { get; set; }
-    public static ScreenSize GetScreenSize(Window window)
+    public static ScreenSize? ScreenSize { get; set; }
+    public static ScreenSize? GetScreenSize(Window window)
     {
-        var screen = window.Screens.ScreenFromWindow(window);
+        var screen = window.Screens.ScreenFromVisual(window);
         
-        var monitorWidth = screen.WorkingArea.Width / screen.Scaling;
-        var monitorHeight = screen.WorkingArea.Height / screen.Scaling;
+        var monitorWidth = screen.Bounds.Width / screen.Scaling;
+        var monitorHeight = screen.Bounds.Height / screen.Scaling;
 
         
-        return new ScreenSize
+        return new ScreenSize(monitorWidth, monitorHeight, screen.Scaling)
         {
-            Width = screen.Bounds.Width,
-            Height = screen.Bounds.Height,
             WorkingAreaWidth = monitorWidth,
             WorkingAreaHeight = monitorHeight,
-            X = screen.Bounds.X,
-            Y = screen.Bounds.Y,
-            Scaling = screen.Scaling
+            Scaling = screen.Scaling,
         };
     }
 }

+ 38 - 21
src/PicView.Avalonia/UI/WindowHelper.cs

@@ -113,7 +113,7 @@ public static class WindowHelper
             var scalingFactor = screen.Scaling;
 
             // Get the current screen's bounds (in physical pixels, not adjusted for scaling)
-            var screenBounds = screen.Bounds;
+            var screenBounds = screen.WorkingArea;
 
             // Calculate the actual bounds in logical units (adjusting for scaling)
             var screenWidth = screenBounds.Width / scalingFactor;
@@ -135,8 +135,6 @@ public static class WindowHelper
             {
                 window.Position = new PixelPoint(window.Position.X, (int)centeredY);
             }
-            
-        
         });
     }
 
@@ -393,7 +391,38 @@ public static class WindowHelper
             vm.IsTopToolbarShown = false; // Hide interface in fullscreen. Remember to turn back when exiting fullscreen
             vm.IsBottomToolbarShown = false;
             vm.IsInterfaceShown = false;
-            Dispatcher.UIThread.Post(() => CenterWindowOnScreen());
+            Dispatcher.UIThread.Post(() =>
+            {
+                // Get the screen that the window is currently on
+                var window = desktop.MainWindow;
+                var screens = desktop.MainWindow.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.Bounds;
+
+                // 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 = new PixelPoint((int)centeredX, (int)centeredY);
+            });
             // TODO: Add Fullscreen mode for Windows (and maybe for Linux?)
             // macOS fullscreen version already works nicely
         }
@@ -515,25 +544,13 @@ public static class WindowHelper
         {
             return;
         }
+
         var screenSize = ScreenHelper.ScreenSize;
         double desktopMinWidth = 0, desktopMinHeight = 0, containerWidth = 0, containerHeight = 0;
-        if (Dispatcher.UIThread.CheckAccess())
-        {
-            desktopMinWidth = desktop.MainWindow.MinWidth;
-            desktopMinHeight = desktop.MainWindow.MinHeight;
-            containerWidth = mainView.Bounds.Width;
-            containerHeight = mainView.Bounds.Height;
-        }
-        else
-        {
-            Dispatcher.UIThread.Invoke(() =>
-            {
-                desktopMinWidth = desktop.MainWindow.MinWidth;
-                desktopMinHeight = desktop.MainWindow.MinHeight;
-                containerWidth = mainView.Bounds.Width;
-                containerHeight = mainView.Bounds.Height;
-            }, DispatcherPriority.Send);
-        }
+        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))
         {

+ 1 - 1
src/PicView.Avalonia/Views/StartUpMenu.axaml.cs

@@ -135,7 +135,7 @@ public partial class StartUpMenu : UserControl
 
         vm.TitleMaxWidth = ImageSizeCalculationHelper.GetTitleMaxWidth(vm.RotationAngle, width, height,
             desktop.MainWindow.MinWidth, desktop.MainWindow.MinHeight, ImageSizeCalculationHelper.GetInterfaceSize(),
-            desktop.MainWindow.Width);
+            desktop.MainWindow.Width, ScreenHelper.ScreenSize.Scaling);
         
         return;
 

+ 4 - 4
src/PicView.Core/Calculations/ImageSizeCalculationHelper.cs

@@ -41,7 +41,7 @@ namespace PicView.Core.Calculations
 
             var fullscreen = SettingsHelper.Settings.WindowProperties.Fullscreen ||
                              SettingsHelper.Settings.WindowProperties.Maximized;
-
+            
             var borderSpaceHeight = fullscreen ? 0 : uiTopSize + uiBottomSize + galleryHeight;
             var borderSpaceWidth = fullscreen ? 0 : padding;
 
@@ -151,7 +151,7 @@ namespace PicView.Core.Calculations
             }
 
             var titleMaxWidth = GetTitleMaxWidth(rotationAngle, xWidth, xHeight, monitorMinWidth, monitorMinHeight,
-                interfaceSize, containerWidth);
+                interfaceSize, containerWidth, dpiScaling);
 
             return new ImageSize(xWidth, xHeight, 0, scrollWidth, scrollHeight, titleMaxWidth, margin, aspectRatio);
         }
@@ -290,7 +290,7 @@ namespace PicView.Core.Calculations
             }
 
             var titleMaxWidth = GetTitleMaxWidth(rotationAngle, combinedWidth, xHeight, monitorMinWidth,
-                monitorMinHeight, interfaceSize, containerWidth);
+                monitorMinHeight, interfaceSize, containerWidth, dpiScaling);
 
             var margin = firstSize.Height > secondSize.Height ? firstSize.Margin : secondSize.Margin;
             return new ImageSize(combinedWidth, xHeight, xWidth2, scrollWidth, scrollHeight, titleMaxWidth, margin,
@@ -299,7 +299,7 @@ namespace PicView.Core.Calculations
 
 
         public static double GetTitleMaxWidth(double rotationAngle, double width, double height, double monitorMinWidth,
-            double monitorMinHeight, double interfaceSize, double containerWidth)
+            double monitorMinHeight, double interfaceSize, double containerWidth, double dpiScaling)
         {
             double titleMaxWidth;
             var maximized = SettingsHelper.Settings.WindowProperties.Fullscreen ||