From 901efda7fc22875216da5644312cbc6105a560f8 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Sat, 23 Nov 2024 10:30:26 +0000 Subject: [PATCH 1/2] Use URLWithString for pickers (#17594) --- native/Avalonia.Native/src/OSX/StorageProvider.mm | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/StorageProvider.mm b/native/Avalonia.Native/src/OSX/StorageProvider.mm index 0fd77c6789e..abf7f85c5fb 100644 --- a/native/Avalonia.Native/src/OSX/StorageProvider.mm +++ b/native/Avalonia.Native/src/OSX/StorageProvider.mm @@ -173,8 +173,7 @@ virtual void SelectFolderDialog (IAvnWindow* parentWindowHandle, if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; - panel.directoryURL = [NSURL fileURLWithPath:directoryString - isDirectory:true]; + panel.directoryURL = [NSURL URLWithString:directoryString]; } auto handler = ^(NSModalResponse result) { @@ -239,8 +238,7 @@ virtual void OpenFileDialog (IAvnWindow* parentWindowHandle, if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; - panel.directoryURL = [NSURL fileURLWithPath:directoryString - isDirectory:true]; + panel.directoryURL = [NSURL URLWithString:directoryString]; } if(initialFile != nullptr) @@ -309,8 +307,7 @@ virtual void SaveFileDialog (IAvnWindow* parentWindowHandle, if(initialDirectory != nullptr) { auto directoryString = [NSString stringWithUTF8String:initialDirectory]; - panel.directoryURL = [NSURL fileURLWithPath:directoryString - isDirectory:true]; + panel.directoryURL = [NSURL URLWithString:directoryString]; } if(initialFile != nullptr) From 35f6d73e0d79c3dd8b5c97b06e845475a135ae40 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 26 Nov 2024 01:06:31 +0000 Subject: [PATCH 2/2] Raise the `EffectiveViewPortChanged` when a control is added to the tree that has already has a valid layout (#17570) * add unit tests to show that the EffectiveViewPortChanged event is not being raised when it should. note: this tests are verified against UWP behavior. * fix raising of EffectiveViewPortChanged event. --------- Co-authored-by: Julien Lebosquain Co-authored-by: Max Katz --- src/Avalonia.Base/Layout/LayoutManager.cs | 9 +-- ...ayoutableTests_EffectiveViewportChanged.cs | 61 ++++++++++++++++++- 2 files changed, 62 insertions(+), 8 deletions(-) diff --git a/src/Avalonia.Base/Layout/LayoutManager.cs b/src/Avalonia.Base/Layout/LayoutManager.cs index cffda3e84c7..79d43239e6c 100644 --- a/src/Avalonia.Base/Layout/LayoutManager.cs +++ b/src/Avalonia.Base/Layout/LayoutManager.cs @@ -213,9 +213,7 @@ public void Dispose() void ILayoutManager.RegisterEffectiveViewportListener(Layoutable control) { _effectiveViewportChangedListeners ??= new List(); - _effectiveViewportChangedListeners.Add(new EffectiveViewportChangedListener( - control, - CalculateEffectiveViewport(control))); + _effectiveViewportChangedListeners.Add(new EffectiveViewportChangedListener(control)); } void ILayoutManager.UnregisterEffectiveViewportListener(Layoutable control) @@ -438,14 +436,13 @@ private void CalculateEffectiveViewport(Visual target, Visual control, ref Rect private class EffectiveViewportChangedListener { - public EffectiveViewportChangedListener(Layoutable listener, Rect viewport) + public EffectiveViewportChangedListener(Layoutable listener) { Listener = listener; - Viewport = viewport; } public Layoutable Listener { get; } - public Rect Viewport { get; set; } + public Rect? Viewport { get; set; } } private enum ArrangeResult diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs index 94054f5245c..09e4986da02 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_EffectiveViewportChanged.cs @@ -14,7 +14,7 @@ namespace Avalonia.Base.UnitTests.Layout public class LayoutableTests_EffectiveViewportChanged { [Fact] - public async Task EffectiveViewportChanged_Not_Raised_When_Control_Added_To_Tree() + public async Task EffectiveViewportChanged_Not_Raised_When_Control_Added_To_Tree_And_Layout_Pass_Has_Not_Run() { #pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously await RunOnUIThread.Execute(async () => @@ -34,6 +34,60 @@ await RunOnUIThread.Execute(async () => Assert.Equal(0, raised); }); } + + [Fact] + public async Task EffectiveViewportChanged_Raised_When_Control_Added_To_Tree_And_Layout_Pass_Has_Run() + { +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + await RunOnUIThread.Execute(async () => +#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously + { + var root = CreateRoot(); + var target = new Canvas(); + var raised = 0; + + target.EffectiveViewportChanged += (s, e) => + { + ++raised; + }; + + root.Child = target; + + Assert.Equal(0, raised); + + await ExecuteInitialLayoutPass(root); + + Assert.Equal(1, raised); + }); + } + + [Fact] + public async Task EffectiveViewportChanged_Raised_When_Root_LayedOut_And_Then_Control_Added_To_Tree_And_Layout_Pass_Runs() + { +#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously + await RunOnUIThread.Execute(async () => +#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously + { + var root = CreateRoot(); + var target = new Canvas(); + var raised = 0; + + target.EffectiveViewportChanged += (s, e) => + { + ++raised; + }; + + await ExecuteInitialLayoutPass(root); + + root.Child = target; + + Assert.Equal(0, raised); + + await ExecuteInitialLayoutPass(root); + + Assert.Equal(1, raised); + }); + } [Fact] public async Task EffectiveViewportChanged_Raised_Before_LayoutUpdated() @@ -268,8 +322,11 @@ await RunOnUIThread.Execute(async () => root.Child = parent; - await ExecuteInitialLayoutPass(root); target.EffectiveViewportChanged += (s, e) => ++raised; + await ExecuteInitialLayoutPass(root); + + raised = 0; // The initial layout pass is expected to raise. + target.RenderTransform = new TranslateTransform { X = 8 }; target.InvalidateMeasure(); await ExecuteLayoutPass(root);