Skip to content

Commit

Permalink
fix(reg): Workaround Gallery measure issue on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
Youssef1313 committed Sep 13, 2024
1 parent a0955f2 commit a6c0107
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -389,11 +389,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down Expand Up @@ -444,11 +441,8 @@ public _View Build(object __ResourceOwner_1)
;
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down Expand Up @@ -266,11 +263,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down Expand Up @@ -355,11 +349,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,8 @@ public _View Build(object __ResourceOwner_1)
;
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,8 @@ public _View Build(object __ResourceOwner_1)
}
if (__rootInstance is DependencyObject d)
{
if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)
{
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
}
global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);
__nameScope.Owner = d;
global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);
}
return __rootInstance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -953,11 +953,8 @@ private void BuildChildSubclasses(IIndentedStringBuilder writer, bool isTopLevel

using (writer.BlockInvariant("if (__rootInstance is DependencyObject d)", kvp.Value.ReturnType))
{
using (writer.BlockInvariant("if (global::Microsoft.UI.Xaml.NameScope.GetNameScope(d) == null)", kvp.Value.ReturnType))
{
writer.AppendLineIndented("global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);");
writer.AppendLineIndented("__nameScope.Owner = d;");
}
writer.AppendLineIndented("global::Microsoft.UI.Xaml.NameScope.SetNameScope(d, __nameScope);");
writer.AppendLineIndented("__nameScope.Owner = d;");

writer.AppendLineIndented("global::Uno.UI.FrameworkElementHelper.AddObjectReference(d, this);");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ public async Task When_InvalidatingMeasureExplicitly()

using var _ = new AssertionScope();

ctl1.MeasureCount.Should().Be(1);
ctl1.MeasureCount.Should().Be(2);
ctl2.MeasureCount.Should().Be(2);
ctl3.MeasureCount.Should().Be(1);

Expand Down
5 changes: 5 additions & 0 deletions src/Uno.UI/Extensions/ViewExtensions.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
using Android.Views.Animations;
using Microsoft.UI.Xaml.Controls;
using Uno.UI.Controls;
using Microsoft.UI.Xaml.Media;

namespace Uno.UI
{
Expand Down Expand Up @@ -705,6 +706,10 @@ public static string ShowLocalVisualTree(this ViewGroup viewGroup, int fromHeigh
{
root = parent;
}
else if (root is DependencyObject @do && VisualTreeHelper.GetParent(@do) is ViewGroup managedParent)
{
root = managedParent;
}
else
{
break;
Expand Down
7 changes: 6 additions & 1 deletion src/Uno.UI/UI/Xaml/ILayouterElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ internal static bool DoMeasure(this ILayouterElement element, Size availableSize
if (isDirty || frameworkElement is null)
{
// We must reset the flag **BEFORE** doing the actual measure, so the elements are able to re-invalidate themselves
// TODO: We are not controlling measure dirty path on Android. If we did in future, we must clear it here as well.
frameworkElement?.ClearLayoutFlags(UIElement.LayoutFlag.MeasureDirty);

// The dirty flag is explicitly set on this element
Expand All @@ -91,7 +92,9 @@ internal static bool DoMeasure(this ILayouterElement element, Size availableSize
LayoutInformation.SetAvailableSize(element, availableSize);
}

return true; // end of isDirty processing
// TODO: This is NOT correct.
// We shouldn't return here. Skipping children measure is incorrect but fixing it on Android isn't trivial.
return true;
}

// The measure dirty flag is set on one of the descendents:
Expand All @@ -110,6 +113,8 @@ internal static bool DoMeasure(this ILayouterElement element, Size availableSize
{
var previousDesiredSize = childAsUIElement.m_desiredSize;
childAsUIElement.EnsureLayoutStorage();

// TODO: This is NOT correct. This should call DoMeasure (the same method we are in currently!)
element.Layouter.MeasureChild(child, childAsUIElement.m_previousAvailableSize);
var newDesiredSize = childAsUIElement.m_desiredSize;
if (newDesiredSize != previousDesiredSize)
Expand Down
25 changes: 25 additions & 0 deletions src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,31 @@ internal static void AddChild(UIElement view, UIElement child)
{
#if __ANDROID__
view.AddView(child);

// Reset to original (invalidated) state
child.ResetLayoutFlags();
if (view.IsMeasureDirtyPathDisabled)
{
FrameworkElementHelper.SetUseMeasurePathDisabled(child); // will invalidate too
}
else
{
child.InvalidateMeasure();
}

if (view.IsArrangeDirtyPathDisabled)
{
FrameworkElementHelper.SetUseArrangePathDisabled(child); // will invalidate too
}
else
{
child.InvalidateArrange();
}

// Force a new measure of this element (the parent of the new child)
view.InvalidateMeasure();
view.InvalidateArrange();

#elif __IOS__ || __MACOS__
view.AddSubview(child);
#elif __CROSSRUNTIME__
Expand Down
3 changes: 3 additions & 0 deletions src/Uno.UI/UI/Xaml/UIElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,9 @@ public void InvalidateMeasure()
// Use a non-virtual version of the RequestLayout method, for performance.
base.RequestLayout();
SetLayoutFlags(LayoutFlag.MeasureDirty);

// HACK: Android's implementation of measure/arrange is not accurate. See comments in LayouterElementExtensions.DoMeasure
(VisualTreeHelper.GetParent(this) as UIElement)?.InvalidateMeasure();
#elif __IOS__
SetNeedsLayout();
SetLayoutFlags(LayoutFlag.MeasureDirty);
Expand Down

0 comments on commit a6c0107

Please sign in to comment.