Skip to content

Commit

Permalink
Merge pull request AvaloniaUI#8305 from AvaloniaUI/fixes/reduce-exces…
Browse files Browse the repository at this point in the history
…sive-layout-passes

Fixes/reduce excessive layout passes
# Conflicts:
#	tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
  • Loading branch information
danwalmsley committed Jun 10, 2022
1 parent 96c21bf commit 82d55a1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
17 changes: 9 additions & 8 deletions native/Avalonia.Native/src/OSX/WindowBaseImpl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -297,14 +297,15 @@
}

@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 {
Expand Down
14 changes: 12 additions & 2 deletions src/Avalonia.Layout/LayoutManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class LayoutManager : ILayoutManager, IDisposable
public LayoutManager(ILayoutRoot owner)
{
_owner = owner ?? throw new ArgumentNullException(nameof(owner));
_executeLayoutPass = ExecuteLayoutPass;
_executeLayoutPass = ExecuteQueuedLayoutPass;
}

public virtual event EventHandler? LayoutUpdated;
Expand Down Expand Up @@ -94,6 +94,16 @@ public virtual void InvalidateArrange(ILayoutable control)
QueueLayoutPass();
}

private void ExecuteQueuedLayoutPass()
{
if (!_queued)
{
return;
}

ExecuteLayoutPass();
}

/// <inheritdoc/>
public virtual void ExecuteLayoutPass()
{
Expand Down Expand Up @@ -319,8 +329,8 @@ private void QueueLayoutPass()
{
if (!_queued && !_running)
{
Dispatcher.UIThread.Post(_executeLayoutPass, DispatcherPriority.Layout);
_queued = true;
Dispatcher.UIThread.Post(_executeLayoutPass, DispatcherPriority.Layout);
}
}

Expand Down
19 changes: 19 additions & 0 deletions tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Threading;
using Xunit;

namespace Avalonia.Layout.UnitTests
Expand Down Expand Up @@ -420,5 +422,22 @@ public void Calling_ExecuteLayoutPass_From_ExecuteInitialLayoutPass_Does_Not_Bre
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);
}
}
}

0 comments on commit 82d55a1

Please sign in to comment.