Browse Source

Measure Window to MaxAutoSizeHint.

- Renamed `MaxClientSize` to `MaxAutoSizeHint`
- On Windows get its value from `WM_GETMINMAXINFO` message
- Remove `ILayoutRoot.MaxClientSize` as it's not used any more
Steven Kirk 5 years ago
parent
commit
95735d239b

+ 2 - 3
src/Avalonia.Controls/Platform/IWindowBaseImpl.cs

@@ -1,5 +1,4 @@
 using System;
-using Avalonia.Controls;
 
 namespace Avalonia.Platform
 {
@@ -46,9 +45,9 @@ namespace Avalonia.Platform
         IPlatformHandle Handle { get; }
        
         /// <summary>
-        /// Gets the maximum size of a window on the system.
+        /// Gets a maximum client size hint for an auto-sizing window, in device-independent pixels.
         /// </summary>
-        Size MaxClientSize { get; }
+        Size MaxAutoSizeHint { get; }
 
         /// <summary>
         /// Sets whether this window appears on top of all other windows

+ 1 - 1
src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs

@@ -113,7 +113,7 @@ namespace Avalonia.Controls.Presenters
         {
             var scrollable = (ILogicalScrollable)Owner;
             var visualRoot = Owner.GetVisualRoot();
-            var maxAvailableSize = (visualRoot as WindowBase)?.PlatformImpl?.MaxClientSize
+            var maxAvailableSize = (visualRoot as WindowBase)?.PlatformImpl?.MaxAutoSizeHint
                  ?? (visualRoot as TopLevel)?.ClientSize;
 
             // If infinity is passed as the available size and we're virtualized then we need to

+ 0 - 3
src/Avalonia.Controls/TopLevel.cs

@@ -212,9 +212,6 @@ namespace Avalonia.Controls
             set { SetValue(AccessText.ShowAccessKeyProperty, value); }
         }
 
-        /// <inheritdoc/>
-        Size ILayoutRoot.MaxClientSize => Size.Infinity;
-
         /// <inheritdoc/>
         double ILayoutRoot.LayoutScaling => PlatformImpl?.Scaling ?? 1;
 

+ 4 - 6
src/Avalonia.Controls/Window.cs

@@ -184,7 +184,7 @@ namespace Avalonia.Controls
         {
             impl.Closing = HandleClosing;
             impl.WindowStateChanged = HandleWindowStateChanged;
-            _maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size);
+            _maxPlatformClientSize = PlatformImpl?.MaxAutoSizeHint ?? default(Size);
             this.GetObservable(ClientSizeProperty).Skip(1).Subscribe(x => PlatformImpl?.Resize(x));
 
             PlatformImpl?.ShowTaskbarIcon(ShowInTaskbar);
@@ -314,9 +314,6 @@ namespace Avalonia.Controls
         /// </summary>
         public void BeginResizeDrag(WindowEdge edge, PointerPressedEventArgs e) => PlatformImpl?.BeginResizeDrag(edge, e);
 
-        /// <inheritdoc/>
-        Size ILayoutRoot.MaxClientSize => _maxPlatformClientSize;
-
         /// <inheritdoc/>
         Type IStyleable.StyleKey => typeof(Window);
 
@@ -572,15 +569,16 @@ namespace Avalonia.Controls
             var sizeToContent = SizeToContent;
             var clientSize = ClientSize;
             var constraint = clientSize;
+            var maxAutoSize = PlatformImpl?.MaxAutoSizeHint ?? Size.Infinity;
 
             if (sizeToContent.HasFlagCustom(SizeToContent.Width))
             {
-                constraint = constraint.WithWidth(double.PositiveInfinity);
+                constraint = constraint.WithWidth(maxAutoSize.Width);
             }
 
             if (sizeToContent.HasFlagCustom(SizeToContent.Height))
             {
-                constraint = constraint.WithHeight(double.PositiveInfinity);
+                constraint = constraint.WithHeight(maxAutoSize.Height);
             }
 
             var result = base.MeasureOverride(constraint);

+ 1 - 1
src/Avalonia.DesignerSupport/Remote/PreviewerWindowImpl.cs

@@ -44,7 +44,7 @@ namespace Avalonia.DesignerSupport.Remote
         public IPlatformHandle Handle { get; }
         public WindowState WindowState { get; set; }
         public Action<WindowState> WindowStateChanged { get; set; }
-        public Size MaxClientSize { get; } = new Size(4096, 4096);
+        public Size MaxAutoSizeHint { get; } = new Size(4096, 4096);
         public event Action LostFocus
         {
             add {}

+ 1 - 1
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@@ -19,7 +19,7 @@ namespace Avalonia.DesignerSupport.Remote
         public Action Deactivated { get; set; }
         public Action Activated { get; set; }
         public IPlatformHandle Handle { get; }
-        public Size MaxClientSize { get; }
+        public Size MaxAutoSizeHint { get; }
         public Size ClientSize { get; }
         public double Scaling { get; } = 1.0;
         public IEnumerable<object> Surfaces { get; }

+ 0 - 5
src/Avalonia.Layout/ILayoutRoot.cs

@@ -10,11 +10,6 @@ namespace Avalonia.Layout
         /// </summary>
         Size ClientSize { get; }
 
-        /// <summary>
-        /// The maximum client size available.
-        /// </summary>
-        Size MaxClientSize { get; }
-
         /// <summary>
         /// The scaling factor to use in layout.
         /// </summary>

+ 1 - 1
src/Avalonia.Native/WindowImplBase.cs

@@ -309,7 +309,7 @@ namespace Avalonia.Native
             _native.BeginMoveDrag();
         }
 
-        public Size MaxClientSize => Screen.AllScreens.Select(s => s.Bounds.Size.ToSize(s.PixelDensity))
+        public Size MaxAutoSizeHint => Screen.AllScreens.Select(s => s.Bounds.Size.ToSize(s.PixelDensity))
             .OrderByDescending(x => x.Width + x.Height).FirstOrDefault();
 
         public void SetTopmost(bool value)

+ 1 - 1
src/Avalonia.X11/X11Window.cs

@@ -915,7 +915,7 @@ namespace Avalonia.X11
 
         public IScreenImpl Screen => _platform.Screens;
 
-        public Size MaxClientSize => _platform.X11Screens.Screens.Select(s => s.Bounds.Size.ToSize(s.PixelDensity))
+        public Size MaxAutoSizeHint => _platform.X11Screens.Screens.Select(s => s.Bounds.Size.ToSize(s.PixelDensity))
             .OrderByDescending(x => x.Width + x.Height).FirstOrDefault();
 
 

+ 2 - 0
src/Windows/Avalonia.Win32/WindowImpl.WndProc.cs

@@ -399,6 +399,8 @@ namespace Avalonia.Win32
                 case WindowsMessage.WM_GETMINMAXINFO:
                 {
                     MINMAXINFO mmi = Marshal.PtrToStructure<MINMAXINFO>(lParam);
+                    
+                    _maxTrackSize = mmi.ptMaxTrackSize;
 
                     if (_minSize.Width > 0)
                     {

+ 2 - 10
src/Windows/Avalonia.Win32/WindowImpl.cs

@@ -62,6 +62,7 @@ namespace Avalonia.Win32
         private OleDropTarget _dropTarget;
         private Size _minSize;
         private Size _maxSize;
+        private POINT _maxTrackSize;
         private WindowImpl _parent;
 
         public WindowImpl()
@@ -164,16 +165,7 @@ namespace Avalonia.Win32
 
         public IPlatformHandle Handle { get; private set; }
 
-        public Size MaxClientSize
-        {
-            get
-            {
-                return (new Size(
-                            GetSystemMetrics(SystemMetric.SM_CXMAXTRACK),
-                            GetSystemMetrics(SystemMetric.SM_CYMAXTRACK))
-                        - BorderThickness) / Scaling;
-            }
-        }
+        public Size MaxAutoSizeHint => new Size(_maxTrackSize.X / Scaling, _maxTrackSize.Y / Scaling);
 
         public IMouseDevice MouseDevice => _mouseDevice;
 

+ 8 - 5
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@@ -297,12 +297,12 @@ namespace Avalonia.Controls.UnitTests
         {
             var parentWindowImpl = MockWindowingPlatform.CreateWindowMock();
             parentWindowImpl.Setup(x => x.ClientSize).Returns(new Size(800, 480));
-            parentWindowImpl.Setup(x => x.MaxClientSize).Returns(new Size(1920, 1080));
+            parentWindowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
             parentWindowImpl.Setup(x => x.Scaling).Returns(1);
 
             var windowImpl = MockWindowingPlatform.CreateWindowMock();
             windowImpl.Setup(x => x.ClientSize).Returns(new Size(320, 200));
-            windowImpl.Setup(x => x.MaxClientSize).Returns(new Size(1920, 1080));
+            windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1920, 1080));
             windowImpl.Setup(x => x.Scaling).Returns(1);
 
             var parentWindowServices = TestServices.StyledWindow.With(
@@ -380,12 +380,15 @@ namespace Avalonia.Controls.UnitTests
         }
 
         [Fact]
-        public void Child_Should_Be_Measured_With_Infinity_If_SizeToContent_Is_WidthAndHeight()
+        public void Child_Should_Be_Measured_With_MaxAutoSizeHint_If_SizeToContent_Is_WidthAndHeight()
         {
             using (UnitTestApplication.Start(TestServices.StyledWindow))
             {
+                var windowImpl = MockWindowingPlatform.CreateWindowMock();
+                windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(new Size(1200, 1000));
+
                 var child = new ChildControl();
-                var target = new Window
+                var target = new Window(windowImpl.Object)
                 {
                     Width = 100,
                     Height = 50,
@@ -396,7 +399,7 @@ namespace Avalonia.Controls.UnitTests
                 target.Show();
 
                 Assert.Equal(1, child.MeasureSizes.Count);
-                Assert.Equal(Size.Infinity, child.MeasureSizes[0]);
+                Assert.Equal(new Size(1200, 1000), child.MeasureSizes[0]);
             }
         }
 

+ 1 - 0
tests/Avalonia.UnitTests/MockWindowingPlatform.cs

@@ -28,6 +28,7 @@ namespace Avalonia.UnitTests
 
             windowImpl.SetupAllProperties();
             windowImpl.Setup(x => x.ClientSize).Returns(() => clientSize);
+            windowImpl.Setup(x => x.MaxAutoSizeHint).Returns(s_screenSize);
             windowImpl.Setup(x => x.Scaling).Returns(1);
             windowImpl.Setup(x => x.Screen).Returns(CreateScreenMock().Object);
             windowImpl.Setup(x => x.Position).Returns(() => position);