Skip to content

Commit

Permalink
fix: Ensure app is started after native WPF template is applied
Browse files Browse the repository at this point in the history
If the initial page of the application has an input field as the first focusable element, an exception would occur, as the native overlay layer was not initialized yet. Moving app startup after WPF's OnApplyTemplate ensures that this condition does not occur.
  • Loading branch information
MartinZikmund committed May 30, 2022
1 parent 37323c2 commit 08b3e0e
Showing 1 changed file with 25 additions and 9 deletions.
34 changes: 25 additions & 9 deletions src/Uno.UI.Runtime.Skia.Wpf/WpfHost.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,10 @@ public class WpfHost : WpfControl, WinUI.ISkiaHost
private const string NativeOverlayLayerPart = "NativeOverlayLayer";

private readonly bool designMode;

private readonly Func<UnoApplication> _appBuilder;

private bool _appStarted = false;

[ThreadStatic] private static WpfHost _current;

private WpfCanvas? _nativeOverlayLayer = null;
Expand Down Expand Up @@ -99,20 +102,13 @@ public WpfHost(global::System.Windows.Threading.Dispatcher dispatcher, Func<WinU
public WpfHost(global::System.Windows.Threading.Dispatcher dispatcher, Func<WinUI.Application> appBuilder)
{
_current = this;
_appBuilder = appBuilder;

designMode = DesignerProperties.GetIsInDesignMode(this);

void CreateApp(WinUI.ApplicationInitializationCallbackParams _)
{
var app = appBuilder();
app.Host = this;
}

Windows.UI.Core.CoreDispatcher.DispatchOverride = d => dispatcher.BeginInvoke(d);
Windows.UI.Core.CoreDispatcher.HasThreadAccessOverride = dispatcher.CheckAccess;

WinUI.Application.StartWithArguments(CreateApp);

WinUI.Window.InvalidateRender += () =>
{
InvalidateOverlays();
Expand Down Expand Up @@ -156,6 +152,26 @@ public override void OnApplyTemplate()
base.OnApplyTemplate();

_nativeOverlayLayer = GetTemplateChild(NativeOverlayLayerPart) as WpfCanvas;

// App needs to be created after the native overlay layer is properly initialized
// otherwise the initially focused input element would cause exception.
StartApp();
}

private void StartApp()
{
if (_appStarted)
{
return;
}

void CreateApp(WinUI.ApplicationInitializationCallbackParams _)
{
var app = _appBuilder();
app.Host = this;
}

WinUI.Application.StartWithArguments(CreateApp);
}

private void MainWindow_StateChanged(object? sender, EventArgs e)
Expand Down

0 comments on commit 08b3e0e

Please sign in to comment.