Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport #18193 and #18377 #18381

Merged
merged 4 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/test-scripts/run-netcore-mobile-template-tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function CleanupTree()
git clean -fdx -e *.binlog
}

$default = @('/ds', '/v:m', '/p:UseDotNetNativeToolchain=false', '/p:PackageCertificateKeyFile=')
$default = @('/ds', '/v:m', '/p:UseDotNetNativeToolchain=false', '/p:PackageCertificateKeyFile=', '/p:RunAOTCompilation=false')

if ($IsWindows)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,11 @@ 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);

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
14 changes: 14 additions & 0 deletions src/Uno.UI/UI/Xaml/Controls/TextBox/TextBoxView.Android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ internal partial class TextBoxView : EditText, DependencyObject
internal TextBox? Owner => _ownerRef?.Target as TextBox;

private Action? _foregroundChanged;
private bool _isDisposed;

public TextBoxView(TextBox owner)
: base(ContextHelper.Current)
Expand Down Expand Up @@ -313,10 +314,23 @@ private void OnForegroundChanged(Brush oldValue, Brush newValue)

void ApplyColor()
{
if (_isDisposed)
{
// Binding changes may happen after the
// underlying control has been disposed
return;
}

SetTextColor(scb.Color);
SetCursorColor(scb.Color);
}
}
}

protected override void Dispose(bool disposing)
{
_isDisposed = true;
base.Dispose(disposing);
}
}
}
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
19 changes: 19 additions & 0 deletions src/Uno.UI/UI/Xaml/UIElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,25 @@ 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
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;
}

#elif __IOS__
SetNeedsLayout();
SetLayoutFlags(LayoutFlag.MeasureDirty);
Expand Down
Loading