Skip to content

Commit 4ff875a

Browse files
authored
Revert "Cleanup virtual layer measure invalidation (#28756)" (#28872)
This reverts commit 82b018a.
1 parent 82b018a commit 4ff875a

File tree

16 files changed

+218
-205
lines changed

16 files changed

+218
-205
lines changed

src/Controls/src/Core/ContentPresenter.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,10 @@ Size ICrossPlatformLayout.CrossPlatformArrange(Rect bounds)
130130
this.ArrangeContent(bounds);
131131
return bounds.Size;
132132
}
133+
134+
private protected override void InvalidateMeasureLegacy(InvalidationTrigger trigger, int depth, int depthLeveltoInvalidate)
135+
{
136+
base.InvalidateMeasureLegacy(trigger, depth, 1);
137+
}
133138
}
134139
}

src/Controls/src/Core/InvalidationEventArgs.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,15 @@ public InvalidationEventArgs(InvalidationTrigger trigger)
1010
{
1111
Trigger = trigger;
1212
}
13+
public InvalidationEventArgs(InvalidationTrigger trigger, int depth) : this(trigger)
14+
{
15+
CurrentInvalidationDepth = depth;
16+
}
17+
1318

1419
public InvalidationTrigger Trigger { get; private set; }
20+
21+
22+
public int CurrentInvalidationDepth { set; get; }
1523
}
1624
}

src/Controls/src/Core/LegacyLayouts/Layout.cs

Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,8 @@ public override SizeRequest Measure(double widthConstraint, double heightConstra
202202
SizeRequest size = base.Measure(widthConstraint - Padding.HorizontalThickness, heightConstraint - Padding.VerticalThickness, flags);
203203
#pragma warning restore CS0618 // Type or member is obsolete
204204
#pragma warning disable CS0618 // Type or member is obsolete
205-
var request = new Size(size.Request.Width + Padding.HorizontalThickness, size.Request.Height + Padding.VerticalThickness);
206-
var minimum = new Size(size.Minimum.Width + Padding.HorizontalThickness, size.Minimum.Height + Padding.VerticalThickness);
207-
208-
DesiredSize = request;
209-
210-
return new SizeRequest(request, minimum);
205+
return new SizeRequest(new Size(size.Request.Width + Padding.HorizontalThickness, size.Request.Height + Padding.VerticalThickness),
206+
new Size(size.Minimum.Width + Padding.HorizontalThickness, size.Minimum.Height + Padding.VerticalThickness));
211207
#pragma warning restore CS0618 // Type or member is obsolete
212208
}
213209
#pragma warning restore CS0672 // Member overrides obsolete member
@@ -324,19 +320,14 @@ public void RaiseChild(View view)
324320
[Obsolete("Use InvalidateMeasure depending on your scenario")]
325321
protected virtual void InvalidateLayout()
326322
{
327-
SetNeedsLayout();
323+
_hasDoneLayout = false;
328324
InvalidateMeasureInternal(InvalidationTrigger.MeasureChanged);
329325
if (!_hasDoneLayout)
330326
{
331327
ForceLayout();
332328
}
333329
}
334330

335-
void SetNeedsLayout()
336-
{
337-
_hasDoneLayout = false;
338-
}
339-
340331
/// <summary>
341332
/// Positions and sizes the children of a layout.
342333
/// </summary>
@@ -350,18 +341,10 @@ void SetNeedsLayout()
350341
[Obsolete("Use ArrangeOverride")]
351342
protected abstract void LayoutChildren(double x, double y, double width, double height);
352343

353-
internal override void OnChildMeasureInvalidated(VisualElement child, InvalidationTrigger trigger)
344+
internal override void OnChildMeasureInvalidatedInternal(VisualElement child, InvalidationTrigger trigger, int depth)
354345
{
355-
SetNeedsLayout();
356-
InvalidateMeasureCache();
357-
358-
OnChildMeasureInvalidated(child, new InvalidationEventArgs(trigger));
359-
360-
var propagatedTrigger = GetPropagatedTrigger(trigger);
361-
InvokeMeasureInvalidated(propagatedTrigger);
362-
363-
// Behavior of legacy layouts is to always propagate the measure invalidation to the parent
364-
(Parent as VisualElement)?.OnChildMeasureInvalidated(this, propagatedTrigger);
346+
// TODO: once we remove old Xamarin public signatures we can invoke `OnChildMeasureInvalidated(VisualElement, InvalidationTrigger)` directly
347+
OnChildMeasureInvalidated(child, new InvalidationEventArgs(trigger, depth));
365348
}
366349

367350
/// <summary>
@@ -373,6 +356,19 @@ internal override void OnChildMeasureInvalidated(VisualElement child, Invalidati
373356
/// <remarks>This method has a default implementation and application developers must call the base implementation.</remarks>
374357
protected void OnChildMeasureInvalidated(object sender, EventArgs e)
375358
{
359+
var depth = 0;
360+
InvalidationTrigger trigger;
361+
if (e is InvalidationEventArgs args)
362+
{
363+
trigger = args.Trigger;
364+
depth = args.CurrentInvalidationDepth;
365+
}
366+
else
367+
{
368+
trigger = InvalidationTrigger.Undefined;
369+
}
370+
371+
OnChildMeasureInvalidated((VisualElement)sender, trigger, depth);
376372
OnChildMeasureInvalidated();
377373
}
378374

@@ -546,6 +542,55 @@ internal static void LayoutChildIntoBoundingRegion(View child, Rect region, Size
546542
child.Layout(region);
547543
}
548544

545+
internal virtual void OnChildMeasureInvalidated(VisualElement child, InvalidationTrigger trigger, int depth)
546+
{
547+
IReadOnlyList<Element> children = LogicalChildrenInternal;
548+
int count = children.Count;
549+
for (var index = 0; index < count; index++)
550+
{
551+
if (LogicalChildrenInternal[index] is VisualElement v && v.IsVisible && (!v.IsPlatformEnabled || !v.IsPlatformStateConsistent))
552+
{
553+
return;
554+
}
555+
}
556+
557+
if (child is View view)
558+
{
559+
// we can ignore the request if we are either fully constrained or when the size request changes and we were already fully constrained
560+
if ((trigger == InvalidationTrigger.MeasureChanged && view.Constraint == LayoutConstraint.Fixed) ||
561+
(trigger == InvalidationTrigger.SizeRequestChanged && view.ComputedConstraint == LayoutConstraint.Fixed))
562+
{
563+
return;
564+
}
565+
if (trigger == InvalidationTrigger.HorizontalOptionsChanged || trigger == InvalidationTrigger.VerticalOptionsChanged)
566+
{
567+
ComputeConstraintForView(view);
568+
}
569+
}
570+
571+
InvalidateMeasureLegacy(trigger, depth, int.MaxValue);
572+
}
573+
574+
// This lets us override the rules for invalidation on MAUI controls that unfortunately still inheirt from the legacy layout
575+
private protected virtual void InvalidateMeasureLegacy(InvalidationTrigger trigger, int depth, int depthLeveltoInvalidate)
576+
{
577+
if (depth <= depthLeveltoInvalidate)
578+
{
579+
if (trigger == InvalidationTrigger.RendererReady)
580+
{
581+
InvalidateMeasureInternal(new InvalidationEventArgs(InvalidationTrigger.RendererReady, depth));
582+
}
583+
else
584+
{
585+
InvalidateMeasureInternal(new InvalidationEventArgs(InvalidationTrigger.MeasureChanged, depth));
586+
}
587+
}
588+
else
589+
{
590+
FireMeasureChanged(trigger, depth);
591+
}
592+
}
593+
549594
internal override void OnIsVisibleChanged(bool oldValue, bool newValue)
550595
{
551596
base.OnIsVisibleChanged(oldValue, newValue);
@@ -663,6 +708,19 @@ bool ShouldLayoutChildren()
663708
return true;
664709
}
665710

711+
protected override void InvalidateMeasureOverride()
712+
{
713+
base.InvalidateMeasureOverride();
714+
715+
foreach (var child in ((IElementController)this).LogicalChildren)
716+
{
717+
if (child is IView fe)
718+
{
719+
fe.InvalidateMeasure();
720+
}
721+
}
722+
}
723+
666724
protected override Size ArrangeOverride(Rect bounds)
667725
{
668726
base.ArrangeOverride(bounds);

src/Controls/src/Core/LegacyLayouts/StackLayout.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,12 @@ protected override SizeRequest OnMeasure(double widthConstraint, double heightCo
9292
return result;
9393
}
9494

95-
internal override void OnChildMeasureInvalidated(VisualElement child, InvalidationTrigger trigger)
96-
{
97-
_layoutInformation = new LayoutInformation();
98-
base.OnChildMeasureInvalidated(child, trigger);
99-
}
100-
10195
internal override void ComputeConstraintForView(View view)
10296
{
10397
ComputeConstraintForView(view, false);
10498
}
10599

106-
internal override void InvalidateMeasureInternal(InvalidationTrigger trigger)
100+
internal override void InvalidateMeasureInternal(InvalidationEventArgs trigger)
107101
{
108102
_layoutInformation = new LayoutInformation();
109103
base.InvalidateMeasureInternal(trigger);

src/Controls/src/Core/Page/Page.cs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -506,11 +506,10 @@ protected override void OnBindingContextChanged()
506506
}
507507

508508

509-
internal override void OnChildMeasureInvalidated(VisualElement child, InvalidationTrigger trigger)
509+
internal override void OnChildMeasureInvalidatedInternal(VisualElement child, InvalidationTrigger trigger, int depth)
510510
{
511-
OnChildMeasureInvalidated(child, new InvalidationEventArgs(trigger));
512-
var propagatedTrigger = GetPropagatedTrigger(trigger);
513-
InvokeMeasureInvalidated(propagatedTrigger);
511+
// TODO: once we remove old Xamarin public signatures we can invoke `OnChildMeasureInvalidated(VisualElement, InvalidationTrigger)` directly
512+
OnChildMeasureInvalidated(child, new InvalidationEventArgs(trigger, depth));
514513
}
515514

516515
/// <summary>
@@ -520,6 +519,19 @@ internal override void OnChildMeasureInvalidated(VisualElement child, Invalidati
520519
/// <param name="e">The event arguments.</param>
521520
protected virtual void OnChildMeasureInvalidated(object sender, EventArgs e)
522521
{
522+
var depth = 0;
523+
InvalidationTrigger trigger;
524+
if (e is InvalidationEventArgs args)
525+
{
526+
trigger = args.Trigger;
527+
depth = args.CurrentInvalidationDepth;
528+
}
529+
else
530+
{
531+
trigger = InvalidationTrigger.Undefined;
532+
}
533+
534+
OnChildMeasureInvalidated((VisualElement)sender, trigger, depth);
523535
}
524536

525537
/// <summary>
@@ -598,6 +610,36 @@ protected void UpdateChildrenLayout()
598610
}
599611
}
600612

613+
internal virtual void OnChildMeasureInvalidated(VisualElement child, InvalidationTrigger trigger, int depth)
614+
{
615+
var container = this as IPageContainer<Page>;
616+
if (container != null)
617+
{
618+
Page page = container.CurrentPage;
619+
if (page != null && page.IsVisible && (!page.IsPlatformEnabled || !page.IsPlatformStateConsistent))
620+
return;
621+
}
622+
else
623+
{
624+
var logicalChildren = this.InternalChildren;
625+
for (var i = 0; i < logicalChildren.Count; i++)
626+
{
627+
var v = logicalChildren[i] as VisualElement;
628+
if (v != null && v.IsVisible && (!v.IsPlatformEnabled || !v.IsPlatformStateConsistent))
629+
return;
630+
}
631+
}
632+
633+
if (depth <= 1)
634+
{
635+
InvalidateMeasureInternal(new InvalidationEventArgs(InvalidationTrigger.MeasureChanged, depth));
636+
}
637+
else
638+
{
639+
FireMeasureChanged(trigger, depth);
640+
}
641+
}
642+
601643
internal void OnAppearing(Action action)
602644
{
603645
if (_hasAppeared)

src/Controls/src/Core/PublicAPI/net-android/PublicAPI.Unshipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ const Microsoft.Maui.Controls.TitleBar.TrailingHiddenState = "TrailingContentCol
6969
const Microsoft.Maui.Controls.TitleBar.TrailingVisibleState = "TrailingContentVisible" -> string!
7070
Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
7171
Microsoft.Maui.Controls.HandlerProperties
72-
*REMOVED*override Microsoft.Maui.Controls.Compatibility.Layout.InvalidateMeasureOverride() -> void
7372
Microsoft.Maui.Controls.HybridWebView
7473
Microsoft.Maui.Controls.HybridWebView.DefaultFile.get -> string?
7574
Microsoft.Maui.Controls.HybridWebView.DefaultFile.set -> void

src/Controls/src/Core/PublicAPI/net-ios/PublicAPI.Unshipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ const Microsoft.Maui.Controls.TitleBar.TrailingHiddenState = "TrailingContentCol
206206
const Microsoft.Maui.Controls.TitleBar.TrailingVisibleState = "TrailingContentVisible" -> string!
207207
Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
208208
Microsoft.Maui.Controls.HandlerProperties
209-
*REMOVED*override Microsoft.Maui.Controls.Compatibility.Layout.InvalidateMeasureOverride() -> void
210209
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker
211210
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker.Dispose() -> void
212211
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker.OnLayoutSubviews() -> void

src/Controls/src/Core/PublicAPI/net-maccatalyst/PublicAPI.Unshipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ const Microsoft.Maui.Controls.TitleBar.TrailingHiddenState = "TrailingContentCol
207207
const Microsoft.Maui.Controls.TitleBar.TrailingVisibleState = "TrailingContentVisible" -> string!
208208
Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
209209
Microsoft.Maui.Controls.HandlerProperties
210-
*REMOVED*override Microsoft.Maui.Controls.Compatibility.Layout.InvalidateMeasureOverride() -> void
211210
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker
212211
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker.Dispose() -> void
213212
*REMOVED*Microsoft.Maui.Controls.Handlers.Compatibility.ShellScrollViewTracker.OnLayoutSubviews() -> void

src/Controls/src/Core/PublicAPI/net-tizen/PublicAPI.Unshipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,6 @@ const Microsoft.Maui.Controls.TitleBar.TitleVisibleState = "TitleVisible" -> str
6868
const Microsoft.Maui.Controls.TitleBar.TrailingHiddenState = "TrailingContentCollapsed" -> string!
6969
const Microsoft.Maui.Controls.TitleBar.TrailingVisibleState = "TrailingContentVisible" -> string!
7070
Microsoft.Maui.Controls.HandlerProperties
71-
*REMOVED*override Microsoft.Maui.Controls.Compatibility.Layout.InvalidateMeasureOverride() -> void
7271
Microsoft.Maui.Controls.HybridWebView
7372
Microsoft.Maui.Controls.HybridWebView.DefaultFile.get -> string?
7473
Microsoft.Maui.Controls.HybridWebView.DefaultFile.set -> void

src/Controls/src/Core/PublicAPI/net-windows/PublicAPI.Unshipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ const Microsoft.Maui.Controls.TitleBar.TrailingHiddenState = "TrailingContentCol
7070
const Microsoft.Maui.Controls.TitleBar.TrailingVisibleState = "TrailingContentVisible" -> string!
7171
Microsoft.Maui.Controls.Embedding.EmbeddingExtensions
7272
Microsoft.Maui.Controls.HandlerProperties
73-
*REMOVED*override Microsoft.Maui.Controls.Compatibility.Layout.InvalidateMeasureOverride() -> void
7473
Microsoft.Maui.Controls.HybridWebView
7574
Microsoft.Maui.Controls.HybridWebView.DefaultFile.get -> string?
7675
Microsoft.Maui.Controls.HybridWebView.DefaultFile.set -> void

0 commit comments

Comments
 (0)