Merge branch '4.8.0' into 5.0.0

This commit is contained in:
Rui Marinho 2020-09-29 11:33:54 +01:00
Родитель 79cc0f49fe 10f1043762
Коммит d825f18ef8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 924E81B5DB553385
10 изменённых файлов: 134 добавлений и 149 удалений

Просмотреть файл

@ -0,0 +1,51 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
#if UITEST
using Xamarin.Forms.Core.UITests;
using Xamarin.UITest;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[Category(UITestCategories.ManualReview)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 12153, "Setting FontFamily to pre-installed fonts on UWP crashes", PlatformAffected.UWP)]
public class Issue12153 : TestContentPage // or TestMasterDetailPage, etc ...
{
protected override void Init()
{
Content = new StackLayout()
{
Children =
{
// Setting the font family to "Tahoma" or any other built-in Windows font would crash on UWP
new Label() { Text = "Four bell icons should be visible below and it shouldn't crash on UWP", FontFamily = "Tahoma", Margin = new Thickness(10), AutomationId = "Success"},
new Label { FontFamily = "FontAwesome", FontSize = 50, TextColor = Color.Black, Text = "\xf0f3" },
new Label { FontFamily = "fa-regular-400.ttf", FontSize = 50, TextColor = Color.Black, Text = "\xf0f3" },
new Image() { Source = new FontImageSource() { FontFamily = "FontAwesome", Glyph = "\xf0f3", Color = Color.Black, Size = 50}, HorizontalOptions = LayoutOptions.Start},
new Image() { Source = new FontImageSource() { FontFamily = "fa-regular-400.ttf", Glyph = "\xf0f3", Color = Color.Black, Size = 50}, HorizontalOptions = LayoutOptions.Start},
new Label() { Text = "This text should be shown using the Lobster font, which is included as an asset", FontFamily = "Lobster-Regular", Margin = new Thickness(10)},
new Label() { Text = "Below a PLAY icon should be visible (if the \"Segoe MDL2 Assets\" font is installed)", Margin = new Thickness(10)},
new Image() { Source = new FontImageSource{Glyph = "\xe102",FontFamily = "Segoe MDL2 Assets", Size = 50, Color = Color.Green}, HorizontalOptions = LayoutOptions.Start },
}
};
}
#if UITEST
[Test]
public void InvalidFontDoesntCauseAppToCrash()
{
RunningApp.WaitForElement("Success");
}
#endif
}
}

Просмотреть файл

@ -10,6 +10,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)CollectionViewGroupTypeIssue.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue12153.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue10324.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Github9536.xaml.cs">
<DependentUpon>Github9536.xaml</DependentUpon>

Просмотреть файл

@ -109,12 +109,27 @@ namespace Xamarin.Forms.Platform.UWP
static string FindFontFamilyName(string fontFile)
{
using (var fontSet = new CanvasFontSet(new Uri(fontFile)))
try
{
if (fontSet.Fonts.Count == 0)
return null;
var fontUri = new Uri(fontFile, UriKind.RelativeOrAbsolute);
return fontSet.GetPropertyValues(CanvasFontPropertyIdentifier.FamilyName).FirstOrDefault().Value;
// CanvasFontSet only supports ms-appx:// and ms-appdata:// font URIs
if (fontUri.IsAbsoluteUri && (fontUri.Scheme == "ms-appx" || fontUri.Scheme == "ms-appdata"))
{
using (var fontSet = new CanvasFontSet(fontUri))
{
if (fontSet.Fonts.Count != 0)
return fontSet.GetPropertyValues(CanvasFontPropertyIdentifier.FamilyName).FirstOrDefault().Value;
}
}
return null;
}
catch(Exception ex)
{
// the CanvasFontSet constructor can throw an exception in case something's wrong with the font. It should not crash the app
Internals.Log.Warning("Font",$"Error loading font {fontFile}: {ex.Message}");
return null;
}
}

Просмотреть файл

@ -23,9 +23,19 @@ namespace Xamarin.Forms.Platform.UWP
var device = CanvasDevice.GetSharedDevice();
var dpi = Math.Max(_minimumDpi, Windows.Graphics.Display.DisplayInformation.GetForCurrentView().LogicalDpi);
// There's really no perfect solution to handle font families with fallbacks (comma-separated)
// So if the font family has fallbacks, only the first one is taken, because CanvasTextFormat
// only supports one font family
var fontFamily = fontsource.FontFamily.ToFontFamily();
var allFamilies = fontFamily.Source.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (allFamilies.Length < 1)
return null;
var textFormat = new CanvasTextFormat
{
FontFamily = fontsource.FontFamily.ToFontFamily().Source,
FontFamily = allFamilies[0],
FontSize = (float)fontsource.Size,
HorizontalAlignment = CanvasHorizontalAlignment.Center,
VerticalAlignment = CanvasVerticalAlignment.Center,
@ -44,7 +54,7 @@ namespace Xamarin.Forms.Platform.UWP
// offset by 1 as we added a 1 inset
var x = (float)layout.DrawBounds.X * -1;
ds.DrawTextLayout(layout, x, 1f, iconcolor);
}
@ -65,10 +75,10 @@ namespace Xamarin.Forms.Platform.UWP
Foreground = fontImageSource.Color.ToBrush()
};
var uwpFontFamily = fontImageSource.FontFamily.ToFontFamily().Source;
var uwpFontFamily = fontImageSource.FontFamily.ToFontFamily();
if (!string.IsNullOrEmpty(uwpFontFamily))
((WFontIconSource)image).FontFamily = new FontFamily(uwpFontFamily);
if (!string.IsNullOrEmpty(uwpFontFamily.Source))
((WFontIconSource)image).FontFamily = uwpFontFamily;
}
return Task.FromResult(image);
@ -87,10 +97,10 @@ namespace Xamarin.Forms.Platform.UWP
Foreground = fontImageSource.Color.ToBrush()
};
var uwpFontFamily = fontImageSource.FontFamily.ToFontFamily().Source;
var uwpFontFamily = fontImageSource.FontFamily.ToFontFamily();
if (!string.IsNullOrEmpty(uwpFontFamily))
((FontIcon)image).FontFamily = new FontFamily(uwpFontFamily);
if (!string.IsNullOrEmpty(uwpFontFamily.Source))
((FontIcon)image).FontFamily = uwpFontFamily;
}
return Task.FromResult(image);

Просмотреть файл

@ -1,102 +0,0 @@
using System;
using Foundation;
using UIKit;
namespace Xamarin.Forms.Platform.iOS
{
internal class PageLifecycleManager : IDisposable, IDisconnectable
{
NSObject _activateObserver;
NSObject _resignObserver;
bool _disposed;
bool _appeared;
IPageController _pageController;
public PageLifecycleManager(IPageController pageController)
{
_pageController = pageController ?? throw new ArgumentNullException("You need to provide a Page Element");
_activateObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.DidBecomeActiveNotification, n =>
{
if (CheckIfWeAreTheCurrentPage())
HandlePageAppearing();
});
_resignObserver = NSNotificationCenter.DefaultCenter.AddObserver(UIApplication.WillResignActiveNotification, n =>
{
if (CheckIfWeAreTheCurrentPage())
HandlePageDisappearing();
});
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
(this as IDisconnectable).Disconnect();
}
_disposed = true;
}
void IDisconnectable.Disconnect()
{
if (_activateObserver != null)
{
NSNotificationCenter.DefaultCenter.RemoveObserver(_activateObserver);
_activateObserver = null;
}
if (_resignObserver != null)
{
NSNotificationCenter.DefaultCenter.RemoveObserver(_resignObserver);
_resignObserver = null;
}
HandlePageDisappearing();
_pageController = null;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
public void HandlePageAppearing()
{
if (_appeared)
return;
_appeared = true;
_pageController?.SendAppearing();
}
public void HandlePageDisappearing()
{
if (!_appeared || _pageController == null)
return;
_appeared = false;
_pageController.SendDisappearing();
}
public bool Appeared => _appeared;
bool CheckIfWeAreTheCurrentPage()
{
if (_pageController == null)
return false;
if (_pageController.RealParent is IPageContainer<Page> multipage)
return multipage.CurrentPage == _pageController;
return true;
}
}
}

Просмотреть файл

@ -4,7 +4,6 @@ using System.ComponentModel;
using System.Linq;
using System.Threading.Tasks;
using CoreGraphics;
using Foundation;
using UIKit;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
@ -20,6 +19,7 @@ namespace Xamarin.Forms.Platform.iOS
public class NavigationRenderer : UINavigationController, IVisualElementRenderer, IEffectControlProvider
{
internal const string UpdateToolbarButtons = "Xamarin.UpdateToolbarButtons";
bool _appeared;
bool _ignorePopCall;
bool _loaded;
FlyoutPage _parentFlyoutPage;
@ -32,9 +32,8 @@ namespace Xamarin.Forms.Platform.iOS
UIImage _defaultNavBarShadowImage;
UIImage _defaultNavBarBackImage;
bool _disposed;
PageLifecycleManager _pageLifecycleManager;
[Internals.Preserve(Conditional = true)]
[Preserve(Conditional = true)]
public NavigationRenderer() : base(typeof(FormsNavigationBar), null)
{
MessagingCenter.Subscribe<IVisualElementRenderer>(this, UpdateToolbarButtons, sender =>
@ -72,9 +71,8 @@ namespace Xamarin.Forms.Platform.iOS
Element = element;
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
element?.SendViewInitialized(NativeView);
if (element != null)
element.SendViewInitialized(NativeView);
EffectUtilities.RegisterEffectControlProvider(this, oldElement, element);
}
@ -134,7 +132,11 @@ namespace Xamarin.Forms.Platform.iOS
public override void ViewDidAppear(bool animated)
{
_pageLifecycleManager?.HandlePageAppearing();
if (!_appeared)
{
_appeared = true;
PageController?.SendAppearing();
}
base.ViewDidAppear(animated);
@ -152,7 +154,11 @@ namespace Xamarin.Forms.Platform.iOS
{
base.ViewDidDisappear(animated);
_pageLifecycleManager?.HandlePageDisappearing();
if (!_appeared || Element == null)
return;
_appeared = false;
PageController.SendDisappearing();
}
public override void ViewDidLayoutSubviews()
@ -275,12 +281,16 @@ namespace Xamarin.Forms.Platform.iOS
navPage.PopToRootRequested -= OnPopToRootRequested;
navPage.RemovePageRequested -= OnRemovedPageRequested;
navPage.InsertPageBeforeRequested -= OnInsertPageBeforeRequested;
_pageLifecycleManager?.Dispose();
_pageLifecycleManager = null;
}
base.Dispose(disposing);
if (disposing && _appeared)
{
PageController.SendDisappearing();
_appeared = false;
}
}
protected virtual void OnElementChanged(VisualElementChangedEventArgs e)
@ -357,6 +367,7 @@ namespace Xamarin.Forms.Platform.iOS
UpdateBackgroundColor();
}
ParentingViewController CreateViewControllerForPage(Page page)
{
if (Platform.GetRenderer(page) == null)

Просмотреть файл

@ -11,11 +11,11 @@ namespace Xamarin.Forms.Platform.iOS
{
public class PageRenderer : UIViewController, IVisualElementRenderer, IEffectControlProvider, IAccessibilityElementsController, IShellContentInsetObserver, IDisconnectable
{
bool _appeared;
bool _disposed;
EventTracker _events;
VisualElementPackager _packager;
VisualElementTracker _tracker;
PageLifecycleManager _pageLifecycleManager;
// storing this into a local variable causes it to not get collected. Do not delete this please
PageContainer _pageContainer;
@ -111,8 +111,6 @@ namespace Xamarin.Forms.Platform.iOS
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
if (element != null)
{
if (!string.IsNullOrEmpty(element.AutomationId))
@ -189,31 +187,33 @@ namespace Xamarin.Forms.Platform.iOS
{
base.ViewDidAppear(animated);
if (_disposed || Element == null)
if (_appeared || _disposed || Element == null)
return;
_appeared = true;
UpdateStatusBarPrefersHidden();
if (Forms.RespondsToSetNeedsUpdateOfHomeIndicatorAutoHidden)
SetNeedsUpdateOfHomeIndicatorAutoHidden();
if (Element.Parent is CarouselPage)
return;
_pageLifecycleManager?.HandlePageAppearing();
Page.SendAppearing();
}
public override void ViewDidDisappear(bool animated)
{
base.ViewDidDisappear(animated);
if (_disposed || Element == null)
if (!_appeared || _disposed || Element == null)
return;
_appeared = false;
if (Element.Parent is CarouselPage)
return;
_pageLifecycleManager?.HandlePageDisappearing();
Page.SendDisappearing();
}
public override void ViewDidLoad()
@ -264,10 +264,13 @@ namespace Xamarin.Forms.Platform.iOS
{
Element.PropertyChanged -= OnHandlePropertyChanged;
Platform.SetRenderer(Element, null);
if (_appeared)
Page.SendDisappearing();
Element = null;
}
(_pageLifecycleManager as IDisconnectable)?.Disconnect();
_events?.Disconnect();
_packager?.Disconnect();
_tracker?.Disconnect();
@ -282,14 +285,12 @@ namespace Xamarin.Forms.Platform.iOS
{
(this as IDisconnectable).Disconnect();
_pageLifecycleManager?.Dispose();
_events?.Dispose();
_packager?.Dispose();
_tracker?.Dispose();
_events = null;
_packager = null;
_tracker = null;
_pageLifecycleManager = null;
Element = null;
Container?.Dispose();
@ -377,7 +378,7 @@ namespace Xamarin.Forms.Platform.iOS
void UpdateUseSafeArea()
{
if (Element == null || _pageLifecycleManager == null)
if (Element == null)
return;
if (_userOverriddenSafeArea)

Просмотреть файл

@ -23,7 +23,6 @@ namespace Xamarin.Forms.Platform.iOS
bool? _defaultBarTranslucent;
bool _loaded;
Size _queuedSize;
PageLifecycleManager _pageLifecycleManager;
Page Page => Element as Page;
@ -73,8 +72,6 @@ namespace Xamarin.Forms.Platform.iOS
OnElementChanged(new VisualElementChangedEventArgs(oldElement, element));
_pageLifecycleManager = new PageLifecycleManager(Element as IPageController);
OnPagesChanged(null, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
if (element != null)
@ -114,15 +111,14 @@ namespace Xamarin.Forms.Platform.iOS
public override void ViewDidAppear(bool animated)
{
_pageLifecycleManager?.HandlePageAppearing();
Page.SendAppearing();
base.ViewDidAppear(animated);
}
public override void ViewDidDisappear(bool animated)
{
base.ViewDidDisappear(animated);
_pageLifecycleManager?.HandlePageDisappearing();
Page.SendDisappearing();
}
public override void ViewDidLayoutSubviews()
@ -157,8 +153,7 @@ namespace Xamarin.Forms.Platform.iOS
{
if (disposing)
{
_pageLifecycleManager?.Dispose();
_pageLifecycleManager = null;
Page.SendDisappearing();
Tabbed.PropertyChanged -= OnPropertyChanged;
Tabbed.PagesChanged -= OnPagesChanged;
FinishedCustomizingViewControllers -= HandleFinishedCustomizingViewControllers;

Просмотреть файл

@ -303,8 +303,12 @@ namespace Xamarin.Forms.Platform.MacOS
{
if (Control == null)
return;
#if __MOBILE__
focusRequestArgs.Result = focusRequestArgs.Focus ? Control.BecomeFirstResponder() : Control.ResignFirstResponder();
#else
focusRequestArgs.Result = focusRequestArgs.Focus ? Control.Window.MakeFirstResponder(Control) : Control.Window.MakeFirstResponder(null);
#endif
}
}
}

Просмотреть файл

@ -173,7 +173,6 @@
<Compile Include="IOSDeviceInfo.cs" />
<Compile Include="LinkerSafeAttribute.cs" />
<Compile Include="ModalWrapper.cs" />
<Compile Include="PageLifecycleManager.cs" />
<Compile Include="Renderers\FormsCAKeyFrameAnimation.cs" />
<Compile Include="Renderers\FormsCheckBox.cs" />
<Compile Include="Renderers\FormsUIImageView.cs" />
@ -326,4 +325,4 @@
<Name>Xamarin.Forms.Core</Name>
</ProjectReference>
</ItemGroup>
</Project>
</Project>