Browse Source

Listen for DPI changes and update layout.

Steven Kirk 9 years ago
parent
commit
e55ecb9960

+ 2 - 0
src/Gtk/Perspex.Gtk/WindowImpl.cs

@@ -129,6 +129,8 @@ namespace Perspex.Gtk
 
         public Action<Size> Resized { get; set; }
 
+        public Action<double> ScalingChanged { get; set; }
+
         public IPopupImpl CreatePopup()
         {
             return new PopupImpl();

+ 5 - 0
src/Perspex.Controls/Platform/ITopLevelImpl.cs

@@ -62,6 +62,11 @@ namespace Perspex.Platform
         /// </summary>
         Action<Size> Resized { get; set; }
 
+        /// <summary>
+        /// Gets or sets a method called when the window's scaling changes.
+        /// </summary>
+        Action<double> ScalingChanged { get; set; }
+
         /// <summary>
         /// Activates the window.
         /// </summary>

+ 6 - 2
src/Perspex.Controls/Platform/PlatformManager.cs

@@ -131,8 +131,6 @@ namespace Perspex.Controls.Platform
             public Action<Rect> Paint { get; set; }
             public Action<Size> Resized { get; set; }
 
-
-
             public Action Activated
             {
                 get { return _tl.Activated; }
@@ -151,6 +149,12 @@ namespace Perspex.Controls.Platform
                 set { _tl.Deactivated = value; }
             }
 
+            public Action<double> ScalingChanged
+            {
+                get { return _tl.ScalingChanged; }
+                set { _tl.ScalingChanged = value; }
+            }
+
             public void Dispose() => _tl.Dispose();
 
             public IPlatformHandle Handle => _tl.Handle;

+ 15 - 0
src/Perspex.Controls/TopLevel.cs

@@ -12,6 +12,7 @@ using Perspex.Layout;
 using Perspex.Platform;
 using Perspex.Rendering;
 using Perspex.Styling;
+using Perspex.VisualTree;
 
 namespace Perspex.Controls
 {
@@ -99,6 +100,7 @@ namespace Perspex.Controls
             PlatformImpl.Closed = HandleClosed;
             PlatformImpl.Input = HandleInput;
             PlatformImpl.Resized = HandleResized;
+            PlatformImpl.ScalingChanged = HandleScalingChanged;
 
             _keyboardNavigationHandler?.SetOwner(this);
             _accessKeyHandler?.SetOwner(this);
@@ -280,6 +282,19 @@ namespace Perspex.Controls
             PlatformImpl.Invalidate(new Rect(clientSize));
         }
 
+        /// <summary>
+        /// Handles a window scaling change notification from 
+        /// <see cref="ITopLevelImpl.ScalingChanged"/>.
+        /// </summary>
+        /// <param name="scaling">The window scaling.</param>
+        protected virtual void HandleScalingChanged(double scaling)
+        {
+            foreach (ILayoutable control in this.GetSelfAndVisualDescendents())
+            {
+                control.InvalidateMeasure();
+            }
+        }
+
         /// <inheritdoc/>
         protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
         {

+ 1 - 0
src/Windows/Perspex.Win32/Interop/UnmanagedMethods.cs

@@ -489,6 +489,7 @@ namespace Perspex.Win32.Interop
             WM_WTSSESSION_CHANGE = 0x02B1,
             WM_TABLET_FIRST = 0x02c0,
             WM_TABLET_LAST = 0x02df,
+            WM_DPICHANGED = 0x02E0,
             WM_CUT = 0x0300,
             WM_COPY = 0x0301,
             WM_PASTE = 0x0302,

+ 8 - 0
src/Windows/Perspex.Win32/WindowImpl.cs

@@ -52,6 +52,8 @@ namespace Perspex.Win32
 
         public Action<Size> Resized { get; set; }
 
+        public Action<double> ScalingChanged { get; set; }
+
         public Thickness BorderThickness
         {
             get
@@ -359,6 +361,12 @@ namespace Perspex.Win32
 
                     return IntPtr.Zero;
 
+                case UnmanagedMethods.WindowsMessage.WM_DPICHANGED:
+                    var dpi = (int)wParam & 0xffff;
+                    _scaling = dpi / 96.0;
+                    ScalingChanged?.Invoke(_scaling);
+                    break;
+
                 case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
                 case UnmanagedMethods.WindowsMessage.WM_SYSKEYDOWN:
                     e = new RawKeyEventArgs(