44#include < windows.h>
55#include < windowsx.h>
66
7- #include < memory>
8- #include < mutex>
9-
107// Disabled until we have a 3rd party story for custom components
118// #include "AutolinkedNativeModules.g.h"
129
13- #include < winrt/Windows.Foundation.Collections.h>
14-
15- #include < DispatcherQueue.h>
16- #include < UIAutomation.h>
17- #include < windows.ui.composition.interop.h>
18-
1910#include < winrt/Microsoft.ReactNative.Composition.Experimental.h>
2011#include < winrt/Microsoft.ReactNative.Composition.h>
21- #include < winrt/Windows.UI.Composition.Desktop.h>
22- #include < winrt/Windows.UI.Composition.h>
2312
2413#include < DesktopWindowBridge.h>
2514#include " App.xaml.h"
@@ -108,12 +97,9 @@ struct CompReactPackageProvider
10897 }
10998};
11099
111- winrt::Windows::System::DispatcherQueueController g_dispatcherQueueController{nullptr };
112- winrt::Windows::UI::Composition::Compositor g_compositor{nullptr };
113-
114100constexpr auto WindowDataProperty = L" WindowData" ;
115101
116- int RunPlayground (int showCmd, bool useWebDebugger );
102+ int RunPlayground (int showCmd);
117103
118104struct WindowData {
119105 static HINSTANCE s_instance;
@@ -124,10 +110,8 @@ struct WindowData {
124110 winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr };
125111 winrt::Microsoft::ReactNative::ReactNativeHost m_host{nullptr };
126112 winrt::Microsoft::ReactNative::ReactInstanceSettings m_instanceSettings{nullptr };
127- bool m_useLiftedComposition{true };
128113 bool m_sizeToContent{false };
129114 bool m_forceRTL{false };
130- winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget m_target{nullptr };
131115 LONG m_height{0 };
132116 LONG m_width{0 };
133117
@@ -196,114 +180,66 @@ struct WindowData {
196180
197181 winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
198182 viewOptions.ComponentName (appName);
199- auto windowData = WindowData::GetFromWindow (hwnd);
200183
201184 if (!m_compRootView) {
202- if (windowData->m_useLiftedComposition ) {
203- m_compRootView = winrt::Microsoft::ReactNative::ReactNativeIsland (g_liftedCompositor);
204- } else {
205- m_compRootView = winrt::Microsoft::ReactNative::ReactNativeIsland ();
185+ m_compRootView = winrt::Microsoft::ReactNative::ReactNativeIsland (g_liftedCompositor);
186+
187+ // By setting the compositor here we opt into using the new architecture.
188+ winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositor (
189+ InstanceSettings (), g_liftedCompositor);
190+
191+ // Register ellipse:// uri hander for images
192+ host.PackageProviders ().Append (winrt::make<EllipseReactPackageProvider>());
193+
194+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create (
195+ g_liftedCompositor, winrt::Microsoft::UI::GetWindowIdFromWindow (hwnd));
196+
197+ if (m_forceRTL) {
198+ m_bridge.LayoutDirectionOverride (winrt::Microsoft::UI::Content::ContentLayoutDirection::RightToLeft);
206199 }
207200
208- if (windowData->m_useLiftedComposition ) {
209- // By setting the compositor here we opt into using the new architecture.
210- winrt::Microsoft::ReactNative::Composition::CompositionUIService::SetCompositor (
211- InstanceSettings (), g_liftedCompositor);
212-
213- // Register ellipse:// uri hander for images
214- host.PackageProviders ().Append (winrt::make<EllipseReactPackageProvider>());
215-
216- m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create (
217- g_liftedCompositor, winrt::Microsoft::UI::GetWindowIdFromWindow (hwnd));
218-
219- if (m_forceRTL) {
220- m_bridge.LayoutDirectionOverride (winrt::Microsoft::UI::Content::ContentLayoutDirection::RightToLeft);
221- }
222-
223- auto appContent = m_compRootView.Island ();
224-
225- m_bridge.Connect (appContent);
226- m_bridge.Show ();
227-
228- m_compRootView.ScaleFactor (ScaleFactor (hwnd));
229- winrt::Microsoft::ReactNative::LayoutConstraints constraints;
230- constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
231- constraints.MaximumSize =
232- constraints.MinimumSize = {m_width / ScaleFactor (hwnd), m_height / ScaleFactor (hwnd)};
233-
234- if (m_sizeToContent) {
235- ApplyConstraintsForContentSizedWindow (constraints);
236-
237- // Disable user sizing of the hwnd
238- ::SetWindowLong (hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX);
239- m_compRootView.SizeChanged (
240- [hwnd, props = InstanceSettings ().Properties ()](
241- auto /* sender*/ , const winrt::Microsoft::ReactNative::RootViewSizeChangedEventArgs &args) {
242- auto compositor =
243- winrt::Microsoft::ReactNative::Composition::CompositionUIService::GetCompositor (props);
244- auto async = compositor.RequestCommitAsync ();
245- async.Completed ([hwnd, size = args.Size ()](
246- auto /* asyncInfo*/ , winrt::Windows::Foundation::AsyncStatus /* asyncStatus*/ ) {
247- RECT rcClient, rcWindow;
248- GetClientRect (hwnd, &rcClient);
249- GetWindowRect (hwnd, &rcWindow);
250-
251- SetWindowPos (
252- hwnd,
253- nullptr ,
254- 0 ,
255- 0 ,
256- static_cast <int >(size.Width ) + rcClient.left - rcClient.right + rcWindow.right -
257- rcWindow.left ,
258- static_cast <int >(size.Height ) + rcClient.top - rcClient.bottom + rcWindow.bottom -
259- rcWindow.top ,
260- SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
261- });
262- });
263- }
264- m_compRootView.Arrange (constraints, {0 , 0 });
265-
266- m_bridge.ResizePolicy (winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
267-
268- } else if (!m_target) {
269- // General users of RNW should never set CompositionContext - this is an advanced usage to inject another
270- // composition implementation. By using the SystemCompositionContextHelper here, React Native Windows will
271- // use System Visuals for its tree.
272- winrt::Microsoft::ReactNative::ReactPropertyBag (InstanceSettings ().Properties ())
273- .Set (
274- winrt::Microsoft::ReactNative::ReactPropertyId<
275- winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext>{
276- L" ReactNative.Composition" , L" CompositionContext" },
277- winrt::Microsoft::ReactNative::Composition::Experimental::SystemCompositionContextHelper::
278- CreateContext (g_compositor));
279-
280- auto interop = g_compositor.as <ABI::Windows::UI::Composition::Desktop::ICompositorDesktopInterop>();
281- winrt::Windows::UI::Composition::Desktop::DesktopWindowTarget target{nullptr };
282- winrt::check_hresult (interop->CreateDesktopWindowTarget (
283- hwnd,
284- false ,
285- reinterpret_cast <ABI::Windows::UI::Composition::Desktop::IDesktopWindowTarget **>(
286- winrt::put_abi (target))));
287- m_target = target;
288-
289- auto root = g_compositor.CreateContainerVisual ();
290- root.RelativeSizeAdjustment ({1 .0f , 1 .0f });
291- root.Offset ({0 , 0 , 0 });
292- m_target.Root (root);
293- m_compRootView
294- .as <winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
295- .SetWindow (reinterpret_cast <uint64_t >(hwnd));
296- m_compRootView
297- .as <winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
298- .InternalRootVisual (winrt::Microsoft::ReactNative::Composition::Experimental::
299- SystemCompositionContextHelper::CreateVisual (root));
300- m_compRootView.ScaleFactor (ScaleFactor (hwnd));
301- winrt::Microsoft::ReactNative::LayoutConstraints contraints;
302- contraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
303- contraints.MaximumSize =
304- contraints.MinimumSize = {m_width / ScaleFactor (hwnd), m_height / ScaleFactor (hwnd)};
305- m_compRootView.Arrange (contraints, {0 , 0 });
201+ auto appContent = m_compRootView.Island ();
202+
203+ m_bridge.Connect (appContent);
204+ m_bridge.Show ();
205+
206+ m_compRootView.ScaleFactor (ScaleFactor (hwnd));
207+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
208+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
209+ constraints.MaximumSize =
210+ constraints.MinimumSize = {m_width / ScaleFactor (hwnd), m_height / ScaleFactor (hwnd)};
211+
212+ if (m_sizeToContent) {
213+ ApplyConstraintsForContentSizedWindow (constraints);
214+
215+ // Disable user sizing of the hwnd
216+ ::SetWindowLong (hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX);
217+ m_compRootView.SizeChanged ([hwnd, props = InstanceSettings ().Properties ()](
218+ auto /* sender*/ ,
219+ const winrt::Microsoft::ReactNative::RootViewSizeChangedEventArgs &args) {
220+ auto compositor =
221+ winrt::Microsoft::ReactNative::Composition::CompositionUIService::GetCompositor (props);
222+ auto async = compositor.RequestCommitAsync ();
223+ async.Completed ([hwnd, size = args.Size ()](
224+ auto /* asyncInfo*/ , winrt::Windows::Foundation::AsyncStatus /* asyncStatus*/ ) {
225+ RECT rcClient, rcWindow;
226+ GetClientRect (hwnd, &rcClient);
227+ GetWindowRect (hwnd, &rcWindow);
228+
229+ SetWindowPos (
230+ hwnd,
231+ nullptr ,
232+ 0 ,
233+ 0 ,
234+ static_cast <int >(size.Width ) + rcClient.left - rcClient.right + rcWindow.right - rcWindow.left ,
235+ static_cast <int >(size.Height ) + rcClient.top - rcClient.bottom + rcWindow.bottom - rcWindow.top ,
236+ SWP_DEFERERASE | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER);
237+ });
238+ });
306239 }
240+ m_compRootView.Arrange (constraints, {0 , 0 });
241+
242+ m_bridge.ResizePolicy (winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
307243 }
308244
309245 // Nudge the ReactNativeHost to create the instance and wrapping context
@@ -319,7 +255,7 @@ struct WindowData {
319255 std::thread playgroundThread{([]() {
320256 // For subsequent RN windows do not use the web debugger by default,
321257 // since one instance can be connected to it at a time.
322- RunPlayground (SW_SHOW, false );
258+ RunPlayground (SW_SHOW);
323259 })};
324260 playgroundThread.detach ();
325261 break ;
@@ -404,15 +340,6 @@ struct WindowData {
404340 }
405341 }
406342
407- LRESULT TranslateMessage (HWND /* hwnd*/ , UINT message, WPARAM wparam, LPARAM lparam) noexcept {
408- if (!m_useLiftedComposition && m_compRootView) {
409- return static_cast <LRESULT>(
410- m_compRootView.as <winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
411- .SendMessage (message, wparam, lparam));
412- }
413- return 0 ;
414- }
415-
416343 // / Message handler for about box.
417344 static INT_PTR CALLBACK About (HWND hwnd, UINT message, WPARAM wparam, LPARAM /* lparam */ ) noexcept {
418345 switch (message) {
@@ -488,7 +415,6 @@ struct WindowData {
488415 case WM_INITDIALOG: {
489416 auto boolToCheck = [](bool b) { return b ? BST_CHECKED : BST_UNCHECKED; };
490417 auto self = reinterpret_cast <WindowData *>(lparam);
491- CheckDlgButton (hwnd, IDC_LIFTEDCOMPOSITION, boolToCheck (self->m_useLiftedComposition ));
492418 CheckDlgButton (hwnd, IDC_FASTREFRESH, boolToCheck (self->InstanceSettings ().UseFastRefresh ()));
493419 CheckDlgButton (hwnd, IDC_DIRECTDEBUGGER, boolToCheck (self->InstanceSettings ().UseDirectDebugger ()));
494420 CheckDlgButton (hwnd, IDC_BREAKONNEXTLINE, boolToCheck (self->InstanceSettings ().DebuggerBreakOnNextLine ()));
@@ -498,20 +424,12 @@ struct WindowData {
498424 SetWindowTextW (portEditControl, std::to_wstring (self->InstanceSettings ().DebuggerPort ()).c_str ());
499425 SendMessageW (portEditControl, (UINT)EM_SETLIMITTEXT, (WPARAM)5 , (LPARAM)0 );
500426
501- auto cmbEngines = GetDlgItem (hwnd, IDC_JSENGINE);
502- SendMessageW (cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0 , (LPARAM)TEXT (" Chakra" ));
503- SendMessageW (cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0 , (LPARAM)TEXT (" Hermes" ));
504- SendMessageW (cmbEngines, (UINT)CB_ADDSTRING, (WPARAM)0 , (LPARAM)TEXT (" V8" ));
505- // Fabric only supports Hermes right now - So dont actually set JS engine override
506- // SendMessageW(cmbEngines, CB_SETCURSEL, (WPARAM) static_cast<int32_t>(self->m_jsEngine), (LPARAM)0);
507-
508427 return TRUE ;
509428 }
510429 case WM_COMMAND: {
511430 switch (LOWORD (wparam)) {
512431 case IDOK: {
513432 auto self = GetFromWindow (GetParent (hwnd));
514- self->m_useLiftedComposition = (IsDlgButtonChecked (hwnd, IDC_LIFTEDCOMPOSITION) == BST_CHECKED);
515433 self->InstanceSettings ().UseFastRefresh (IsDlgButtonChecked (hwnd, IDC_FASTREFRESH) == BST_CHECKED);
516434 self->InstanceSettings ().UseDirectDebugger (IsDlgButtonChecked (hwnd, IDC_DIRECTDEBUGGER) == BST_CHECKED);
517435 self->InstanceSettings ().DebuggerBreakOnNextLine (
@@ -533,11 +451,6 @@ struct WindowData {
533451 // Don't update the debugger port if the new value can't be parsed
534452 // (E.g. includes letters or symbols).
535453 }
536-
537- // Fabric only supports Hermes right now - So dont actually set JS engine override
538- // auto cmbEngines = GetDlgItem(hwnd, IDC_JSENGINE);
539- // int itemIndex = (int)SendMessageW(cmbEngines, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0);
540- // self->m_jsEngine = static_cast<Microsoft::ReactNative::JSIEngine>(itemIndex);
541454 }
542455 [[fallthrough]];
543456 case IDCANCEL:
@@ -557,11 +470,6 @@ HINSTANCE WindowData::s_instance = reinterpret_cast<HINSTANCE>(&__ImageBase);
557470
558471LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) noexcept {
559472 auto windowData = WindowData::GetFromWindow (hwnd);
560- if (windowData) {
561- auto result = WindowData::GetFromWindow (hwnd)->TranslateMessage (hwnd, message, wparam, lparam);
562- if (result)
563- return result;
564- }
565473
566474 switch (message) {
567475 case WM_COMMAND: {
@@ -606,20 +514,6 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
606514 SetProp (hwnd, WindowDataProperty, reinterpret_cast <HANDLE>(windowData));
607515 break ;
608516 }
609- case WM_GETOBJECT: {
610- if (!windowData->m_useLiftedComposition && lparam == UiaRootObjectId) {
611- if (windowData == nullptr || !windowData->m_compRootView )
612- break ;
613-
614- auto rootView = windowData->m_compRootView ;
615- winrt::com_ptr<IRawElementProviderSimple> spReps;
616- if (!rootView.GetUiaProvider ().try_as (spReps)) {
617- break ;
618- }
619- LRESULT lResult = UiaReturnRawElementProvider (hwnd, wparam, lparam, spReps.get ());
620- return lResult;
621- }
622- }
623517 case WM_WINDOWPOSCHANGED: {
624518 windowData->UpdateSize (hwnd);
625519
@@ -634,7 +528,7 @@ LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
634528
635529constexpr PCWSTR c_windowClassName = L" MS_REACTNATIVE_PLAYGROUND_COMPOSITION" ;
636530
637- int RunPlayground (int showCmd, bool /* useWebDebugger */ ) {
531+ int RunPlayground (int showCmd) {
638532 constexpr PCWSTR appName = L" React Native Playground (Composition)" ;
639533
640534 auto windowData = std::make_unique<WindowData>();
@@ -665,10 +559,6 @@ int RunPlayground(int showCmd, bool /*useWebDebugger*/) {
665559 // know the message loop has finished.
666560 g_liftedDispatcherQueueController.ShutdownQueue ();
667561
668- // Destroy all Composition objects
669- g_compositor.Close ();
670- g_compositor = nullptr ;
671-
672562 return 0 ;
673563}
674564
@@ -692,19 +582,6 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
692582 WINRT_VERIFY (classId);
693583 winrt::check_win32 (!classId);
694584
695- DispatcherQueueOptions options{
696- sizeof (DispatcherQueueOptions), /* dwSize */
697- DQTYPE_THREAD_CURRENT, /* threadType */
698- DQTAT_COM_ASTA /* apartmentType */
699- };
700-
701- // Need to have a Dispatcher on the current thread to be able to create a Compositor
702- winrt::check_hresult (CreateDispatcherQueueController (
703- options,
704- reinterpret_cast <ABI::Windows::System::IDispatcherQueueController **>(
705- winrt::put_abi (g_dispatcherQueueController))));
706- g_compositor = winrt::Windows::UI::Composition::Compositor ();
707-
708585 // Create a Lifted (WinAppSDK) DispatcherQueue for this thread. This is needed for
709586 // Microsoft.UI.Composition, Content, and Input APIs.
710587 g_liftedDispatcherQueueController =
@@ -715,5 +592,5 @@ _Use_decl_annotations_ int CALLBACK WinMain(HINSTANCE instance, HINSTANCE, PSTR
715592 // in Microsoft.ui.xaml.controls.dll.
716593 auto playgroundApp{winrt::make<winrt::Playground::implementation::App>()};
717594
718- return RunPlayground (showCmd, false );
595+ return RunPlayground (showCmd);
719596}
0 commit comments