diff --git a/src/Controls/src/Core/Window/Window.cs b/src/Controls/src/Core/Window/Window.cs index 3d37a59e2e8f..2d99cd52ee3c 100644 --- a/src/Controls/src/Core/Window/Window.cs +++ b/src/Controls/src/Core/Window/Window.cs @@ -204,15 +204,18 @@ double GetSizeCoordinate(BindableProperty property) void IWindow.FrameChanged(Rect frame) { if (new Rect(X, Y, Width, Height) == frame) + { return; + } _batchFrameUpdate++; - bool shouldTriggerSizeChanged = (Width != frame.Width) || (Height != frame.Height); - X = frame.X; - Y = frame.Y; - Width = frame.Width; - Height = frame.Height; + var shouldTriggerSizeChanged = (Width != frame.Width) || (Height != frame.Height); + + SetValue(XProperty, frame.X, SetterSpecificity.FromHandler); + SetValue(YProperty, frame.Y, SetterSpecificity.FromHandler); + SetValue(WidthProperty, frame.Width, SetterSpecificity.FromHandler); + SetValue(HeightProperty, frame.Height, SetterSpecificity.FromHandler); _batchFrameUpdate--; if (_batchFrameUpdate < 0) @@ -222,25 +225,6 @@ void IWindow.FrameChanged(Rect frame) { SizeChanged?.Invoke(this, EventArgs.Empty); } - - - // If for some reason during the PropertyChanged event on X,Y,Width,Height - // the user has changed these values. Then we need to propagate them back to the handler - UpdateHandler(X != frame.X, nameof(X)); - UpdateHandler(Y != frame.Y, nameof(Y)); - UpdateHandler(Width != frame.Width, nameof(Width)); - UpdateHandler(Height != frame.Height, nameof(Height)); - - - void UpdateHandler(bool condition, string property) - { - if (Handler is null || !condition) - { - return; - } - - Handler.UpdateValue(property); - } } private protected override void UpdateHandlerValue(string property) @@ -253,7 +237,6 @@ private protected override void UpdateHandlerValue(string property) base.UpdateHandlerValue(property); } - public event EventHandler? ModalPopped; public event EventHandler? ModalPopping; public event EventHandler? ModalPushed; diff --git a/src/Core/tests/DeviceTests/Core.DeviceTests.csproj b/src/Core/tests/DeviceTests/Core.DeviceTests.csproj index 613806d00989..68b810f94a27 100644 --- a/src/Core/tests/DeviceTests/Core.DeviceTests.csproj +++ b/src/Core/tests/DeviceTests/Core.DeviceTests.csproj @@ -13,6 +13,10 @@ true + + $(DefineConstants);CI + + Core Tests com.microsoft.maui.core.devicetests diff --git a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.cs b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.cs index 638ec4adf2b4..9ae5a276ed25 100644 --- a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.cs +++ b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.cs @@ -35,11 +35,10 @@ public async Task WindowHasReasonableDisplayDensity() #if MACCATALYST || WINDOWS [Fact( -#if MACCATALYST - Skip = "Setting Location on MacCatalyst is currently not supported" +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif - )] - + )] public async Task InitialPositionsAreTakenIntoAccount() { var window = new Window(new NavigationPage(new ContentPage())) @@ -50,20 +49,132 @@ public async Task InitialPositionsAreTakenIntoAccount() Y = 500 }; + await RunWindowTest(window, handler => + { +#if MACCATALYST + // these are updated by the OS + Assert.True(window.Width > 0, $"Expected Width to be >= 0, but was {window.Width}"); + Assert.True(window.Height > 0, $"Expected Height to be >= 0, but was {window.Height}"); + // these are not available from the OS... + Assert.True(window.X == 0, $"Expected X to be == 0, but was {window.X}"); + Assert.True(window.Y == 0, $"Expected Y to be == 0, but was {window.Y}"); +#elif WINDOWS + Assert.Equal(200, window.Width); + Assert.Equal(500, window.Height); + Assert.Equal(0, window.X); + Assert.Equal(500, window.Y); +#endif + }); + } + + [Fact( +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" +#endif + )] + public async Task UpdatedPositionsAreTakenIntoAccount() + { + var window = new Window(new NavigationPage(new ContentPage())); + await RunWindowTest(window, async handler => { - // Just let things settle for good measure + var currentFrame = new Rect(window.X, window.Y, window.Width, window.Height); + + window.Width = 200; + window.Height = 500; + window.X = 0; + window.Y = 0; + + // Just let things settle as some platforms require a few UI cycles to update bounds await Task.Delay(100); + +#if MACCATALYST + // Mac Catalyst does not support this operation, so it should never change + Assert.Equal(currentFrame, new Rect(window.X, window.Y, window.Width, window.Height)); +#elif WINDOWS Assert.Equal(200, window.Width); Assert.Equal(500, window.Height); Assert.Equal(0, window.X); - Assert.Equal(500, window.Y); + Assert.Equal(0, window.Y); +#endif }); } [Fact( +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" +#endif + )] + public async Task ChangingTitleWhileChangingTitle() + { + var window = new Window(new NavigationPage(new ContentPage())) + { + Title = "Initial" + }; + + window.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Window.Title) && window.Title == "Changed") + { + window.Title = "Final"; + } + }; + + await RunWindowTest(window, handler => + { + window.Title = "Changed"; + + Assert.Equal("Final", window.Title); + }); + } + + [Fact( +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" +#endif + )] + public async Task ChangingSizeWhileChangingSize() + { + var window = new Window(new NavigationPage(new ContentPage())) + { + Width = 300, + Height = 500, + X = 0, + Y = 500 + }; + + window.PropertyChanged += (s, e) => + { + if (e.PropertyName == nameof(Window.Width) && window.Width == 400) + { + window.Width = 250; + } + }; + + await RunWindowTest(window, async handler => + { + var currentFrame = new Rect(window.X, window.Y, window.Width, window.Height); + + window.Width = 400; + + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); + #if MACCATALYST - Skip = "Causes Catalyst test run to hang" + // Mac Catalyst does not support this operation, so it should never change + Assert.Equal(currentFrame, new Rect(window.X, window.Y, window.Width, window.Height)); +#elif WINDOWS + Assert.Equal(250, window.Width); + Assert.Equal(500, window.Height); + Assert.Equal(0, window.X); + Assert.Equal(500, window.Y); +#endif + }); + } + + [Fact( +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif )] public async Task WindowSupportsEmptyPage() @@ -77,8 +188,8 @@ await RunWindowTest(window, handler => } [Theory( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif )] [InlineData(150, 300)] @@ -101,15 +212,16 @@ await RunWindowTest(window, async handler => window.MinimumWidth = min; - await Task.Delay(100); // mac catalyst seems to have delays + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); Assert.Equal(expected, window.Width); }); } [Theory( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif )] [InlineData(150, 300)] @@ -132,15 +244,16 @@ await RunWindowTest(window, async handler => window.MinimumHeight = min; - await Task.Delay(100); // mac catalyst seems to have delays + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); Assert.Equal(expected, window.Height); }); } [Theory( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif )] [InlineData(150, 150)] @@ -163,15 +276,16 @@ await RunWindowTest(window, async handler => window.MaximumWidth = max; - await Task.Delay(100); // mac catalyst seems to have delays + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); Assert.Equal(expected, window.Width); }); } [Theory( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI && MACCATALYST + Skip = "Causes Catalyst test run to hang" #endif )] [InlineData(150, 150)] @@ -194,7 +308,8 @@ await RunWindowTest(window, async handler => window.MaximumHeight = max; - await Task.Delay(100); // mac catalyst seems to have delays + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); Assert.Equal(expected, window.Height); }); @@ -232,6 +347,10 @@ Task RunWindowTest(Window window, Func action) // If we don't wait for the content to load then the CloseWindow call crashes await ((IPlatformViewHandler)window.Page.Handler).PlatformView.OnLoadedAsync(); #endif + + // Just let things settle as some platforms require a few UI cycles to update bounds + await Task.Delay(100); + try { await action(windowHandler); diff --git a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.iOS.cs b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.iOS.cs index 2a5dd8c664bf..860ac214d4a0 100644 --- a/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Handlers/Window/WindowHandlerTests.iOS.cs @@ -12,8 +12,8 @@ public partial class WindowHandlerTests : CoreHandlerTestBase #if MACCATALYST [Fact( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI + Skip = "Causes Catalyst test run to hang" #endif )] public async Task TitleSetsOnWindow() @@ -35,10 +35,9 @@ await RunWindowTest(window, handler => }); } - [Fact( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI + Skip = "Causes Catalyst test run to hang" #endif )] public async Task ContentIsSetInitially() @@ -60,15 +59,15 @@ await RunWindowTest(window, handler => Assert.NotNull(page.View); var content = Assert.IsType(root.View.Subviews[0]); - var btn = Assert.IsType(content.Subviews[0]); + var btn = Assert.IsType(content.Subviews[0].Subviews[0]); Assert.Equal("Yay!", btn.Title(UIControlState.Normal)); }); } [Fact( -#if MACCATALYST - Skip = "Causes Catalyst test run to hang" +#if CI + Skip = "Causes Catalyst test run to hang" #endif )] public async Task WindowSupportsEmptyPage_Platform()