From c6417b2499a2abe54bb4df44064c4613dc09a2d2 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 2 Mar 2023 15:31:13 +0000 Subject: [PATCH 01/11] constrain window to maximum size. --- native/Avalonia.Native/src/OSX/WindowBaseImpl.mm | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index 59102e15a6..dba5daf90b 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -273,6 +273,7 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso auto resizeBlock = ResizeScope(View, reason); @autoreleasepool { + auto screenSize = [Window screen].visibleFrame.size; auto maxSize = lastMaxSize; auto minSize = lastMinSize; @@ -292,6 +293,15 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso y = maxSize.height; } + if(x > screenSize.width){ + x = screenSize.width; + } + + if(y > screenSize.height) + { + y = screenSize.height; + } + @try { if(x != lastSize.width || y != lastSize.height) { lastSize = NSSize{x, y}; From d56c7aa6e71308c4d0ae35647d8a414ca1c0d1de Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 2 Mar 2023 15:34:36 +0000 Subject: [PATCH 02/11] make sure _lastWindowState and _actualWindowState are both reset when window is shown. --- native/Avalonia.Native/src/OSX/WindowImpl.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index cf1ee6943d..8e890d3216 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -54,6 +54,7 @@ HRESULT WindowImpl::Show(bool activate, bool isDialog) { WindowBaseImpl::Show(activate, isDialog); GetWindowState(&_actualWindowState); + _lastWindowState = _actualWindowState; return SetWindowState(_lastWindowState); } } From c9aed1386df291c03865e57f1df6ef778ad1d5b6 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 2 Mar 2023 15:57:55 +0000 Subject: [PATCH 03/11] update the test app to show the size that measure was called with on window content. --- .../IntegrationTestApp/ShowWindowTest.axaml | 77 +++++++++++-------- .../ShowWindowTest.axaml.cs | 19 +++++ 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/samples/IntegrationTestApp/ShowWindowTest.axaml b/samples/IntegrationTestApp/ShowWindowTest.axaml index 00987429d0..9e49298829 100644 --- a/samples/IntegrationTestApp/ShowWindowTest.axaml +++ b/samples/IntegrationTestApp/ShowWindowTest.axaml @@ -1,41 +1,50 @@ - - - - - - - - - - - - - - - - - - - - - - Normal - Minimized - Maximized - FullScreen - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + Normal + Minimized + Maximized + FullScreen + + + + + + + + + + + + + + diff --git a/samples/IntegrationTestApp/ShowWindowTest.axaml.cs b/samples/IntegrationTestApp/ShowWindowTest.axaml.cs index 43875dd990..ffcd6fc32c 100644 --- a/samples/IntegrationTestApp/ShowWindowTest.axaml.cs +++ b/samples/IntegrationTestApp/ShowWindowTest.axaml.cs @@ -7,6 +7,25 @@ using Avalonia.Threading; namespace IntegrationTestApp { + public class MeasureBorder : Border + { + protected override Size MeasureOverride(Size availableSize) + { + MeasuredWith = availableSize; + + return base.MeasureOverride(availableSize); + } + + public static readonly StyledProperty MeasuredWithProperty = AvaloniaProperty.Register( + nameof(MeasuredWith)); + + public Size MeasuredWith + { + get => GetValue(MeasuredWithProperty); + set => SetValue(MeasuredWithProperty, value); + } + } + public class ShowWindowTest : Window { private readonly DispatcherTimer? _timer; From f2bceb40c92fd8626773499718c9742455eb9a72 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Thu, 2 Mar 2023 16:06:31 +0000 Subject: [PATCH 04/11] add an integration test. --- .../WindowTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs index a2bfb618d6..fb3283fbe7 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Avalonia.Controls; +using Avalonia.Utilities; using Avalonia.Media.Imaging; using OpenQA.Selenium; using OpenQA.Selenium.Appium; @@ -143,6 +144,24 @@ namespace Avalonia.IntegrationTests.Appium } } + + [Fact] + public void Showing_Window_With_Size_Larger_Than_Screen_Measures_Content_With_Working_Area() + { + using (OpenWindow(new Size(4000, 2200), ShowWindowMode.NonOwned, WindowStartupLocation.Manual)) + { + var measuredWithTextBlock = _session.FindElementById("MeasuredWithText"); + var screenRectTextBox = _session.FindElementById("ScreenRect"); + + var measuredWithString = measuredWithTextBlock.Text; + var workingAreaString = screenRectTextBox.Text; + + var workingArea = Rect.Parse(workingAreaString); + var measuredWith = Size.Parse(measuredWithString); + + Assert.Equal(workingArea.Size, measuredWith); + } + } [Theory] [InlineData(ShowWindowMode.NonOwned)] From 101ea9cb5fd4e3a68165e634e629dcd1bbba7313 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 12:21:54 +0000 Subject: [PATCH 05/11] only constrain to working area before show. After that cocoa will do it for us. --- .../Avalonia.Native/src/OSX/WindowBaseImpl.mm | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index dba5daf90b..bf98a6d1b6 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -273,7 +273,6 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso auto resizeBlock = ResizeScope(View, reason); @autoreleasepool { - auto screenSize = [Window screen].visibleFrame.size; auto maxSize = lastMaxSize; auto minSize = lastMinSize; @@ -293,20 +292,25 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso y = maxSize.height; } - if(x > screenSize.width){ - x = screenSize.width; - } - - if(y > screenSize.height) - { - y = screenSize.height; - } - @try { if(x != lastSize.width || y != lastSize.height) { lastSize = NSSize{x, y}; if (!_shown) { + // Before the window is shown, Cocoa wont give Resized events + // constraining the window to the maximum size available on the monitor. + // we have to emulated this behavior that Avalonia relies on. + auto screenSize = [Window screen].visibleFrame.size; + + if(x > screenSize.width){ + x = screenSize.width; + } + + if(y > screenSize.height) + { + y = screenSize.height; + } + BaseEvents->Resized(AvnSize{x, y}, reason); } else if (Window != nullptr) { [Window setContentSize:lastSize]; From c8b868a558228e44196c7ad46bfd539a1d114d42 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 14:55:21 +0000 Subject: [PATCH 06/11] alway setContentSize even before show, but preconstrain the size. --- native/Avalonia.Native/src/OSX/AvnView.mm | 7 ++---- .../Avalonia.Native/src/OSX/WindowBaseImpl.mm | 24 ++++++++----------- 2 files changed, 12 insertions(+), 19 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm index 4ae6ad5a00..bcfdc23053 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.mm +++ b/native/Avalonia.Native/src/OSX/AvnView.mm @@ -127,11 +127,8 @@ [self updateRenderTarget]; auto reason = [self inLiveResize] ? ResizeUser : _resizeReason; - - if(_parent->IsShown()) - { - _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason); - } + + _parent->BaseEvents->Resized(AvnSize{newSize.width, newSize.height}, reason); } } diff --git a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm index bf98a6d1b6..b579920c6b 100644 --- a/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowBaseImpl.mm @@ -4,6 +4,7 @@ // #import +#import #include "common.h" #include "AvnView.h" #include "menu.h" @@ -293,29 +294,24 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso } @try { - if(x != lastSize.width || y != lastSize.height) { - lastSize = NSSize{x, y}; - + if(x != lastSize.width || y != lastSize.height) + { if (!_shown) { - // Before the window is shown, Cocoa wont give Resized events - // constraining the window to the maximum size available on the monitor. - // we have to emulated this behavior that Avalonia relies on. auto screenSize = [Window screen].visibleFrame.size; - if(x > screenSize.width){ + if (x > screenSize.width) { x = screenSize.width; } - if(y > screenSize.height) - { + if (y > screenSize.height) { y = screenSize.height; } - - BaseEvents->Resized(AvnSize{x, y}, reason); - } else if (Window != nullptr) { - [Window setContentSize:lastSize]; - [Window invalidateShadow]; } + + lastSize = NSSize{x, y}; + + [Window setContentSize:lastSize]; + [Window invalidateShadow]; } } @finally { From e51aaf4b2dbdda73aa27cc1d7bd0f6a0cc2a9d98 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 16:51:01 +0000 Subject: [PATCH 07/11] only reset _lastWindowState if we are zoomed. --- native/Avalonia.Native/src/OSX/WindowImpl.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/native/Avalonia.Native/src/OSX/WindowImpl.mm b/native/Avalonia.Native/src/OSX/WindowImpl.mm index 8e890d3216..840f2c9e88 100644 --- a/native/Avalonia.Native/src/OSX/WindowImpl.mm +++ b/native/Avalonia.Native/src/OSX/WindowImpl.mm @@ -54,7 +54,11 @@ HRESULT WindowImpl::Show(bool activate, bool isDialog) { WindowBaseImpl::Show(activate, isDialog); GetWindowState(&_actualWindowState); - _lastWindowState = _actualWindowState; + + if(IsZoomed()) { + _lastWindowState = _actualWindowState; + } + return SetWindowState(_lastWindowState); } } From 4203bae16d96660cdf06dd241f40990c9c7ab52d Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 17:25:59 +0000 Subject: [PATCH 08/11] fix test. --- tests/Avalonia.IntegrationTests.Appium/WindowTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs index 6b70edbdf4..aa65f38084 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs @@ -151,7 +151,7 @@ namespace Avalonia.IntegrationTests.Appium using (OpenWindow(new Size(4000, 2200), ShowWindowMode.NonOwned, WindowStartupLocation.Manual)) { var measuredWithTextBlock = _session.FindElementById("MeasuredWithText"); - var screenRectTextBox = _session.FindElementById("ScreenRect"); + var screenRectTextBox = _session.FindElementById("CurrentScreenRect"); var measuredWithString = measuredWithTextBlock.Text; var workingAreaString = screenRectTextBox.Text; From 3ec8888b5dcb5b9c7f826e135b1764e32568e47f Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 17:35:39 +0000 Subject: [PATCH 09/11] actually fix the test. --- tests/Avalonia.IntegrationTests.Appium/WindowTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs index aa65f38084..ce97678a24 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs @@ -151,7 +151,7 @@ namespace Avalonia.IntegrationTests.Appium using (OpenWindow(new Size(4000, 2200), ShowWindowMode.NonOwned, WindowStartupLocation.Manual)) { var measuredWithTextBlock = _session.FindElementById("MeasuredWithText"); - var screenRectTextBox = _session.FindElementById("CurrentScreenRect"); + var screenRectTextBox = _session.FindElementById("CurrentClientSize"); var measuredWithString = measuredWithTextBlock.Text; var workingAreaString = screenRectTextBox.Text; From c634f11def09f8346bdbc1a5d11629ed314cf322 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 17:59:59 +0000 Subject: [PATCH 10/11] really really fix the test. --- tests/Avalonia.IntegrationTests.Appium/WindowTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs index ce97678a24..948fb3225f 100644 --- a/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs +++ b/tests/Avalonia.IntegrationTests.Appium/WindowTests.cs @@ -156,10 +156,10 @@ namespace Avalonia.IntegrationTests.Appium var measuredWithString = measuredWithTextBlock.Text; var workingAreaString = screenRectTextBox.Text; - var workingArea = Rect.Parse(workingAreaString); + var workingArea = Size.Parse(workingAreaString); var measuredWith = Size.Parse(measuredWithString); - Assert.Equal(workingArea.Size, measuredWith); + Assert.Equal(workingArea, measuredWith); } } From 4d343293c82b8ecd84715870c3f065252f15caeb Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Fri, 3 Mar 2023 22:15:50 +0000 Subject: [PATCH 11/11] fix test on windows. --- samples/IntegrationTestApp/ShowWindowTest.axaml | 10 ++++------ tests/Avalonia.IntegrationTests.Appium/WindowTests.cs | 4 ++-- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/samples/IntegrationTestApp/ShowWindowTest.axaml b/samples/IntegrationTestApp/ShowWindowTest.axaml index ed23797ad7..bd6910dd4d 100644 --- a/samples/IntegrationTestApp/ShowWindowTest.axaml +++ b/samples/IntegrationTestApp/ShowWindowTest.axaml @@ -37,13 +37,11 @@ - - - - - - +