From 66bcf7249d90b8d4ced872267728a9db67e94489 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Tue, 8 Oct 2024 14:52:45 -0400 Subject: [PATCH 1/7] chore: Revert "chore: Adjust Android's layouting workaround" This reverts commit 2e4a1c4dfb0bc18642c793e780954e0ad01aa578. --- src/Uno.UI/UI/Xaml/UIElement.cs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/src/Uno.UI/UI/Xaml/UIElement.cs b/src/Uno.UI/UI/Xaml/UIElement.cs index bd1c88625bae..b169fcd006c0 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.cs @@ -1157,23 +1157,7 @@ public void InvalidateMeasure() SetLayoutFlags(LayoutFlag.MeasureDirty); // HACK: Android's implementation of measure/arrange is not accurate. See comments in LayouterElementExtensions.DoMeasure - global::Android.Views.IViewParent parent = this; - parent = parent.Parent; - while (parent is not null) - { - if (parent is UIElement parentAsUIElement) - { - parentAsUIElement.InvalidateMeasure(); - break; - } - else - { - parent.RequestLayout(); - } - - parent = parent.Parent; - } - + (VisualTreeHelper.GetParent(this) as UIElement)?.InvalidateMeasure(); #elif __IOS__ SetNeedsLayout(); SetLayoutFlags(LayoutFlag.MeasureDirty); From 19e95295225985c6f3f3bf8bb343e5a1312c97de Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Tue, 8 Oct 2024 14:53:27 -0400 Subject: [PATCH 2/7] Revert "fix(reg): Workaround Gallery measure issue on Android" This reverts commit 152944bf1d87f7ef2ca2e169bfdb12b8db032a46. --- .../Tests/Windows_UI_Xaml/Given_UIElement.cs | 4 --- .../Extensions/ViewExtensions.Android.cs | 5 ---- src/Uno.UI/UI/Xaml/ILayouterElement.cs | 7 +----- src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs | 25 ------------------- src/Uno.UI/UI/Xaml/UIElement.cs | 3 --- 5 files changed, 1 insertion(+), 43 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs index 60fa526b05ca..fa8acc766dd1 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_UIElement.cs @@ -938,11 +938,7 @@ public async Task When_InvalidatingMeasureExplicitly() using var _ = new AssertionScope(); -#if __ANDROID__ - ctl1.MeasureCount.Should().Be(2); -#else ctl1.MeasureCount.Should().Be(1); -#endif ctl2.MeasureCount.Should().Be(2); ctl3.MeasureCount.Should().Be(1); diff --git a/src/Uno.UI/Extensions/ViewExtensions.Android.cs b/src/Uno.UI/Extensions/ViewExtensions.Android.cs index c6c2124279c3..4ac82ffcda42 100644 --- a/src/Uno.UI/Extensions/ViewExtensions.Android.cs +++ b/src/Uno.UI/Extensions/ViewExtensions.Android.cs @@ -21,7 +21,6 @@ using Android.Views.Animations; using Microsoft.UI.Xaml.Controls; using Uno.UI.Controls; -using Microsoft.UI.Xaml.Media; namespace Uno.UI { @@ -706,10 +705,6 @@ 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; diff --git a/src/Uno.UI/UI/Xaml/ILayouterElement.cs b/src/Uno.UI/UI/Xaml/ILayouterElement.cs index 68f5f0d7d2fa..9d43be9e9e72 100644 --- a/src/Uno.UI/UI/Xaml/ILayouterElement.cs +++ b/src/Uno.UI/UI/Xaml/ILayouterElement.cs @@ -74,7 +74,6 @@ 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 @@ -92,9 +91,7 @@ internal static bool DoMeasure(this ILayouterElement element, Size availableSize LayoutInformation.SetAvailableSize(element, availableSize); } - // 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; + return true; // end of isDirty processing } // The measure dirty flag is set on one of the descendents: @@ -113,8 +110,6 @@ 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) diff --git a/src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs b/src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs index 0e74bb600b47..ec4af5e05f56 100644 --- a/src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs +++ b/src/Uno.UI/UI/Xaml/Media/VisualTreeHelper.cs @@ -393,31 +393,6 @@ 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__ diff --git a/src/Uno.UI/UI/Xaml/UIElement.cs b/src/Uno.UI/UI/Xaml/UIElement.cs index b169fcd006c0..2753f624f8d1 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.cs @@ -1155,9 +1155,6 @@ 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); From 519736e86c465a57723c9e987e5b964145274fc5 Mon Sep 17 00:00:00 2001 From: Jerome Laban Date: Tue, 8 Oct 2024 14:55:57 -0400 Subject: [PATCH 3/7] fix(android): Restore inheritance workaround for android --- src/Uno.UI/UI/Xaml/DependencyObjectStore.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs index 1305066e97cb..fc2d4918e944 100644 --- a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs +++ b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs @@ -1327,7 +1327,13 @@ private void CleanupInheritedProperties() return (localProperty, propertyDetails); } } - else if (property.IsAttached && property.IsInherited) + else if (property.IsAttached + && property.IsInherited + +#if __ANDROID__ + && _properties.GetPropertyDetails(property) is { } +#endif + ) { return (property, _properties.GetPropertyDetails(property)); } From 2b2f2f96243f4e35beb0a36dd5e278dc95aa117d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Wed, 9 Oct 2024 08:29:23 -0400 Subject: [PATCH 4/7] chore: Adjust android layouting --- src/Uno.UI/UI/Xaml/DependencyObjectStore.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs index fc2d4918e944..a5ca5d152cc8 100644 --- a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs +++ b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs @@ -1331,7 +1331,7 @@ private void CleanupInheritedProperties() && property.IsInherited #if __ANDROID__ - && _properties.GetPropertyDetails(property) is { } + && _properties.FindPropertyDetails(property) is { } #endif ) { From 7e3285f080c7657686fa636e2a631426f788ae51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Wed, 9 Oct 2024 09:23:54 -0400 Subject: [PATCH 5/7] chore: Disable nuget checks --- src/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 2bade8325363..799ce2dcde05 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -224,6 +224,9 @@ $(NoWarn);CS0436 + + $(NoWarn);NU1903 + From adf5b49c9259c491ddc6c9401555bb6da7a86078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Wed, 9 Oct 2024 11:30:23 -0400 Subject: [PATCH 6/7] chore: Adjust comments --- src/Uno.UI/UI/Xaml/DependencyObjectStore.cs | 5 +++++ src/Uno.UI/UI/Xaml/ILayouterElement.cs | 8 +++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs index a5ca5d152cc8..571f0fcc590e 100644 --- a/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs +++ b/src/Uno.UI/UI/Xaml/DependencyObjectStore.cs @@ -1331,6 +1331,11 @@ private void CleanupInheritedProperties() && property.IsInherited #if __ANDROID__ + // This is a workaround related to property inheritance and + // https://github.com/unoplatform/uno/pull/18261. + // Removing this line can randomly produce elements not rendering + // properly, such as TextBlock not measure/arrange properly + // even when invalidated. && _properties.FindPropertyDetails(property) is { } #endif ) diff --git a/src/Uno.UI/UI/Xaml/ILayouterElement.cs b/src/Uno.UI/UI/Xaml/ILayouterElement.cs index 9d43be9e9e72..28bf1e43d1f3 100644 --- a/src/Uno.UI/UI/Xaml/ILayouterElement.cs +++ b/src/Uno.UI/UI/Xaml/ILayouterElement.cs @@ -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 @@ -91,7 +92,10 @@ 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: @@ -110,6 +114,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) From 5556f7dfcdf918ffa623d3ac2c1efecc87dc7dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Laban?= Date: Wed, 9 Oct 2024 11:46:57 -0400 Subject: [PATCH 7/7] chore: Adjust formatting --- src/Uno.UI/UI/Xaml/ILayouterElement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uno.UI/UI/Xaml/ILayouterElement.cs b/src/Uno.UI/UI/Xaml/ILayouterElement.cs index 28bf1e43d1f3..58c0dc9c4032 100644 --- a/src/Uno.UI/UI/Xaml/ILayouterElement.cs +++ b/src/Uno.UI/UI/Xaml/ILayouterElement.cs @@ -114,7 +114,7 @@ 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;