Browse Source
Merge pull request #8305 from AvaloniaUI/fixes/reduce-excessive-layout-passes
Fixes/reduce excessive layout passes
pull/8324/head
Dan Walmsley
4 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with
39 additions and
10 deletions
-
native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
-
src/Avalonia.Base/Layout/LayoutManager.cs
-
tests/Avalonia.Base.UnitTests/Layout/LayoutManagerTests.cs
|
|
|
@ -298,14 +298,15 @@ HRESULT WindowBaseImpl::Resize(double x, double y, AvnPlatformResizeReason reaso |
|
|
|
} |
|
|
|
|
|
|
|
@try { |
|
|
|
lastSize = NSSize {x, y}; |
|
|
|
|
|
|
|
if (!_shown) { |
|
|
|
BaseEvents->Resized(AvnSize{x, y}, reason); |
|
|
|
} |
|
|
|
else if(Window != nullptr) { |
|
|
|
[Window setContentSize:lastSize]; |
|
|
|
[Window invalidateShadow]; |
|
|
|
if(x != lastSize.width || y != lastSize.height) { |
|
|
|
lastSize = NSSize{x, y}; |
|
|
|
|
|
|
|
if (!_shown) { |
|
|
|
BaseEvents->Resized(AvnSize{x, y}, reason); |
|
|
|
} else if (Window != nullptr) { |
|
|
|
[Window setContentSize:lastSize]; |
|
|
|
[Window invalidateShadow]; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@finally { |
|
|
|
|
|
|
|
@ -28,7 +28,7 @@ namespace Avalonia.Layout |
|
|
|
public LayoutManager(ILayoutRoot owner) |
|
|
|
{ |
|
|
|
_owner = owner ?? throw new ArgumentNullException(nameof(owner)); |
|
|
|
_executeLayoutPass = ExecuteLayoutPass; |
|
|
|
_executeLayoutPass = ExecuteQueuedLayoutPass; |
|
|
|
} |
|
|
|
|
|
|
|
public virtual event EventHandler? LayoutUpdated; |
|
|
|
@ -94,6 +94,16 @@ namespace Avalonia.Layout |
|
|
|
QueueLayoutPass(); |
|
|
|
} |
|
|
|
|
|
|
|
private void ExecuteQueuedLayoutPass() |
|
|
|
{ |
|
|
|
if (!_queued) |
|
|
|
{ |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
ExecuteLayoutPass(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <inheritdoc/>
|
|
|
|
public virtual void ExecuteLayoutPass() |
|
|
|
{ |
|
|
|
@ -319,8 +329,8 @@ namespace Avalonia.Layout |
|
|
|
{ |
|
|
|
if (!_queued && !_running) |
|
|
|
{ |
|
|
|
Dispatcher.UIThread.Post(_executeLayoutPass, DispatcherPriority.Layout); |
|
|
|
_queued = true; |
|
|
|
Dispatcher.UIThread.Post(_executeLayoutPass, DispatcherPriority.Layout); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -2,6 +2,7 @@ using System.Collections.Generic; |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Controls; |
|
|
|
using Avalonia.Layout; |
|
|
|
using Avalonia.Threading; |
|
|
|
using Xunit; |
|
|
|
|
|
|
|
namespace Avalonia.Base.UnitTests.Layout |
|
|
|
@ -421,5 +422,22 @@ namespace Avalonia.Base.UnitTests.Layout |
|
|
|
Assert.Equal(new Size(200, 200), control.Bounds.Size); |
|
|
|
Assert.Equal(new Size(200, 200), control.DesiredSize); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void LayoutManager_Execute_Layout_Pass_Should_Clear_Queued_LayoutPasses() |
|
|
|
{ |
|
|
|
var control = new LayoutTestControl(); |
|
|
|
var root = new LayoutTestRoot { Child = control }; |
|
|
|
|
|
|
|
int layoutCount = 0; |
|
|
|
root.LayoutUpdated += (_, _) => layoutCount++; |
|
|
|
|
|
|
|
root.LayoutManager.InvalidateArrange(control); |
|
|
|
root.LayoutManager.ExecuteInitialLayoutPass(); |
|
|
|
|
|
|
|
Dispatcher.UIThread.RunJobs(DispatcherPriority.Layout); |
|
|
|
|
|
|
|
Assert.Equal(1, layoutCount); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|