99namespace winrt
1010{
1111 using winrt::Microsoft::ReactNative::IJSValueWriter;
12- using winrt::Microsoft::ReactNative::LayoutDirection;
13- using winrt::Microsoft::ReactNative::ReactCoreInjection;
14- using winrt::Microsoft::ReactNative::ReactNativeIsland;
1512 using winrt::Microsoft::ReactNative::ReactViewOptions;
16- using winrt::Microsoft::UI::Composition::Compositor;
17- using winrt::Microsoft::UI::Content::ContentSizePolicy;
18- using winrt::Microsoft::UI::Content::DesktopChildSiteBridge;
19- using winrt::Microsoft::UI::Dispatching::DispatcherQueueController;
20- using winrt::Microsoft::UI::Windowing::AppWindow;
21- using winrt::Microsoft::UI::Windowing::AppWindowChangedEventArgs;
22- using winrt::Microsoft::UI::Windowing::OverlappedPresenter;
23- using winrt::Microsoft::UI::Windowing::OverlappedPresenterState;
24- using winrt::Windows::Foundation::AsyncStatus;
25- using winrt::Windows::Foundation::Size;
2613} // namespace winrt
2714
2815namespace
@@ -34,30 +21,9 @@ namespace
3421#endif
3522 constexpr bool kSingleAppMode = static_cast <bool >(ENABLE_SINGLE_APP_MODE);
3623
37- float ScaleFactor (HWND hwnd) noexcept
24+ void ConfigureReactViewOptions (winrt::ReactViewOptions viewOptions,
25+ ReactApp::Component const &component)
3826 {
39- return GetDpiForWindow (hwnd) / static_cast <float >(USER_DEFAULT_SCREEN_DPI);
40- }
41-
42- void UpdateRootViewSizeToAppWindow (winrt::ReactNativeIsland const &rootView,
43- winrt::AppWindow const &window)
44- {
45- // Do not relayout when minimized
46- auto windowState = window.Presenter ().as <winrt::OverlappedPresenter>().State ();
47- if (windowState == winrt::OverlappedPresenterState::Minimized) {
48- return ;
49- }
50-
51- auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId (window.Id ());
52- auto scaleFactor = ScaleFactor (hwnd);
53- winrt::Size size{window.ClientSize ().Width / scaleFactor,
54- window.ClientSize ().Height / scaleFactor};
55- rootView.Arrange ({size, size, winrt::LayoutDirection::Undefined}, {0 , 0 });
56- }
57-
58- winrt::ReactViewOptions MakeReactViewOptions (ReactApp::Component const &component)
59- {
60- winrt::ReactViewOptions viewOptions;
6127 viewOptions.ComponentName (winrt::to_hstring (component.appKey ));
6228
6329 auto initialProps = component.initialProperties .value_or <ReactApp::JSONObject>({});
@@ -71,8 +37,6 @@ namespace
7137 }
7238 writer.WriteObjectEnd ();
7339 });
74-
75- return viewOptions;
7640 }
7741} // namespace
7842
@@ -91,22 +55,8 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE /* instance */,
9155 // Enable per monitor DPI scaling
9256 SetProcessDpiAwarenessContext (DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
9357
94- // Create a DispatcherQueue for this thread. This is needed for Composition, Content, and
95- // Input APIs.
96- auto dispatcherQueueController = winrt::DispatcherQueueController::CreateOnCurrentThread ();
97-
98- // Create a Compositor for all Content on this thread.
99- auto compositor = winrt::Compositor{};
100-
101- // Create a top-level window.
102- auto window = winrt::AppWindow::Create ();
103- window.Title (winrt::to_hstring (manifest.displayName ));
104- window.Resize ({600 , 800 });
105- window.Show ();
106- auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId (window.Id ());
107- auto scaleFactor = ScaleFactor (hwnd);
108-
109- auto instance = ReactTestApp::ReactInstance{hwnd, compositor};
58+ auto app = winrt::Microsoft::ReactNative::ReactNativeAppBuilder ().Build ();
59+ auto instance = ReactTestApp::ReactInstance{app.ReactNativeHost ()};
11060 if (manifest.bundleRoot .has_value ()) {
11161 auto &bundleRoot = *manifest.bundleRoot ;
11262 instance.BundleRoot (std::make_optional (winrt::to_hstring (bundleRoot)));
@@ -115,81 +65,31 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE /* instance */,
11565 // Start the react-native instance, which will create a JavaScript runtime and load the
11666 // applications bundle
11767 if constexpr (kDebug ) {
118- instance.LoadJSBundleFrom (ReactTestApp::JSBundleSource::DevServer);
68+ instance.LoadJSBundleFrom (ReactTestApp::JSBundleSource::DevServer, false );
11969 } else {
120- instance.LoadJSBundleFrom (ReactTestApp::JSBundleSource::Embedded);
70+ instance.LoadJSBundleFrom (ReactTestApp::JSBundleSource::Embedded, false );
12171 }
12272
123- // Create a RootView which will present a react-native component
124- winrt::ReactViewOptions viewOptions;
73+ // Configure ReactViewOptions to load the initial component
12574 if constexpr (kSingleAppMode ) {
12675 assert (manifest.singleApp .has_value () ||
12776 !" `ENABLE_SINGLE_APP_MODE` shouldn't have been true" );
12877
12978 for (auto &component : *manifest.components ) {
13079 if (component.slug == *manifest.singleApp ) {
131- viewOptions = MakeReactViewOptions ( component);
80+ ConfigureReactViewOptions (app. ReactViewOptions (), component);
13281 break ;
13382 }
13483 }
13584 } else {
13685 // TODO: Implement session restoration
13786 auto &component = (*manifest.components )[0 ];
138- viewOptions = MakeReactViewOptions ( component);
87+ ConfigureReactViewOptions (app. ReactViewOptions (), component);
13988 }
14089
141- auto rootView = winrt::ReactNativeIsland{compositor};
142- rootView.ReactViewHost (
143- winrt::ReactCoreInjection::MakeViewHost (instance.ReactHost (), viewOptions));
144-
145- // Update the size of the RootView when the AppWindow changes size
146- window.Changed (
147- [wkRootView = winrt::make_weak (rootView)](winrt::AppWindow const &window,
148- winrt::AppWindowChangedEventArgs const &args) {
149- if (args.DidSizeChange () || args.DidVisibilityChange ()) {
150- if (auto rootView = wkRootView.get ()) {
151- UpdateRootViewSizeToAppWindow (rootView, window);
152- }
153- }
154- });
155-
156- // Quit application when main window is closed
157- window.Destroying ([&host = instance.ReactHost ()](winrt::AppWindow const & /* window */ ,
158- winrt::IInspectable const & /* args */ ) {
159- // Before we shutdown the application - unload the ReactNativeHost to give the javascript a
160- // chance to save any state
161- auto async = host.UnloadInstance ();
162- async.Completed ([host](auto asyncInfo, winrt::AsyncStatus asyncStatus) {
163- assert (asyncStatus == winrt::AsyncStatus::Completed);
164- host.InstanceSettings ().UIDispatcher ().Post ([]() { PostQuitMessage (0 ); });
165- });
166- });
167-
168- // DesktopChildSiteBridge create a ContentSite that can host the RootView ContentIsland
169- auto bridge = winrt::DesktopChildSiteBridge::Create (compositor, window.Id ());
170- bridge.Connect (rootView.Island ());
171- bridge.ResizePolicy (winrt::ContentSizePolicy::ResizeContentToParentWindow);
172-
173- auto invScale = 1 .0f / scaleFactor;
174- rootView.RootVisual ().Scale ({invScale, invScale, invScale});
175- rootView.ScaleFactor (scaleFactor);
176-
177- // Set the intialSize of the root view
178- UpdateRootViewSizeToAppWindow (rootView, window);
179-
180- bridge.Show ();
181-
182- // Run the main application event loop
183- dispatcherQueueController.DispatcherQueue ().RunEventLoop ();
184-
185- // Rundown the DispatcherQueue. This drains the queue and raises events to let components
186- // know the message loop has finished.
187- dispatcherQueueController.ShutdownQueue ();
188-
189- bridge.Close ();
190- bridge = nullptr ;
90+ auto window = app.AppWindow ();
91+ window.Title (winrt::to_hstring (manifest.displayName ));
92+ window.Resize ({600 , 800 });
19193
192- // Destroy all Composition objects
193- compositor.Close ();
194- compositor = nullptr ;
94+ app.Start ();
19595}
0 commit comments