Browse Source

Merge pull request #3553 from AvaloniaUI/fixes/3550-menu-sizing

Prevent reentrancy in LayoutManager.ExecuteInitialLayoutPass
release/0.9.4
Steven Kirk 6 years ago
committed by Dan Walmsley
parent
commit
fc3278d171
  1. 12
      src/Avalonia.Layout/LayoutManager.cs
  2. 33
      tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs

12
src/Avalonia.Layout/LayoutManager.cs

@ -126,8 +126,16 @@ namespace Avalonia.Layout
/// <inheritdoc/>
public void ExecuteInitialLayoutPass(ILayoutRoot root)
{
Measure(root);
Arrange(root);
try
{
_running = true;
Measure(root);
Arrange(root);
}
finally
{
_running = false;
}
// Running the initial layout pass may have caused some control to be invalidated
// so run a full layout pass now (this usually due to scrollbars; its not known

33
tests/Avalonia.Layout.UnitTests/LayoutManagerTests.cs

@ -374,5 +374,38 @@ namespace Avalonia.Layout.UnitTests
Assert.True(control.Measured);
Assert.True(control.IsMeasureValid);
}
[Fact]
public void Calling_ExecuteLayoutPass_From_ExecuteInitialLayoutPass_Does_Not_Break_Measure()
{
// Test for issue #3550.
var control = new LayoutTestControl();
var root = new LayoutTestRoot { Child = control };
var count = 0;
root.LayoutManager.ExecuteInitialLayoutPass(root);
control.Measured = false;
control.DoMeasureOverride = (l, s) =>
{
if (count++ == 0)
{
control.InvalidateMeasure();
root.LayoutManager.ExecuteLayoutPass();
return new Size(100, 100);
}
else
{
return new Size(200, 200);
}
};
root.InvalidateMeasure();
control.InvalidateMeasure();
root.LayoutManager.ExecuteInitialLayoutPass(root);
Assert.Equal(new Size(200, 200), control.Bounds.Size);
Assert.Equal(new Size(200, 200), control.DesiredSize);
}
}
}

Loading…
Cancel
Save