Skip to content

Commit

Permalink
fix: Make Uno islands ContentIsland compatible with smooth resize
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinZikmund committed Apr 22, 2024
1 parent bb33731 commit 57454d0
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 25 deletions.
31 changes: 16 additions & 15 deletions src/Uno.UI.XamlHost.Skia.Wpf/UnoXamlHostBase.Layout.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@

using System;
using System.Windows;
using Microsoft.UI.Xaml.Hosting;
using Uno.UI.XamlHost.Extensions;
using Windows.Security.Cryptography.Certificates;
using WUX = Microsoft.UI.Xaml;

namespace Uno.UI.XamlHost.Skia.Wpf
Expand Down Expand Up @@ -46,6 +48,7 @@ protected override Size ArrangeOverride(Size finalSize)
{
if (IsXamlContentLoaded())
{
UpdateUnoSize(finalSize);
// Arrange is required to support HorizontalAlignment and VerticalAlignment properties
// set to 'Stretch'. The UWP XAML content will be 0 in the stretch alignment direction
// until Arrange is called, and the UWP XAML content is expanded to fill the available space.
Expand All @@ -62,18 +65,18 @@ protected override Size ArrangeOverride(Size finalSize)
/// <returns>True if the Xaml content is properly loaded</returns>
private bool IsXamlContentLoaded()
{
if (_xamlSource.Content == null)
if (_xamlSource.Content is null ||
!(_xamlSource.XamlIsland.IsLoading || _xamlSource.XamlIsland.IsLoaded))
{
return false;
}

//TODO: What should be the parent? https://github.com/unoplatform/uno/issues/8978
//if (WUX.Media.VisualTreeHelper.GetParent(_xamlSource.Content) == null)
//{
// // If there's no parent to this content, it's not "live" or "loaded" in the tree yet.
// // Performing a measure or arrange in this state may cause unexpected results.
// return false;
//}
if (WUX.Media.VisualTreeHelper.GetParent(_xamlSource.Content) is null)
{
// If there's no parent to this content, it's not "live" or "loaded" in the tree yet.
// Performing a measure or arrange in this state may cause unexpected results.
return false;
}

return true;
}
Expand All @@ -90,21 +93,19 @@ private void XamlContentSizeChanged(object sender, WUX.SizeChangedEventArgs e)

private void OnSizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
{
UpdateUnoSize();
UpdateUnoSize(e.NewSize);
}

//TODO: This is temporary workaround, should not be needed as per UWP islands. https://github.com/unoplatform/uno/issues/8978
//Might be some missing logic. Maybe not needed now after Arrange and Measure works with XamlIslandRoot
private void UpdateUnoSize()
private void UpdateUnoSize(Size newSize)
{
if (IsXamlContentLoaded())
{
if (_xamlSource.GetVisualTreeRoot() is WUX.FrameworkElement element)
if (_xamlSource?.XamlIsland is { } island)
{
var width = ActualWidth;
var height = ActualHeight;
element.Width = width;
element.Height = height;
island.Width = newSize.Width;
island.Height = newSize.Height;
}
}
}
Expand Down
12 changes: 9 additions & 3 deletions src/Uno.UI.XamlHost.Skia.Wpf/UnoXamlHostBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using WpfControl = global::System.Windows.Controls.Control;
using WUX = Microsoft.UI.Xaml;
using Uno.UI.Xaml.Controls;
using Microsoft.UI.Content;

namespace Uno.UI.XamlHost.Skia.Wpf
{
Expand Down Expand Up @@ -249,8 +250,6 @@ protected WUX.UIElement ChildInternal

// Fire updated event
ChildChanged?.Invoke(this, new EventArgs());

UpdateUnoSize();
}
}

Expand Down Expand Up @@ -282,6 +281,7 @@ public object GetUwpInternalObject()
public bool IsDisposed { get; private set; }

private System.Windows.Window _parentWindow;
private ContentIsland _contentIsland;

// /// <summary>
// /// Creates <see cref="WUX.Application" /> object, wrapped <see cref="WUX.Hosting.DesktopWindowXamlSource" /> instance; creates and
Expand Down Expand Up @@ -325,7 +325,12 @@ protected virtual void SetContent()
if (_xamlSource != null)
{
_xamlSource.Content = _childInternal;
_xamlSource.XamlIsland.IsSiteVisible = true;
_contentIsland ??= new ContentIsland(_contentSite.View);
_xamlSource.XamlIsland.XamlRoot.VisualTree.ContentRoot.SetContentIsland(_contentIsland);

UpdateContentSiteVisible();
UpdateContentSiteScale();

TryLoadContent();
}
}
Expand All @@ -336,6 +341,7 @@ protected void TryLoadContent()
if (IsLoaded && _childInternal.XamlRoot is not null)
{
ContentManager.TryLoadRootVisual(_xamlSource.XamlIsland.XamlRoot);
InvalidateMeasure();
}
}

Expand Down
64 changes: 57 additions & 7 deletions src/Uno.UI.XamlHost.Skia.Wpf/UnoXamlHostBase.host.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
#nullable enable

using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using WinUI = Microsoft.UI.Xaml;
using WpfCanvas = global::System.Windows.Controls.Canvas;
using Uno.UI.Runtime.Skia.Wpf.Rendering;
using Uno.UI.XamlHost.Extensions;
using Uno.UI.Runtime.Skia.Wpf.Hosting;
using Uno.UI.Runtime.Skia.Wpf.Extensions;
using Microsoft.UI.Content;
using Uno.UI.Hosting;
using Uno.UI.Runtime.Skia.Wpf;
using Microsoft.UI.Content;
using Uno.UI.Runtime.Skia.Wpf.Extensions;
using Uno.UI.Runtime.Skia.Wpf.Hosting;
using Uno.UI.Runtime.Skia.Wpf.Rendering;
using Uno.UI.XamlHost.Extensions;
using WinUI = Microsoft.UI.Xaml;
using WpfCanvas = global::System.Windows.Controls.Canvas;
using WpfWindow = global::System.Windows.Window;

namespace Uno.UI.XamlHost.Skia.Wpf;

Expand All @@ -24,6 +26,8 @@ partial class UnoXamlHostBase : IWpfXamlRootHost
private WpfCanvas _nativeOverlayLayer;
private IWpfRenderer _renderer;
private Microsoft.UI.Xaml.UIElement? _rootElement;
private ContentSite _contentSite;
private WpfWindow? _window;

/// <summary>
/// Gets or sets the current Skia Render surface type.
Expand All @@ -43,11 +47,52 @@ public bool IgnorePixelScaling

private void InitializeHost()
{
_contentSite ??= new ContentSite();

this.IsVisibleChanged += (s, e) =>
{
UpdateContentSiteVisible();
};
this.Loaded += (s, e) =>
{
_window = WpfWindow.GetWindow(this);

if (_window is not null)
{
_window.DpiChanged += OnWindowDpiChanged;
}
};

this.Unloaded += (s, e) =>
{
if (_window is null)
{
return;
}

_window.DpiChanged -= OnWindowDpiChanged;
_window = null;
};

WpfExtensionsRegistrar.Register();

_designMode = DesignerProperties.GetIsInDesignMode(this);
}

private void UpdateContentSiteVisible()
{
_contentSite.IsSiteVisible = IsLoaded && IsVisible;
RaiseContentIslandStateChanged(ContentIslandStateChangedEventArgs.SiteVisibleChange);
}

private void OnWindowDpiChanged(object sender, DpiChangedEventArgs e) => UpdateContentSiteScale();

private void UpdateContentSiteScale()
{
_contentSite.ParentScale = (float)VisualTreeHelper.GetDpi(this).DpiScaleX;
RaiseContentIslandStateChanged(ContentIslandStateChangedEventArgs.RasterizationScaleChange);
}

protected override void OnRender(DrawingContext drawingContext)
{
base.OnRender(drawingContext);
Expand Down Expand Up @@ -78,4 +123,9 @@ void IXamlRootHost.InvalidateRender()
bool IWpfXamlRootHost.IgnorePixelScaling => IgnorePixelScaling;

RenderSurfaceType? IWpfXamlRootHost.RenderSurfaceType => RenderSurfaceType;

private void RaiseContentIslandStateChanged(ContentIslandStateChangedEventArgs args)
{
_contentIsland?.RaiseStateChanged(args);
}
}

0 comments on commit 57454d0

Please sign in to comment.