From 5f21882ed11f2a8bc97479b1f5a61c71176318bb Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Fri, 5 Apr 2024 19:38:23 -0500 Subject: [PATCH 01/17] Update GitInfo.txt (#21672) --- GitInfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitInfo.txt b/GitInfo.txt index 2a329af0bcd4..e88c611d044b 100644 --- a/GitInfo.txt +++ b/GitInfo.txt @@ -1 +1 @@ -8.0.20-ci.net8 \ No newline at end of file +8.0.20-preview From 4aec0608cc422f8e9f0f2951aab8bc9c06d602f1 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Tue, 9 Apr 2024 06:25:24 -0400 Subject: [PATCH 02/17] [android] improve FormattedString performance (#21712) Context: https://github.com/Redth/MauiCollectionViewGallery Fixes: https://github.com/dotnet/maui/issues/14222 This will conflict with: * https://github.com/dotnet/maui/pull/20352 But I will rework this after it is merged. Profiling the above sample while scrolling on a Pixel 5, a lot of time is spent in `FormattedStringExtensions.RecalculateSpanPositions()`: (20%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.RecalculateSpanPositions(Android.Widget.TextView,Microsoft.Maui.Controls.Label,Android.Text.SpannableString,Microsoft.Maui.SizeRequest) (11%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan.UpdateDrawState(Android.Text.TextPaint) (11%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan.Apply(Android.Text.TextPaint) (6.3%) MauiCollectionViewGallery!PoolMathApp.Helpers.FormattedTextExtensions.ToFormattedString(PoolMathApp.Models.FormattedTex The key contributors are `FontSpan` and `LineHeightSpan` which: * Implement `MetricAffectingSpan`, an abstract class that allows to change the metrics of the text. * Implement `UpdateDrawState()` and `Apply()` methods that are called during draw. Causing frequent Java -> C# interop. To fix this, let's move the following types from C# to Java: * `FontSpan` -> `PlatformFontSpan` * `LetterSpacingSpan` -> `PlatformFontSpan` (use different ctor) * `LineHeightSpan` -> `PlatformLineHeightSpan` `PlatformLineHeightSpan` is similar, as it is an implementation of the `LineHeightSpan` interface. With these changes, I see a nice improvement while scrolling: (5.5%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.RecalculateSpanPositions(Android.Widget.TextView,Microsoft.Maui.Controls.Label,Android.Text.SpannableString,Microsoft.Maui.SizeRequest) (4.0%) MauiCollectionViewGallery!PoolMathApp.Helpers.FormattedTextExtensions.ToFormattedString(PoolMathApp.Models.FormattedText `RecalculateSpanPositions` overall, went from 20% to 5.5%! Comparing the new types, the times spent calling the constructors are also improved: Before: (1.1%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.FontSpan..ctor(Microsoft.Maui.Font,M (1.5%) Microsoft.Maui.Controls!Microsoft.Maui.Controls.Platform.FormattedStringExtensions.LetterSpacingSpan..ctor(double) After: (1.0%) Microsoft.Maui!Microsoft.Maui.PlatformFontSpan..ctor(Android.Content.Context,Android.Graphics.Typeface,bool,single) (0.82%) Microsoft.Maui!Microsoft.Maui.PlatformFontSpan..ctor(single) This should be reasonable for .NET 8servicing, as there should be no behavior changes and no API changes. In a future PR, it looks like `FormattedStringExtensions` could be improved further, but this is a decent starting point that makes it a lot better. --- .../Extensions/FormattedStringExtensions.cs | 91 +----------------- .../com/microsoft/maui/PlatformFontSpan.java | 68 +++++++++++++ .../com/microsoft/maui/PlatformInterop.java | 4 +- .../maui/PlatformLineHeightSpan.java | 27 ++++++ src/Core/src/maui.aar | Bin 86449 -> 88415 bytes 5 files changed, 101 insertions(+), 89 deletions(-) create mode 100644 src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformFontSpan.java create mode 100644 src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformLineHeightSpan.java diff --git a/src/Controls/src/Core/Platform/Android/Extensions/FormattedStringExtensions.cs b/src/Controls/src/Core/Platform/Android/Extensions/FormattedStringExtensions.cs index ad2efeca7d39..b698c492eb55 100644 --- a/src/Controls/src/Core/Platform/Android/Extensions/FormattedStringExtensions.cs +++ b/src/Controls/src/Core/Platform/Android/Extensions/FormattedStringExtensions.cs @@ -64,8 +64,6 @@ internal static SpannableString ToSpannableStringNewWay( var builder = new StringBuilder(); - var fontMetrics = PlatformInterop.GetFontMetrics(context, defaultFontSize); - for (int i = 0; i < formattedString.Spans.Count; i++) { Span span = formattedString.Spans[i]; @@ -103,22 +101,22 @@ internal static SpannableString ToSpannableStringNewWay( spannable.SetSpan(new BackgroundColorSpan(span.BackgroundColor.ToPlatform()), start, end, SpanTypes.InclusiveExclusive); // LineHeight - if (span.LineHeight >= 0 && fontMetrics is not null) - spannable.SetSpan(new LineHeightSpan(span.LineHeight, fontMetrics.Top), start, end, SpanTypes.InclusiveExclusive); + if (span.LineHeight >= 0) + spannable.SetSpan(new PlatformLineHeightSpan(context, (float)span.LineHeight, (float)defaultFontSize), start, end, SpanTypes.InclusiveExclusive); // CharacterSpacing var characterSpacing = span.CharacterSpacing >= 0 ? span.CharacterSpacing : defaultCharacterSpacing; if (characterSpacing >= 0) - spannable.SetSpan(new LetterSpacingSpan(characterSpacing.ToEm()), start, end, SpanTypes.InclusiveInclusive); + spannable.SetSpan(new PlatformFontSpan(characterSpacing.ToEm()), start, end, SpanTypes.InclusiveInclusive); // Font var font = span.ToFont(defaultFontSize); if (font.IsDefault && defaultFont.HasValue) font = defaultFont.Value; if (!font.IsDefault) - spannable.SetSpan(new FontSpan(font, fontManager, context), start, end, SpanTypes.InclusiveInclusive); + spannable.SetSpan(new PlatformFontSpan(context ?? AAplication.Context, font.ToTypeface(fontManager), font.AutoScalingEnabled, (float)font.Size), start, end, SpanTypes.InclusiveInclusive); // TextDecorations var textDecorations = span.IsSet(Span.TextDecorationsProperty) @@ -226,86 +224,5 @@ public static void RecalculateSpanPositions(this TextView textView, Label elemen ((ISpatialElement)span).Region = Region.FromRectangles(spanRectangles).Inflate(10); } } - - class FontSpan : MetricAffectingSpan - { - readonly Font _font; - readonly IFontManager _fontManager; - readonly Context? _context; - - public FontSpan(Font font, IFontManager fontManager, Context? context) - { - _font = font; - _fontManager = fontManager; - _context = context; - } - - public override void UpdateDrawState(TextPaint? tp) - { - if (tp != null) - Apply(tp); - } - - public override void UpdateMeasureState(TextPaint p) - { - Apply(p); - } - - void Apply(TextPaint paint) - { - paint.SetTypeface(_font.ToTypeface(_fontManager)); - - paint.TextSize = TypedValue.ApplyDimension( - _font.AutoScalingEnabled ? ComplexUnitType.Sp : ComplexUnitType.Dip, - (float)_font.Size, - (_context ?? AAplication.Context)?.Resources?.DisplayMetrics); - } - } - - class LetterSpacingSpan : MetricAffectingSpan - { - readonly float _letterSpacing; - - public LetterSpacingSpan(double letterSpacing) - { - _letterSpacing = (float)letterSpacing; - } - - public override void UpdateDrawState(TextPaint? tp) - { - if (tp != null) - Apply(tp); - } - - public override void UpdateMeasureState(TextPaint p) - { - Apply(p); - } - - void Apply(TextPaint paint) - { - paint.LetterSpacing = _letterSpacing; - } - } - - class LineHeightSpan : Java.Lang.Object, ILineHeightSpan - { - readonly double _relativeLineHeight; - readonly double _originalTop; - - public LineHeightSpan(double relativeLineHeight, double originalTop) - { - _relativeLineHeight = relativeLineHeight; - _originalTop = originalTop; - } - - public void ChooseHeight(Java.Lang.ICharSequence? text, int start, int end, int spanstartv, int lineHeight, Paint.FontMetricsInt? fm) - { - if (fm is null) - return; - - fm.Ascent = (int)(_originalTop * _relativeLineHeight); - } - } } } \ No newline at end of file diff --git a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformFontSpan.java b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformFontSpan.java new file mode 100644 index 000000000000..b567b512be59 --- /dev/null +++ b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformFontSpan.java @@ -0,0 +1,68 @@ +package com.microsoft.maui; + +import android.content.Context; +import android.graphics.Typeface; +import android.text.TextPaint; +import android.text.style.MetricAffectingSpan; +import android.util.TypedValue; + +import androidx.annotation.NonNull; + +/** + * Class for setting letterSpacing, textSize, or typeface on a Span + */ +public class PlatformFontSpan extends MetricAffectingSpan { + // NOTE: java.lang.Float is a "nullable" float + private Float letterSpacing; + private Float textSize; + private Typeface typeface; + + /** + * Constructor for setting letterSpacing-only + * @param letterSpacing + */ + public PlatformFontSpan(float letterSpacing) { + this.letterSpacing = letterSpacing; + } + + /** + * Constructor for setting typeface and computing textSize + * @param context + * @param typeface + * @param autoScalingEnabled + * @param fontSize + */ + public PlatformFontSpan(@NonNull Context context, Typeface typeface, boolean autoScalingEnabled, float fontSize) { + this.typeface = typeface; + textSize = TypedValue.applyDimension( + autoScalingEnabled ? TypedValue.COMPLEX_UNIT_SP : TypedValue.COMPLEX_UNIT_DIP, + fontSize, + context.getResources().getDisplayMetrics() + ); + } + + @Override + public void updateDrawState(TextPaint textPaint) { + if (textPaint != null) { + apply(textPaint); + } + } + + @Override + public void updateMeasureState(@NonNull TextPaint textPaint) { + apply(textPaint); + } + + void apply(TextPaint textPaint) + { + if (typeface != null) { + textPaint.setTypeface(typeface); + } + if (textSize != null) { + textPaint.setTextSize(textSize); + } + if (letterSpacing != null) { + textPaint.setLetterSpacing(letterSpacing); + } + } +} diff --git a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java index 4964a8d8f9d7..f48ba1ed19f6 100644 --- a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java +++ b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformInterop.java @@ -598,7 +598,7 @@ public static Rect getCurrentWindowMetrics(Activity activity) { * @param defaultFontSize * @return FontMetrics object or null if context or display metrics is null */ - public static Paint.FontMetrics getFontMetrics(Context context, double defaultFontSize) { + public static Paint.FontMetrics getFontMetrics(Context context, float defaultFontSize) { if (context == null) return null; @@ -608,7 +608,7 @@ public static Paint.FontMetrics getFontMetrics(Context context, double defaultFo setTextSize( TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, - (float) defaultFontSize, + defaultFontSize, metrics )); }}.getFontMetrics(); diff --git a/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformLineHeightSpan.java b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformLineHeightSpan.java new file mode 100644 index 000000000000..e918b99cab20 --- /dev/null +++ b/src/Core/AndroidNative/maui/src/main/java/com/microsoft/maui/PlatformLineHeightSpan.java @@ -0,0 +1,27 @@ +package com.microsoft.maui; + +import android.content.Context; +import android.graphics.Paint; +import android.text.style.LineHeightSpan; + +/** + * Class for setting a relativeLineHeight on a Span + */ +public class PlatformLineHeightSpan implements LineHeightSpan { + private final float relativeLineHeight; + private final Float top; //NOTE: nullable float + + public PlatformLineHeightSpan(Context context, float relativeLineHeight, float defaultFontSize) { + this.relativeLineHeight = relativeLineHeight; + Paint.FontMetrics fontMetrics = PlatformInterop.getFontMetrics(context, defaultFontSize); + this.top = fontMetrics != null ? fontMetrics.top : null; + } + + @Override + public void chooseHeight(CharSequence charSequence, int i, int i1, int i2, int i3, Paint.FontMetricsInt fontMetricsInt) { + if (fontMetricsInt != null) { + float top = this.top != null ? this.top : fontMetricsInt.top; + fontMetricsInt.ascent = (int)(top * relativeLineHeight); + } + } +} diff --git a/src/Core/src/maui.aar b/src/Core/src/maui.aar index f4b333f0989cabc732fbdcea770a016feb293d3b..db2ec6ebb444a14116fbf9edb633f04742e1ce63 100644 GIT binary patch delta 46114 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�=@&eN@5w=i%q}g_iWnF;cOvc&Tuqr;_({oW%Y&O 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 K28UMx0000I2hfZF delta 44123 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 From 285290320b81bcf1e3e9ee5a30b6897324bc7060 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Tue, 9 Apr 2024 10:07:28 -0500 Subject: [PATCH 03/17] Update GitInfo.txt to 8.0.21-preview (#21729) --- GitInfo.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GitInfo.txt b/GitInfo.txt index e88c611d044b..af43b6a99c8e 100644 --- a/GitInfo.txt +++ b/GitInfo.txt @@ -1 +1 @@ -8.0.20-preview +8.0.21-preview From e40e7a855be49f4bf4d1048cb264250685469750 Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Wed, 10 Apr 2024 00:14:59 -0500 Subject: [PATCH 04/17] Light up HideSoftInputOnTappedChanged for catalyst (#21529) * Light up HideSoftInputOnTappedChanged for catalyst * Update HideSoftInputOnTappedPageTests.cs * - add back * - switch to reset * - fix up focus to work for catalyst --- ...oftInputOnTappedChangedManager.Platform.cs | 5 +- .../HideSoftInputOnTappedChangedManager.cs | 2 +- .../Issues/HideSoftInputOnTappedPageTests.cs | 81 ++++++++++++++++++- .../src/UITest.Appium/HelperExtensions.cs | 10 +++ 4 files changed, 94 insertions(+), 4 deletions(-) diff --git a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.Platform.cs b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.Platform.cs index acb16c53d70c..b5ed8c838a64 100644 --- a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.Platform.cs +++ b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.Platform.cs @@ -1,4 +1,7 @@ -#if ANDROID || (IOS && !MACCATALYST) +// This behavior isn't lit up for WinUI because it's never been supported on WinUI, event in Xamarin.Forms +// The primary purpose of this API is for XF migration purposes. +// Ideally users would use behavior that's more accessible forward and consistent with platform expectations. +#if ANDROID || IOS using System; using System.Collections.Generic; diff --git a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.cs b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.cs index 52b3298eb1e8..1f369165f5f8 100644 --- a/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.cs +++ b/src/Controls/src/Core/ContentPage/HideSoftInputOnTappedChanged/HideSoftInputOnTappedChangedManager.cs @@ -20,7 +20,7 @@ bool FeatureEnabled } } -#if !(ANDROID || (IOS && !MACCATALYST)) +#if !(ANDROID || IOS) internal void UpdateFocusForView(InputView iv) { diff --git a/src/Controls/tests/UITests/Tests/Issues/HideSoftInputOnTappedPageTests.cs b/src/Controls/tests/UITests/Tests/Issues/HideSoftInputOnTappedPageTests.cs index 590e1c2338f1..9c97b506508f 100644 --- a/src/Controls/tests/UITests/Tests/Issues/HideSoftInputOnTappedPageTests.cs +++ b/src/Controls/tests/UITests/Tests/Issues/HideSoftInputOnTappedPageTests.cs @@ -20,9 +20,46 @@ public void HideSoftInputOnTappedPageTest(string control, bool hideOnTapped) { this.IgnoreIfPlatforms(new[] { - TestDevice.Mac, TestDevice.Windows + TestDevice.Windows }); + + App.WaitForElement("HideSoftInputOnTappedTrue"); + if (this.Device == TestDevice.Mac) + { + HideSoftInputOnTappedPageTestForMac(control, hideOnTapped); + } + else + { + HideSoftInputOnTappedPageTestForAndroidiOS(control, hideOnTapped); + } + } + + void HideSoftInputOnTappedPageTestForMac(string control, bool hideOnTapped) + { + try + { + if (hideOnTapped) + App.Click("HideSoftInputOnTappedTrue"); + else + App.Click("HideSoftInputOnTappedFalse"); + + App.WaitForElement(control); + App.Click(control); + + Assert.IsTrue(App.IsFocused(control)); + + App.Click("EmptySpace"); + Assert.AreEqual(!hideOnTapped, App.IsFocused(control)); + } + finally + { + this.Back(); + } + } + + void HideSoftInputOnTappedPageTestForAndroidiOS(string control, bool hideOnTapped) + { try { if (App.IsKeyboardShown()) @@ -52,9 +89,49 @@ public void TogglingHideSoftInputOnTapped() { this.IgnoreIfPlatforms(new[] { - TestDevice.Mac, TestDevice.Windows + TestDevice.Windows }); + + App.WaitForElement("HideSoftInputOnTappedFalse"); + + if (this.Device == TestDevice.Mac) + { + TogglingHideSoftInputOnTappedForMac(); + } + else + { + TogglingHideSoftInputOnTappedForAndroidiOS(); + } + } + + public void TogglingHideSoftInputOnTappedForMac() + { + try + { + App.Click("HideSoftInputOnTappedFalse"); + // Switch between enabling/disabling feature + for (int i = 0; i < 2; i++) + { + App.Click("HideKeyboardWhenTappingPage"); + Assert.True(App.IsFocused("HideKeyboardWhenTappingPage")); + App.Click("EmptySpace"); + Assert.AreEqual(false, App.IsFocused("HideKeyboardWhenTappingPage")); + + App.Click("DontHideKeyboardWhenTappingPage"); + Assert.True(App.IsFocused("DontHideKeyboardWhenTappingPage")); + App.Click("EmptySpace"); + Assert.AreEqual(true, App.IsFocused("DontHideKeyboardWhenTappingPage")); + } + } + finally + { + this.Back(); + } + } + + public void TogglingHideSoftInputOnTappedForAndroidiOS() + { try { if (App.IsKeyboardShown()) diff --git a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs index 37f9663f0719..b0e8e2f4db5d 100644 --- a/src/TestUtils/src/UITest.Appium/HelperExtensions.cs +++ b/src/TestUtils/src/UITest.Appium/HelperExtensions.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using System.Diagnostics; using System.Drawing; +using OpenQA.Selenium.Appium; using OpenQA.Selenium.Appium.Interfaces; using UITest.Core; @@ -603,6 +604,15 @@ public static bool IsFocused(this IApp app, string id) var activeElement = aaa.Driver.SwitchTo().ActiveElement(); var element = (AppiumDriverElement)app.WaitForElement(id); + if (app.GetTestDevice() == TestDevice.Mac && activeElement is AppiumElement activeAppiumElement) + { + // For some reason on catalyst the ActiveElement returns an AppiumElement with a different id + // The TagName (AutomationId) and the location all match, so, other than the Id it walks and talks + // like the same element + return element.AppiumElement.TagName.Equals(activeAppiumElement.TagName, StringComparison.OrdinalIgnoreCase) && + element.AppiumElement.Location.Equals(activeAppiumElement.Location); + } + return element.AppiumElement.Equals(activeElement); } From 21a3b728345b866845c608df5857a0db7f402e91 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Wed, 10 Apr 2024 22:02:52 +0200 Subject: [PATCH 05/17] Init the flex item before adding it to the layout (#21737) * Init the flex item before adding it to the layout Fixes #21711 In some cases, adding an item before may trigger an update before the add operation is complete. For example, adding a label with HTML text may cause the layout to run while the label is being constructed. To prevent that layout pass from crashing because the flex item is not yet set, we make sure to first set the flex item, and then add it to the layout. Then, when the layout pass runs, the item is ready to be used. This error might not typically appear in normal XAML layouts because the items are first set, and then the entire page is inflated. However, if the layout is part of a CollectionView or items are added dynamically after the UI is loaded, this layout during add may occur. * This too * UI tests * AutomationId is important :) --- .../Issues/Issue21711.cs | 94 +++++++++++++++++++ src/Controls/src/Core/Layout/FlexLayout.cs | 28 +++--- .../tests/UITests/Tests/Issues/Issue21711.cs | 57 +++++++++++ 3 files changed, 163 insertions(+), 16 deletions(-) create mode 100644 src/Controls/samples/Controls.Sample.UITests/Issues/Issue21711.cs create mode 100644 src/Controls/tests/UITests/Tests/Issues/Issue21711.cs diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21711.cs b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21711.cs new file mode 100644 index 000000000000..d1a12727c2d8 --- /dev/null +++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue21711.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Maui; +using Microsoft.Maui.Controls; + +namespace Maui.Controls.Sample.Issues +{ + [Issue(IssueTracker.Github, 21711, "NullReferenceException from FlexLayout.InitItemProperties", PlatformAffected.iOS)] + public class Issue21711 : TestContentPage + { + protected override void Init() + { + FlexLayout flex = null!; + Content = new VerticalStackLayout + { + new Button + { + Text = "Add", + AutomationId = "Add", + Command = new Command(() => + { + flex.Clear(); + flex.Add(NewLabel(0)); + flex.Add(NewLabel(1)); + + flex.Clear(); + flex.Add(NewLabel(2)); + flex.Add(NewLabel(3)); + }) + }, + new Button + { + Text = "Insert", + AutomationId = "Insert", + Command = new Command(() => + { + flex.Clear(); + flex.Insert(0, NewLabel(1)); + flex.Insert(0, NewLabel(0)); + + flex.Clear(); + flex.Insert(0, NewLabel(3)); + flex.Insert(0, NewLabel(2)); + }) + }, + new Button + { + Text = "Update", + AutomationId = "Update", + Command = new Command(() => + { + flex.Clear(); + flex.Add(NewLabel(0)); + flex[0] = NewLabel(1); + + flex.Clear(); + flex.Add(NewLabel(2)); + flex[0] = NewLabel(3); + }) + }, + new Button + { + Text = "Remove", + AutomationId = "Remove", + Command = new Command(() => + { + flex.Clear(); + var label = NewLabel(0); + flex.Add(label); + flex.Remove(label); + + flex.Clear(); + label = NewLabel(1); + flex.Add(label); + flex.Remove(label); + + flex.Add(NewLabel(2)); + }) + }, + (flex = new FlexLayout { }), + }; + } + + Label NewLabel(int count) => + new Label + { + Text = $"Item{count}", + AutomationId = $"Item{count}", + Background = Brush.Yellow, + TextType = TextType.Html + }; + } +} \ No newline at end of file diff --git a/src/Controls/src/Core/Layout/FlexLayout.cs b/src/Controls/src/Core/Layout/FlexLayout.cs index b0084a5d73de..235c6dd5917a 100644 --- a/src/Controls/src/Core/Layout/FlexLayout.cs +++ b/src/Controls/src/Core/Layout/FlexLayout.cs @@ -479,7 +479,7 @@ void InitItemProperties(IView view, Flex.Item item) internal bool InMeasureMode { get; set; } - void AddFlexItem(IView child) + void AddFlexItem(int index, IView child) { if (_root == null) return; @@ -518,7 +518,7 @@ void AddFlexItem(IView child) }; } - _root.InsertAt(Children.IndexOf(child), item); + _root.InsertAt(index, item); SetFlexItem(child, item); } @@ -546,14 +546,8 @@ protected override ILayoutManager CreateLayoutManager() return new FlexLayoutManager(this); } - public Graphics.Rect GetFlexFrame(IView view) - { - return view switch - { - BindableObject bo => ((Flex.Item)bo.GetValue(FlexItemProperty)).GetFrame(), - _ => _viewInfo[view].FlexItem.GetFrame(), - }; - } + public Graphics.Rect GetFlexFrame(IView view) => + GetFlexItem(view).GetFrame(); void EnsureFlexItemPropertiesUpdated() { @@ -601,8 +595,10 @@ protected override void OnParentSet() void PopulateLayout() { InitLayoutProperties(_root = new Flex.Item()); - foreach (var child in Children) - AddFlexItem(child); + for (var i = 0; i < Children.Count; i++) + { + AddFlexItem(i, Children[i]); + } } void ClearLayout() @@ -623,21 +619,21 @@ void InitLayoutProperties(Flex.Item item) protected override void OnAdd(int index, IView view) { + AddFlexItem(index, view); base.OnAdd(index, view); - AddFlexItem(view); } protected override void OnInsert(int index, IView view) { + AddFlexItem(index, view); base.OnInsert(index, view); - AddFlexItem(view); } protected override void OnUpdate(int index, IView view, IView oldView) { - base.OnUpdate(index, view, oldView); RemoveFlexItem(oldView); - AddFlexItem(view); + AddFlexItem(index, view); + base.OnUpdate(index, view, oldView); } protected override void OnRemove(int index, IView view) diff --git a/src/Controls/tests/UITests/Tests/Issues/Issue21711.cs b/src/Controls/tests/UITests/Tests/Issues/Issue21711.cs new file mode 100644 index 000000000000..d3fc4323f6b6 --- /dev/null +++ b/src/Controls/tests/UITests/Tests/Issues/Issue21711.cs @@ -0,0 +1,57 @@ +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.AppiumTests.Issues +{ + public class Issue21711 : _IssuesUITest + { + public Issue21711(TestDevice device) : base(device) + { + } + + public override string Issue => "NullReferenceException from FlexLayout.InitItemProperties"; + + [Test] + public void AddDoesNotCrash() + { + App.WaitForElement("Add"); + + App.Click("Add"); + + App.WaitForElement("Item2"); + App.WaitForElement("Item3"); + } + + [Test] + public void InsertDoesNotCrash() + { + App.WaitForElement("Insert"); + + App.Click("Insert"); + + App.WaitForElement("Item2"); + App.WaitForElement("Item3"); + } + + [Test] + public void UpdateDoesNotCrash() + { + App.WaitForElement("Update"); + + App.Click("Update"); + + App.WaitForElement("Item3"); + } + + [Test] + public void RemoveDoesNotCrash() + { + App.WaitForElement("Remove"); + + App.Click("Remove"); + + App.WaitForElement("Item2"); + } + } +} From cd65268e77aac028e444f7e6c76005bc59adeee1 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 11 Apr 2024 03:32:30 +0200 Subject: [PATCH 06/17] Use the path for determining the extension (#21761) --- .../UriImageSourceService.iOS.cs | 12 ++++++--- .../UriImageSourceServiceTests.iOS.cs | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.iOS.cs b/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.iOS.cs index 1a2eb11f8829..e561e0f77741 100644 --- a/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.iOS.cs +++ b/src/Core/src/ImageSources/UriImageSourceService/UriImageSourceService.iOS.cs @@ -47,9 +47,7 @@ internal async Task DownloadAndCacheImageAsync(IUriImageSource imageSour { // TODO: use a real caching library with the URI - var hash = Crc64.ComputeHashString(imageSource.Uri.OriginalString); - var ext = Path.GetExtension(imageSource.Uri.OriginalString); - var filename = $"{hash}{ext}"; + var filename = GetCachedFileName(imageSource); var pathToImageCache = Path.Combine(CacheDirectory, filename); NSData? imageData; @@ -117,6 +115,14 @@ public NSData GetCachedImage(string path) return imageData; } + + internal string GetCachedFileName(IUriImageSource imageSource) + { + var hash = Crc64.ComputeHashString(imageSource.Uri.OriginalString); + var ext = Path.GetExtension(imageSource.Uri.AbsolutePath); + var filename = $"{hash}{ext}"; + return filename; + } #pragma warning restore CA1822 // Mark members as static } } diff --git a/src/Core/tests/DeviceTests/Services/ImageSource/UriImageSourceServiceTests.iOS.cs b/src/Core/tests/DeviceTests/Services/ImageSource/UriImageSourceServiceTests.iOS.cs index c36535c281fd..d1904e1cb032 100644 --- a/src/Core/tests/DeviceTests/Services/ImageSource/UriImageSourceServiceTests.iOS.cs +++ b/src/Core/tests/DeviceTests/Services/ImageSource/UriImageSourceServiceTests.iOS.cs @@ -19,5 +19,31 @@ public async Task ThrowsForIncorrectTypes(Type type) await Assert.ThrowsAsync(() => service.GetImageAsync(imageSource)); } + + [Theory] + [InlineData("https://test.com/file", "{hash}")] + [InlineData("https://test.com/file#test", "{hash}")] + [InlineData("https://test.com/file#test=123", "{hash}")] + [InlineData("https://test.com/file?test", "{hash}")] + [InlineData("https://test.com/file?test=123", "{hash}")] + [InlineData("https://test.com/file.png", "{hash}.png")] + [InlineData("https://test.com/file.jpg", "{hash}.jpg")] + [InlineData("https://test.com/file.gif", "{hash}.gif")] + [InlineData("https://test.com/file.jpg?ids", "{hash}.jpg")] + [InlineData("https://test.com/file.jpg?id=123", "{hash}.jpg")] + [InlineData("https://test.com/file.gif#id=123", "{hash}.gif")] + [InlineData("https://test.com/file.gif#ids", "{hash}.gif")] + public void CachedFilenameIsCorrectAndValid(string uri, string expected) + { + using var algorithm = new Crc64HashAlgorithm(); + var hashed = algorithm.ComputeHashString(uri); + expected = expected.Replace("{hash}", hashed, StringComparison.OrdinalIgnoreCase); + + var service = new UriImageSourceService(); + + var filename = service.GetCachedFileName(new UriImageSourceStub { Uri = new Uri(uri) }); + + Assert.Equal(expected, filename); + } } } \ No newline at end of file From 478f174e14470168bd6c322f39959279d9b360f1 Mon Sep 17 00:00:00 2001 From: Rui Marinho Date: Thu, 11 Apr 2024 12:48:38 +0100 Subject: [PATCH 07/17] [Catalyst,Windows] Allow drag item from outside the app (#21684) * [Catalyst] Allow drag item from outside the app * [Windows]Allow DropEvent to work from outside drag * [samples] Add sample for drop to OS * [sample] Small cleanup * Update DropFileToMauiApp.xaml.cs --------- Co-authored-by: Rui Marinho --- .../Controls.Sample.Sandbox/MauiProgram.cs | 2 + .../Pages/Core/DropFileToMauiApp.xaml | 15 +++ .../Pages/Core/DropFileToMauiApp.xaml.cs | 109 ++++++++++++++++++ .../ViewModels/GesturesViewModel.cs | 2 + .../GesturePlatformManager.Windows.cs | 5 +- .../Core/Platform/iOS/DragAndDropDelegate.cs | 13 +-- 6 files changed, 135 insertions(+), 11 deletions(-) create mode 100644 src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml create mode 100644 src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml.cs diff --git a/src/Controls/samples/Controls.Sample.Sandbox/MauiProgram.cs b/src/Controls/samples/Controls.Sample.Sandbox/MauiProgram.cs index c4082431bc46..3472acaffa8f 100644 --- a/src/Controls/samples/Controls.Sample.Sandbox/MauiProgram.cs +++ b/src/Controls/samples/Controls.Sample.Sandbox/MauiProgram.cs @@ -10,7 +10,9 @@ public static class MauiProgram public static MauiApp CreateMauiApp() => MauiApp .CreateBuilder() +#if __ANDROID__ || __IOS__ .UseMauiMaps() +#endif .UseMauiApp() .Build(); } diff --git a/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml b/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml new file mode 100644 index 000000000000..24fb33b2f00f --- /dev/null +++ b/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml.cs b/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml.cs new file mode 100644 index 000000000000..f012ae60c479 --- /dev/null +++ b/src/Controls/samples/Controls.Sample/Pages/Core/DropFileToMauiApp.xaml.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Maui; +using Microsoft.Maui.Controls; +using Microsoft.Maui.Graphics; + +#if WINDOWS +using Windows.ApplicationModel.DataTransfer; +using Windows.Storage; +#endif + +#if IOS || MACCATALYST +using UIKit; +using Foundation; +#endif + +namespace Maui.Controls.Sample.Pages +{ + public partial class DropFileToMauiApp + { + + public DropFileToMauiApp() + { + InitializeComponent(); + } + + void DropGestureDragLeave(object? sender, DragEventArgs e) + { + + } + + async void DropGestureDrop(object? sender, DropEventArgs e) + { + var filePaths = new List(); + +#if WINDOWS + if (e.PlatformArgs is not null && e.PlatformArgs.DragEventArgs.DataView.Contains(StandardDataFormats.StorageItems)) + { + var items = await e.PlatformArgs.DragEventArgs.DataView.GetStorageItemsAsync(); + if (items.Any()) + { + foreach (var item in items) + { + if (item is StorageFile file) + { + filePaths.Add(item.Path); + } + } + + } + } +#elif MACCATALYST + + var session = e.PlatformArgs?.DropSession; + if (session == null) + { + return; + } + foreach (UIDragItem item in session.Items) + { + var result = await LoadItemAsync(item.ItemProvider, item.ItemProvider.RegisteredTypeIdentifiers.ToList()); + if (result is not null) + { + filePaths.Add(result.FileUrl?.Path!); + } + } + foreach (var item in filePaths) + { + Debug.WriteLine($"Path: {item}"); + } + + static async Task LoadItemAsync(NSItemProvider itemProvider, List typeIdentifiers) + { + if (typeIdentifiers is null || typeIdentifiers.Count == 0) + { + return null; + } + + var typeIdent = typeIdentifiers.First(); + + if (itemProvider.HasItemConformingTo(typeIdent)) + { + return await itemProvider.LoadInPlaceFileRepresentationAsync(typeIdent); + } + + typeIdentifiers.Remove(typeIdent); + + return await LoadItemAsync(itemProvider, typeIdentifiers); + } +#else + await Task.CompletedTask; +#endif + + lblPath.Text = filePaths.FirstOrDefault(); + } + + void DropGestureDragOver(object? sender, DragEventArgs e) + { + Debug.WriteLine($"Dragging {e.Data?.Text}, {e.Data?.Image}"); + } + + } +} \ No newline at end of file diff --git a/src/Controls/samples/Controls.Sample/ViewModels/GesturesViewModel.cs b/src/Controls/samples/Controls.Sample/ViewModels/GesturesViewModel.cs index 0f9706ff5b26..b11e9270b554 100644 --- a/src/Controls/samples/Controls.Sample/ViewModels/GesturesViewModel.cs +++ b/src/Controls/samples/Controls.Sample/ViewModels/GesturesViewModel.cs @@ -11,6 +11,8 @@ protected override IEnumerable CreateItems() => new[] { new SectionModel(typeof(DragAndDropBetweenLayouts), "Drag And Drop", "Drag and Drop Views."), + new SectionModel(typeof(DropFileToMauiApp), "Drag and Drop file from OS", + "Drop File to App"), new SectionModel(typeof(PanGestureGallery), "Pan Gesture", "Pan Gesture."), new SectionModel(typeof(PinchGestureTestPage), "Pinch Gesture", diff --git a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs index a59ff797e33a..b19e27b47792 100644 --- a/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs +++ b/src/Controls/src/Core/Platform/GestureManager/GesturePlatformManager.Windows.cs @@ -202,10 +202,7 @@ void HandleDrop(object sender, Microsoft.UI.Xaml.DragEventArgs e) element = ve; } - if (datapackage is null) - return; - - var args = new DropEventArgs(datapackage.View, (relativeTo) => GetPosition(relativeTo, e), new PlatformDropEventArgs(sender as UIElement, e)); + var args = new DropEventArgs(datapackage?.View, (relativeTo) => GetPosition(relativeTo, e), new PlatformDropEventArgs(sender as UIElement, e)); SendEventArgs(async rec => { if (!rec.AllowDrop) diff --git a/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs b/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs index 39ddc650ac34..4cf13cde1812 100644 --- a/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs +++ b/src/Controls/src/Core/Platform/iOS/DragAndDropDelegate.cs @@ -90,15 +90,14 @@ public UIDropProposal SessionDidUpdate(UIDropInteraction interaction, IUIDropSes { UIDropOperation operation = UIDropOperation.Cancel; - if (session.LocalDragSession == null) - return new UIDropProposal(operation); - DataPackage package = null; - - if (session.LocalDragSession.Items.Length > 0 && - session.LocalDragSession.Items[0].LocalObject is CustomLocalStateData cdi) + if (session.LocalDragSession != null) { - package = cdi.DataPackage; + if (session.LocalDragSession.Items.Length > 0 && + session.LocalDragSession.Items[0].LocalObject is CustomLocalStateData cdi) + { + package = cdi.DataPackage; + } } var platformArgs = new PlatformDragEventArgs(_viewHandler.PlatformView, interaction, session); From b898d09afb1819c2c5454bcd634664b3fe331f63 Mon Sep 17 00:00:00 2001 From: Jonathan Peppers Date: Thu, 11 Apr 2024 07:50:02 -0400 Subject: [PATCH 08/17] [ios/catalyst] avoid duplicating `UIView.Subviews` arrays (#21765) Context: https://github.com/dotnet/maui/issues/21580 Similar to: https://github.com/dotnet/maui/pull/21308 Recording this app in `dotnet-trace`, I saw: (0.81%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() Where this time is spent in: * `Microsoft.Maui!Microsoft.Maui.Platform.WrapperView` Reviewing the code, it calls `this.Subviews` twice, which would marshal and create two arrays. It then calls `Subviews[0]`. Storing in a local instead will avoid creating the array twice: var subviews = Subviews; if (subviews.Length == 0) return; //... var child = subviews[0]; This improves things a small amount, but is probably worth it: (0.72%) Microsoft.MacCatalyst!UIKit.UIView.get_Subviews() I'll think about making an analyzer for this, but I didn't find any similar cases that appear in `dotnet-trace` at the moment. This doesn't fully solve #21580, but it's a small improvement. --- src/Core/src/Platform/iOS/WrapperView.cs | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Core/src/Platform/iOS/WrapperView.cs b/src/Core/src/Platform/iOS/WrapperView.cs index d2ea8eee8f12..4a287f70c081 100644 --- a/src/Core/src/Platform/iOS/WrapperView.cs +++ b/src/Core/src/Platform/iOS/WrapperView.cs @@ -77,13 +77,14 @@ public override void LayoutSubviews() { base.LayoutSubviews(); - if (Subviews.Length == 0) + var subviews = Subviews; + if (subviews.Length == 0) return; if (_borderView is not null) BringSubviewToFront(_borderView); - var child = Subviews[0]; + var child = subviews[0]; child.Frame = Bounds; @@ -115,10 +116,11 @@ public override void LayoutSubviews() public override CGSize SizeThatFits(CGSize size) { - if (Subviews.Length == 0) + var subviews = Subviews; + if (subviews.Length == 0) return base.SizeThatFits(size); - var child = Subviews[0]; + var child = subviews[0]; // Calling SizeThatFits on an ImageView always returns the image's dimensions, so we need to call the extension method // This also affects ImageButtons @@ -136,10 +138,11 @@ public override CGSize SizeThatFits(CGSize size) internal CGSize SizeThatFitsWrapper(CGSize originalSpec, double virtualViewWidth, double virtualViewHeight) { - if (Subviews.Length == 0) + var subviews = Subviews; + if (subviews.Length == 0) return base.SizeThatFits(originalSpec); - var child = Subviews[0]; + var child = subviews[0]; if (child is UIImageView || (child is UIButton imageButton && imageButton.ImageView?.Image is not null && imageButton.CurrentTitle is null)) { From 5d33bf34163f8f857b117c891cde52b656640e8b Mon Sep 17 00:00:00 2001 From: Shane Neuville Date: Thu, 11 Apr 2024 11:08:44 -0500 Subject: [PATCH 09/17] Move CollectionViewItemsLayoutUpdate to appium (#21767) --- .../src/Issues.Shared/Issue5354.xaml.cs | 1 + .../Issues/Issue5354.xaml | 33 +++++++ .../Issues/Issue5354.xaml.cs | 95 +++++++++++++++++++ .../tests/UITests/Tests/Issues/Issue5354.cs | 45 +++++++++ 4 files changed, 174 insertions(+) create mode 100644 src/Controls/samples/Controls.Sample.UITests/Issues/Issue5354.xaml create mode 100644 src/Controls/samples/Controls.Sample.UITests/Issues/Issue5354.xaml.cs create mode 100644 src/Controls/tests/UITests/Tests/Issues/Issue5354.cs diff --git a/src/Compatibility/ControlGallery/src/Issues.Shared/Issue5354.xaml.cs b/src/Compatibility/ControlGallery/src/Issues.Shared/Issue5354.xaml.cs index 85f9bc9e5bb6..c4dcbb46ae16 100644 --- a/src/Compatibility/ControlGallery/src/Issues.Shared/Issue5354.xaml.cs +++ b/src/Compatibility/ControlGallery/src/Issues.Shared/Issue5354.xaml.cs @@ -76,6 +76,7 @@ void ButtonClicked(object sender, EventArgs e) #if UITEST [Test] [Compatibility.UITests.FailsOnMauiIOS] + [Compatibility.UITests.MovedToAppium] public void CollectionViewItemsLayoutUpdate() { RunningApp.WaitForElement("CollectionView5354"); diff --git a/src/Controls/samples/Controls.Sample.UITests/Issues/Issue5354.xaml b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue5354.xaml new file mode 100644 index 000000000000..3cf3c402e88e --- /dev/null +++ b/src/Controls/samples/Controls.Sample.UITests/Issues/Issue5354.xaml @@ -0,0 +1,33 @@ + + + + + + + + + +