From b8b9fd73bc27bf0fc57e071b459a178e3f4ba6a2 Mon Sep 17 00:00:00 2001 From: Martin Zikmund Date: Wed, 21 Aug 2024 19:42:05 +0200 Subject: [PATCH] fix: Ensure Renderer is initialized when Window HWND is already available --- .../UI/Controls/UnoCompositeWindowHost.cs | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/Uno.UI.Runtime.Skia.Wpf/UI/Controls/UnoCompositeWindowHost.cs b/src/Uno.UI.Runtime.Skia.Wpf/UI/Controls/UnoCompositeWindowHost.cs index fd9dec374be3..db686f624f4a 100644 --- a/src/Uno.UI.Runtime.Skia.Wpf/UI/Controls/UnoCompositeWindowHost.cs +++ b/src/Uno.UI.Runtime.Skia.Wpf/UI/Controls/UnoCompositeWindowHost.cs @@ -12,6 +12,7 @@ using WpfCanvas = System.Windows.Controls.Canvas; using WpfContentPresenter = System.Windows.Controls.ContentPresenter; using WpfControl = System.Windows.Controls.Control; +using WpfWindow = System.Windows.Window; using WpfFrameworkPropertyMetadata = System.Windows.FrameworkPropertyMetadata; using MUX = Microsoft.UI.Xaml; @@ -55,7 +56,7 @@ internal class UnoWpfWindowHost : WpfControl, IWpfWindowHost private readonly MUX.Window _winUIWindow; private readonly WpfCanvas _nativeOverlayLayer; - private readonly RenderingLayerHost _renderLayer; + private RenderingLayerHost _renderLayer; private readonly SerialDisposable _backgroundDisposable = new(); @@ -73,20 +74,25 @@ public UnoWpfWindowHost(UnoWpfWindow wpfWindow, MUX.Window winUIWindow) _nativeOverlayLayer = new WpfCanvas(); // Transparency doesn't work with the OpenGL renderer, so we have to use the software renderer for the top layer - _renderLayer = new RenderingLayerHost(WpfRendererProvider.CreateForHost(this)); + _renderLayer = new RenderingLayerHost(); Loaded += WpfHost_Loaded; Unloaded += (_, _) => _backgroundDisposable.Dispose(); - UpdateRendererBackground(); _backgroundDisposable.Disposable = _winUIWindow.RegisterBackgroundChangedEvent((_, _) => UpdateRendererBackground()); } + public WpfWindow Window => _wpfWindow; + public WpfControl RenderLayer => _renderLayer; public WpfControl BottomLayer => _renderLayer; private void WpfHost_Loaded(object _, System.Windows.RoutedEventArgs __) { + _renderLayer.Renderer = WpfRendererProvider.CreateForHost(this); + UpdateRendererBackground(); + _renderLayer.InvalidateVisual(); + // Avoid dotted border on focus. if (Parent is WpfControl control) { @@ -97,6 +103,11 @@ private void WpfHost_Loaded(object _, System.Windows.RoutedEventArgs __) void UpdateRendererBackground() { + if (_renderLayer.Renderer is null) + { + return; + } + // the flyout layer always has a transparent background so that elements underneath can be seen. _renderLayer.Renderer.BackgroundColor = SKColors.Transparent; @@ -142,14 +153,14 @@ void IXamlRootHost.InvalidateRender() RenderSurfaceType? IWpfXamlRootHost.RenderSurfaceType => WpfHost.Current?.RenderSurfaceType ?? null; - private class RenderingLayerHost(IWpfRenderer renderer) : WpfControl + private class RenderingLayerHost : WpfControl { - public IWpfRenderer Renderer { get; } = renderer; + public IWpfRenderer? Renderer { get; set; } protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) { base.OnRender(drawingContext); - Renderer.Render(drawingContext); + Renderer?.Render(drawingContext); } } }