From 09be506b30f326015f9b0e50db04e29d938a5403 Mon Sep 17 00:00:00 2001 From: Elie Bariche <33458222+ebariche@users.noreply.github.com> Date: Wed, 5 Apr 2023 21:11:54 -0400 Subject: [PATCH] feat: Initialize WindowManager asynchronously --- src/Uno.UI/UI/Xaml/Application.wasm.cs | 31 ++++++++++++------ .../UI/Xaml/WindowManagerInterop.wasm.cs | 29 ++++++----------- src/Uno.UI/ts/MonoSupport.ts | 1 - src/Uno.UI/ts/WindowManager.ts | 32 ++++++------------- .../tsBindings/WindowManagerInitParams.ts | 15 --------- 5 files changed, 42 insertions(+), 66 deletions(-) delete mode 100644 src/Uno.UI/tsBindings/WindowManagerInitParams.ts diff --git a/src/Uno.UI/UI/Xaml/Application.wasm.cs b/src/Uno.UI/UI/Xaml/Application.wasm.cs index 4ed2f6135c..9420b59d5a 100644 --- a/src/Uno.UI/UI/Xaml/Application.wasm.cs +++ b/src/Uno.UI/UI/Xaml/Application.wasm.cs @@ -13,6 +13,7 @@ using Uno.Foundation; using Uno.Extensions; using Uno.Foundation.Logging; using System.Threading; +using System.Threading.Tasks; using Uno.UI; using Uno.UI.Xaml; using Uno; @@ -84,19 +85,31 @@ namespace Windows.UI.Xaml return 0; } - static partial void StartPartial(ApplicationInitializationCallback callback) + static async partial void StartPartial(ApplicationInitializationCallback callback) { - _startInvoked = true; + try + { + _startInvoked = true; + + SynchronizationContext.SetSynchronizationContext( + new CoreDispatcherSynchronizationContext(CoreDispatcher.Main, CoreDispatcherPriority.Normal) + ); - var isLoadEventsEnabled = !FeatureConfiguration.FrameworkElement.WasmUseManagedLoadedUnloaded; - WindowManagerInterop.Init(isLoadEventsEnabled); - Windows.Storage.ApplicationData.Init(); + var isLoadEventsEnabled = !FeatureConfiguration.FrameworkElement.WasmUseManagedLoadedUnloaded; - SynchronizationContext.SetSynchronizationContext( - new CoreDispatcherSynchronizationContext(CoreDispatcher.Main, CoreDispatcherPriority.Normal) - ); + await WindowManagerInterop.InitAsync(isLoadEventsEnabled); - callback(new ApplicationInitializationCallbackParams()); + Windows.Storage.ApplicationData.Init(); + + callback(new ApplicationInitializationCallbackParams()); + } + catch (Exception exception) + { + if (typeof(Application).Log().IsEnabled(LogLevel.Error)) + { + typeof(Application).Log().LogError("Application initialization failed.", exception); + } + } } partial void ObserveSystemThemeChanges() diff --git a/src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs b/src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs index 3c50f35a2d..dd59ea00e5 100644 --- a/src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs +++ b/src/Uno.UI/UI/Xaml/WindowManagerInterop.wasm.cs @@ -27,25 +27,13 @@ namespace Uno.UI.Xaml //When users set double.MaxValue to scroll to the end of the page Javascript doesn't scroll. private const double MAX_SCROLLING_OFFSET = 1_000_000_000_000_000_000; - #region Init - internal static void Init(bool isLoadEventsEnabled) - { - var parms = new WindowManagerInitParams - { - IsLoadEventsEnabled = isLoadEventsEnabled - }; - - TSInteropMarshaller.InvokeJS("UnoStatic:initNative", parms); - } - - [TSInteropMessage] - [StructLayout(LayoutKind.Sequential, Pack = 4)] - private struct WindowManagerInitParams - { - public bool IsLoadEventsEnabled; - } - - #endregion + internal static Task InitAsync(bool isLoadEventsEnabled) + => +#if NET7_0_OR_GREATER + NativeMethods.InitAsync(isLoadEventsEnabled); +#else + WebAssemblyRuntime.InvokeAsync($"Uno.UI.WindowManager.init({(isLoadEventsEnabled ? "true" : "false")})"); +#endif internal static string FindLaunchArguments() => @@ -1314,6 +1302,9 @@ namespace Uno.UI.Xaml [JSImport("globalThis.Uno.UI.WindowManager.current.getProperty")] internal static partial string GetProperty(IntPtr htmlId, string name); + [JSImport("globalThis.Uno.UI.WindowManager.init")] + internal static partial Task InitAsync(bool isLoadEventsEnabled); + [JSImport("globalThis.Uno.UI.WindowManager.current.measureViewNativeFast")] internal static partial void MeasureView(IntPtr htmlId, double availableWidth, double availableHeight, bool measureContent, IntPtr pReturn); diff --git a/src/Uno.UI/ts/MonoSupport.ts b/src/Uno.UI/ts/MonoSupport.ts index 828507fc4d..fdf8b7889b 100644 --- a/src/Uno.UI/ts/MonoSupport.ts +++ b/src/Uno.UI/ts/MonoSupport.ts @@ -29,7 +29,6 @@ namespace MonoSupport { } else { if (!jsCallDispatcher._isUnoRegistered) { - jsCallDispatcher.registerScope("UnoStatic", Uno.UI.WindowManager); jsCallDispatcher.registerScope("UnoStatic_Windows_Storage_StorageFolder", Windows.Storage.StorageFolder); jsCallDispatcher.registerScope("UnoStatic_Windows_Storage_ApplicationDataContainer", Windows.Storage.ApplicationDataContainer); jsCallDispatcher.registerScope("UnoStatic_Windows_ApplicationModel_DataTransfer_DragDrop_Core_DragDropExtension", Windows.ApplicationModel.DataTransfer.DragDrop.Core.DragDropExtension); diff --git a/src/Uno.UI/ts/WindowManager.ts b/src/Uno.UI/ts/WindowManager.ts index 4d334d88b6..0eda98b3bb 100644 --- a/src/Uno.UI/ts/WindowManager.ts +++ b/src/Uno.UI/ts/WindowManager.ts @@ -20,17 +20,16 @@ namespace Uno.UI { private static readonly unoUnarrangedClassName = "uno-unarranged"; private static readonly unoCollapsedClassName = "uno-visibility-collapsed"; - private static _cctor = (() => { - WindowManager.initMethods(); - HtmlDom.initPolyfills(); - })(); - /** * Initialize the WindowManager * @param containerElementId The ID of the container element for the Xaml UI * @param loadingElementId The ID of the loading element to remove once ready */ - public static init(isLoadEventsEnabled: boolean, containerElementId: string = "uno-body", loadingElementId: string = "uno-loading"): void { + public static async init(isLoadEventsEnabled: boolean, containerElementId: string = "uno-body", loadingElementId: string = "uno-loading") { + + HtmlDom.initPolyfills(); + + await WindowManager.initMethods(); WindowManager._isLoadEventsEnabled = isLoadEventsEnabled; @@ -48,7 +47,7 @@ namespace Uno.UI { private static buildReadyPromise(): Promise { return new Promise(resolve => { Promise.all( - [WindowManager.buildSplashScreen(), ExportManager.initialize()] + [WindowManager.buildSplashScreen()] ).then(() => resolve(true)) }); } @@ -112,20 +111,6 @@ namespace Uno.UI { }); } - /** - * Initialize the WindowManager - * @param containerElementId The ID of the container element for the Xaml UI - * @param loadingElementId The ID of the loading element to remove once ready - */ - public static initNative(pParams: number): boolean { - - const params = WindowManagerInitParams.unmarshal(pParams); - - WindowManager.init(params.IsLoadEventsEnabled); - - return true; - } - private containerElement: HTMLDivElement; private rootElement: HTMLElement; @@ -1582,7 +1567,10 @@ namespace Uno.UI { ); } - private static initMethods() { + private static async initMethods() { + + await ExportManager.initialize(); + if (!WindowManager.resizeMethod) { WindowManager.resizeMethod = (Module).mono_bind_static_method("[Uno.UI] Windows.UI.Xaml.Window:Resize"); } diff --git a/src/Uno.UI/tsBindings/WindowManagerInitParams.ts b/src/Uno.UI/tsBindings/WindowManagerInitParams.ts deleted file mode 100644 index fe3aabe7b9..0000000000 --- a/src/Uno.UI/tsBindings/WindowManagerInitParams.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* TSBindingsGenerator Generated code -- this code is regenerated on each build */ -class WindowManagerInitParams -{ - /* Pack=4 */ - public IsLoadEventsEnabled : boolean; - public static unmarshal(pData:number) : WindowManagerInitParams - { - const ret = new WindowManagerInitParams(); - - { - ret.IsLoadEventsEnabled = Boolean(Module.getValue(pData + 0, "i32")); - } - return ret; - } -} -- GitLab