react-native-windows 0.74.21 → 0.74.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/Microsoft.ReactNative/ComponentView.idl +11 -0
  2. package/Microsoft.ReactNative/Composition.Input.idl +1 -0
  3. package/Microsoft.ReactNative/CompositionSwitcher.idl +3 -0
  4. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +18 -8
  5. package/Microsoft.ReactNative/Fabric/ComponentView.h +7 -5
  6. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.cpp +4 -0
  7. package/Microsoft.ReactNative/Fabric/Composition/Composition.Input.h +1 -0
  8. package/Microsoft.ReactNative/Fabric/Composition/CompositionContextHelper.cpp +44 -13
  9. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +75 -0
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.h +8 -2
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionHwndHost.cpp +1 -0
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +34 -7
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +3 -2
  14. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +8 -6
  15. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.h +1 -2
  16. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.cpp +20 -6
  17. package/Microsoft.ReactNative/Fabric/Composition/FocusManager.h +13 -6
  18. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +2 -3
  19. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +1 -2
  20. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +80 -55
  21. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +15 -4
  22. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +37 -8
  23. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +7 -2
  24. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +14 -7
  25. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +1 -2
  26. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +6 -6
  27. package/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +1 -2
  28. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.cpp +1 -2
  29. package/Microsoft.ReactNative/Fabric/Composition/TextDrawing.h +1 -1
  30. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +104 -152
  31. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +7 -3
  32. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp +14 -11
  33. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h +4 -4
  34. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +0 -13
  35. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +0 -3
  36. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +12 -4
  37. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.cpp +338 -0
  38. package/Microsoft.ReactNative/Fabric/Composition/TooltipService.h +66 -0
  39. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +37 -4
  40. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +3 -0
  41. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -2
  42. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h +1 -2
  43. package/Microsoft.ReactNative/Fabric/FabricUIManagerModule.cpp +31 -3
  44. package/Microsoft.ReactNative/Fabric/ReactTaggedView.h +4 -0
  45. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.cpp +5 -0
  46. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewProps.h +1 -1
  47. package/Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/HostPlatformViewTraitsInitializer.h +1 -1
  48. package/Microsoft.ReactNative/Fabric/platform/react/renderer/textlayoutmanager/TextLayoutManager.cpp +9 -2
  49. package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +8 -1
  50. package/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +1 -1
  51. package/Microsoft.ReactNative/Modules/LogBoxModule.cpp +9 -0
  52. package/Microsoft.ReactNative/Modules/LogBoxModule.h +2 -0
  53. package/Microsoft.ReactNative/Modules/SampleTurboModule.cpp +104 -0
  54. package/Microsoft.ReactNative/Modules/SampleTurboModule.h +78 -0
  55. package/Microsoft.ReactNative/ReactCoreInjection.h +0 -1
  56. package/Microsoft.ReactNative/ReactHost/MsoReactContext.cpp +0 -7
  57. package/Microsoft.ReactNative/ReactHost/MsoReactContext.h +0 -5
  58. package/Microsoft.ReactNative/ReactHost/ReactInstanceWin.cpp +17 -1
  59. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +59 -0
  60. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +23 -0
  61. package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +179 -0
  62. package/Microsoft.ReactNative/ReactNativeAppBuilder.h +35 -0
  63. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +69 -0
  64. package/Microsoft.ReactNative/ReactNativeIsland.idl +2 -0
  65. package/Microsoft.ReactNative/ReactNativeWin32App.cpp +82 -0
  66. package/Microsoft.ReactNative/ReactNativeWin32App.h +38 -0
  67. package/Microsoft.ReactNative/Timer.idl +1 -1
  68. package/Microsoft.ReactNative/packages.lock.json +0 -10
  69. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  70. package/Shared/Shared.vcxitems +36 -0
  71. package/Shared/Shared.vcxitems.filters +2 -0
  72. package/Shared/TurboModuleManager.cpp +0 -3
  73. package/package.json +3 -3
  74. package/templates/cpp-app/windows/MyApp/MyApp.cpp +1 -0
@@ -43,7 +43,10 @@ void TextLayoutManager::GetTextLayout(
43
43
  static_cast<facebook::react::FontWeight>(DWRITE_FONT_WEIGHT_REGULAR))),
44
44
  style,
45
45
  DWRITE_FONT_STRETCH_NORMAL,
46
- outerFragment.textAttributes.fontSize,
46
+ (outerFragment.textAttributes.allowFontScaling.value_or(true) &&
47
+ !std::isnan(outerFragment.textAttributes.fontSizeMultiplier))
48
+ ? (outerFragment.textAttributes.fontSizeMultiplier * outerFragment.textAttributes.fontSize)
49
+ : outerFragment.textAttributes.fontSize,
47
50
  L"",
48
51
  spTextFormat.put()));
49
52
 
@@ -118,7 +121,11 @@ void TextLayoutManager::GetTextLayout(
118
121
  attributes.fontWeight.value_or(static_cast<facebook::react::FontWeight>(DWRITE_FONT_WEIGHT_REGULAR))),
119
122
  range));
120
123
  winrt::check_hresult(spTextLayout->SetFontStyle(fragmentStyle, range));
121
- winrt::check_hresult(spTextLayout->SetFontSize(attributes.fontSize, range));
124
+ winrt::check_hresult(spTextLayout->SetFontSize(
125
+ (attributes.allowFontScaling.value_or(true) && !std::isnan(attributes.fontSizeMultiplier))
126
+ ? (attributes.fontSizeMultiplier * attributes.fontSize)
127
+ : attributes.fontSize,
128
+ range));
122
129
 
123
130
  if (!isnan(attributes.letterSpacing)) {
124
131
  winrt::check_hresult(
@@ -47,6 +47,13 @@ namespace Microsoft.ReactNative
47
47
  UInt32 Index { get; };
48
48
  };
49
49
 
50
+ [experimental]
51
+ runtimeclass HandleCommandArgs {
52
+ String CommandName { get; };
53
+ IJSValueReader CommandArgs { get; };
54
+ Boolean Handled;
55
+ };
56
+
50
57
  [experimental]
51
58
  DOC_STRING("A delegate that creates a @IComponentProps object for an instance of @ViewProps. See @IReactViewComponentBuilder.SetCreateProps")
52
59
  delegate IComponentProps ViewPropsFactory(ViewProps props);
@@ -71,7 +78,7 @@ namespace Microsoft.ReactNative
71
78
  delegate void ComponentViewInitializer(ComponentView view);
72
79
 
73
80
  [experimental]
74
- delegate void HandleCommandDelegate(ComponentView source, String commandName, IJSValueReader args);
81
+ delegate void HandleCommandDelegate(ComponentView source, HandleCommandArgs args);
75
82
 
76
83
  [experimental]
77
84
  delegate void UpdateFinalizerDelegate(ComponentView source, ComponentViewUpdateMask updateMask);
@@ -142,7 +142,7 @@
142
142
  <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
143
143
  </ClCompile>
144
144
  <Link>
145
- <AdditionalDependencies>winsqlite3.lib;ChakraRT.lib;dxguid.lib;dloadhelper.lib;OneCoreUap_apiset.lib;%(AdditionalDependencies)</AdditionalDependencies>
145
+ <AdditionalDependencies>winsqlite3.lib;ChakraRT.lib;dxguid.lib;dloadhelper.lib;OneCoreUap_apiset.lib;Dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
146
146
  <DelayLoadDLLs>
147
147
  api-ms-win-core-file-l1-2-0.dll;
148
148
  api-ms-win-core-windowserrorreporting-l1-1-0.dll;
@@ -19,6 +19,15 @@
19
19
 
20
20
  namespace Microsoft::ReactNative {
21
21
 
22
+ LogBox::~LogBox() {
23
+ #ifdef USE_FABRIC
24
+ if (m_hwnd) {
25
+ m_context.UIDispatcher().Post([hwnd = m_hwnd]() { DestroyWindow(hwnd); });
26
+ m_hwnd = nullptr;
27
+ }
28
+ #endif
29
+ }
30
+
22
31
  #ifdef USE_FABRIC
23
32
  constexpr PCWSTR c_logBoxWindowClassName = L"MS_REACTNATIVE_LOGBOX";
24
33
  constexpr auto CompHostProperty = L"CompHost";
@@ -14,6 +14,8 @@ REACT_MODULE(LogBox)
14
14
  struct LogBox : public std::enable_shared_from_this<LogBox> {
15
15
  using ModuleSpec = ReactNativeSpecs::LogBoxSpec;
16
16
 
17
+ ~LogBox();
18
+
17
19
  REACT_INIT(Initialize)
18
20
  void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
19
21
 
@@ -0,0 +1,104 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+
4
+ #include "pch.h"
5
+ #include "SampleTurboModule.h"
6
+
7
+ namespace Microsoft::ReactNative {
8
+
9
+ void SampleTurboModule::Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept {
10
+ m_reactContext = reactContext;
11
+ }
12
+
13
+ ReactNativeSpecs::SampleTurboModuleSpec_Constants SampleTurboModule::GetConstants() noexcept {
14
+ ReactNativeSpecs::SampleTurboModuleSpec_Constants constants;
15
+ constants.const1 = true;
16
+ constants.const2 = 375;
17
+ constants.const3 = "something";
18
+ return constants;
19
+ }
20
+
21
+ void SampleTurboModule::voidFunc() noexcept {}
22
+
23
+ bool SampleTurboModule::getBool(bool arg) noexcept {
24
+ return arg;
25
+ }
26
+
27
+ double SampleTurboModule::getEnum(double arg) noexcept {
28
+ return arg;
29
+ }
30
+
31
+ double SampleTurboModule::getNumber(double arg) noexcept {
32
+ return arg;
33
+ }
34
+
35
+ std::string SampleTurboModule::getString(std::string arg) noexcept {
36
+ return std::string(arg);
37
+ }
38
+
39
+ ::React::JSValueArray SampleTurboModule::getArray(::React::JSValueArray &&arg) noexcept {
40
+ return arg.Copy();
41
+ }
42
+
43
+ ::React::JSValue SampleTurboModule::getObject(::React::JSValue &&arg) noexcept {
44
+ assert(arg.Type() == ::React::JSValueType::Object);
45
+ return arg.Copy();
46
+ }
47
+
48
+ ::React::JSValue SampleTurboModule::getUnsafeObject(::React::JSValue &&arg) noexcept {
49
+ assert(arg.Type() == ::React::JSValueType::Object);
50
+ return arg.Copy();
51
+ }
52
+
53
+ double SampleTurboModule::getRootTag(double arg) noexcept {
54
+ // TODO: Proper impl
55
+ return arg;
56
+ }
57
+
58
+ ::React::JSValue SampleTurboModule::getValue(double x, std::string y, ::React::JSValue &&z) noexcept {
59
+ return ::React::JSValueObject{
60
+ {"x", x},
61
+ {"y", y},
62
+ {"z", z.Copy()},
63
+ };
64
+ }
65
+
66
+ void SampleTurboModule::getValueWithCallback(std::function<void(std::string)> const &callback) noexcept {
67
+ callback("value from callback!");
68
+ }
69
+
70
+ void SampleTurboModule::getValueWithPromise(bool error, ::React::ReactPromise<std::string> &&result) noexcept {
71
+ if (error) {
72
+ result.Reject("intentional promise rejection");
73
+ } else {
74
+ result.Resolve("result!");
75
+ }
76
+ }
77
+
78
+ void SampleTurboModule::voidFuncThrows() noexcept {
79
+ // TODO: Proper impl
80
+ }
81
+
82
+ ::React::JSValue SampleTurboModule::getObjectThrows(::React::JSValue &&arg) noexcept {
83
+ // TODO: Proper impl
84
+ return nullptr;
85
+ }
86
+
87
+ void SampleTurboModule::promiseThrows(::React::ReactPromise<void> &&result) noexcept {
88
+ // TODO: Proper impl
89
+ }
90
+
91
+ void SampleTurboModule::voidFuncAssert() noexcept {
92
+ // TODO: Proper impl
93
+ }
94
+
95
+ ::React::JSValue SampleTurboModule::getObjectAssert(::React::JSValue &&arg) noexcept {
96
+ // TODO: Proper impl
97
+ return nullptr;
98
+ }
99
+
100
+ void SampleTurboModule::promiseAssert(::React::ReactPromise<void> &&result) noexcept {
101
+ // TODO: Proper impl
102
+ }
103
+
104
+ } // namespace Microsoft::ReactNative
@@ -0,0 +1,78 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ #pragma once
4
+
5
+ #include "codegen/NativeSampleTurboModuleSpec.g.h"
6
+ #include <NativeModules.h>
7
+
8
+ namespace Microsoft::ReactNative {
9
+
10
+ REACT_MODULE(SampleTurboModule)
11
+ struct SampleTurboModule {
12
+ using ModuleSpec = ReactNativeSpecs::SampleTurboModuleSpec;
13
+
14
+ REACT_INIT(Initialize)
15
+ void Initialize(winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
16
+
17
+ REACT_GET_CONSTANTS(GetConstants)
18
+ ReactNativeSpecs::SampleTurboModuleSpec_Constants GetConstants() noexcept;
19
+
20
+ REACT_METHOD(voidFunc)
21
+ void voidFunc() noexcept;
22
+
23
+ REACT_SYNC_METHOD(getBool)
24
+ bool getBool(bool arg) noexcept;
25
+
26
+ REACT_SYNC_METHOD(getEnum)
27
+ double getEnum(double arg) noexcept;
28
+
29
+ REACT_SYNC_METHOD(getNumber)
30
+ double getNumber(double arg) noexcept;
31
+
32
+ REACT_SYNC_METHOD(getString)
33
+ std::string getString(std::string arg) noexcept;
34
+
35
+ REACT_SYNC_METHOD(getArray)
36
+ ::React::JSValueArray getArray(::React::JSValueArray &&arg) noexcept;
37
+
38
+ REACT_SYNC_METHOD(getObject)
39
+ ::React::JSValue getObject(::React::JSValue &&arg) noexcept;
40
+
41
+ REACT_SYNC_METHOD(getUnsafeObject)
42
+ ::React::JSValue getUnsafeObject(::React::JSValue &&arg) noexcept;
43
+
44
+ REACT_SYNC_METHOD(getRootTag)
45
+ double getRootTag(double arg) noexcept;
46
+
47
+ REACT_SYNC_METHOD(getValue)
48
+ ::React::JSValue getValue(double x, std::string y, ::React::JSValue &&z) noexcept;
49
+
50
+ REACT_METHOD(getValueWithCallback)
51
+ void getValueWithCallback(std::function<void(std::string)> const &callback) noexcept;
52
+
53
+ REACT_METHOD(getValueWithPromise)
54
+ void getValueWithPromise(bool error, ::React::ReactPromise<std::string> &&result) noexcept;
55
+
56
+ REACT_METHOD(voidFuncThrows)
57
+ void voidFuncThrows() noexcept;
58
+
59
+ REACT_SYNC_METHOD(getObjectThrows)
60
+ ::React::JSValue getObjectThrows(::React::JSValue &&arg) noexcept;
61
+
62
+ REACT_METHOD(promiseThrows)
63
+ void promiseThrows(::React::ReactPromise<void> &&result) noexcept;
64
+
65
+ REACT_METHOD(voidFuncAssert)
66
+ void voidFuncAssert() noexcept;
67
+
68
+ REACT_SYNC_METHOD(getObjectAssert)
69
+ ::React::JSValue getObjectAssert(::React::JSValue &&arg) noexcept;
70
+
71
+ REACT_METHOD(promiseAssert)
72
+ void promiseAssert(::React::ReactPromise<void> &&result) noexcept;
73
+
74
+ private:
75
+ winrt::Microsoft::ReactNative::ReactContext m_reactContext;
76
+ };
77
+
78
+ } // namespace Microsoft::ReactNative
@@ -53,7 +53,6 @@ struct ReactCoreInjection : ReactCoreInjectionT<ReactCoreInjection> {
53
53
  static uint64_t GetTopLevelWindowId(const IReactPropertyBag &properties) noexcept;
54
54
  static void SetTopLevelWindowId(const IReactPropertyBag &properties, uint64_t windowId) noexcept;
55
55
 
56
- static ITimer CreateTimer(const IReactPropertyBag &properties);
57
56
  static TimerFactory GetTimerFactory(const IReactPropertyBag &properties) noexcept;
58
57
  static void SetTimerFactory(const IReactPropertyBag &properties, const TimerFactory &timerFactory) noexcept;
59
58
  };
@@ -170,13 +170,6 @@ ReactContext::ReactContext(
170
170
  m_properties{winrt::make<WeakRefPropertyBag>(properties)},
171
171
  m_notifications{notifications} {}
172
172
 
173
- void ReactContext::Destroy() noexcept {
174
- if (auto notificationService =
175
- winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNotificationService>(m_notifications)) {
176
- notificationService->UnsubscribeAll();
177
- }
178
- }
179
-
180
173
  winrt::Microsoft::ReactNative::IReactPropertyBag ReactContext::Properties() const noexcept {
181
174
  return m_properties;
182
175
  }
@@ -45,11 +45,6 @@ class ReactContext final : public Mso::UnknownObject<IReactContext> {
45
45
  winrt::Microsoft::ReactNative::IReactPropertyBag const &properties,
46
46
  winrt::Microsoft::ReactNative::IReactNotificationService const &notifications) noexcept;
47
47
 
48
- // ReactContext may have longer lifespan than ReactInstance.
49
- // The ReactInstance uses the Destroy method to enforce the ReactContext cleanup
50
- // when the ReactInstance is destroyed.
51
- void Destroy() noexcept;
52
-
53
48
  public: // IReactContext
54
49
  winrt::Microsoft::ReactNative::IReactPropertyBag Properties() const noexcept override;
55
50
  winrt::Microsoft::ReactNative::IReactNotificationService Notifications() const noexcept override;
@@ -39,6 +39,7 @@
39
39
  #include "Modules/ExceptionsManager.h"
40
40
  #include "Modules/PlatformConstantsWinModule.h"
41
41
  #include "Modules/ReactRootViewTagGenerator.h"
42
+ #include "Modules/SampleTurboModule.h"
42
43
  #include "Modules/SourceCode.h"
43
44
  #include "Modules/StatusBarManager.h"
44
45
  #include "Modules/Timing.h"
@@ -399,6 +400,13 @@ void ReactInstanceWin::LoadModules(
399
400
  }
400
401
  #endif
401
402
 
403
+ if (!m_options.UseWebDebugger()) {
404
+ turboModulesProvider->AddModuleProvider(
405
+ L"SampleTurboModule",
406
+ winrt::Microsoft::ReactNative::MakeTurboModuleProvider<::Microsoft::ReactNative::SampleTurboModule>(),
407
+ false);
408
+ }
409
+
402
410
  if (devSettings->useTurboModulesOnly) {
403
411
  ::Microsoft::ReactNative::ExceptionsManager::SetRedBoxHander(
404
412
  winrt::Microsoft::ReactNative::ReactPropertyBag(m_reactContext->Properties()), m_redboxHandler);
@@ -676,8 +684,16 @@ void ReactInstanceWin::InitializeBridgeless() noexcept {
676
684
  return turboModuleManager->getModule(name);
677
685
  };
678
686
 
687
+ // Use a legacy native module binding that always returns null
688
+ // This means that calls to NativeModules.XXX will always return null, rather than crashing on access
689
+ auto legacyNativeModuleBinding =
690
+ [](const std::string & /*name*/) -> std::shared_ptr<facebook::react::TurboModule> { return nullptr; };
691
+
679
692
  facebook::react::TurboModuleBinding::install(
680
- runtime, std::function(binding), nullptr, m_options.TurboModuleProvider->LongLivedObjectCollection());
693
+ runtime,
694
+ std::function(binding),
695
+ std::function(legacyNativeModuleBinding),
696
+ m_options.TurboModuleProvider->LongLivedObjectCollection());
681
697
 
682
698
  auto componentDescriptorRegistry =
683
699
  Microsoft::ReactNative::WindowsComponentDescriptorRegistry::FromProperties(
@@ -0,0 +1,59 @@
1
+ #include "pch.h"
2
+ #include "ReactInstanceSettingsBuilder.h"
3
+ #include "ReactInstanceSettingsBuilder.g.cpp"
4
+ #include "ReactInstanceSettings.h"
5
+
6
+ namespace winrt::ReactNative {
7
+ using namespace winrt::Microsoft::ReactNative;
8
+ }
9
+
10
+ namespace winrt::UI {
11
+ using namespace winrt::Microsoft::UI;
12
+ }
13
+
14
+ namespace winrt::Microsoft::ReactNative::implementation {
15
+ ReactInstanceSettingsBuilder::ReactInstanceSettingsBuilder() {
16
+ m_reactInstanceSettings = winrt::make<winrt::ReactNative::implementation::ReactInstanceSettings>();
17
+ }
18
+
19
+ winrt::ReactNative::ReactInstanceSettings ReactInstanceSettingsBuilder::ReactInstanceSettings() {
20
+ return m_reactInstanceSettings;
21
+ }
22
+
23
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::UseDirectDebugger(bool const &state) {
24
+ m_reactInstanceSettings.UseDirectDebugger(state);
25
+
26
+ return *this;
27
+ }
28
+
29
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::UseDeveloperSupport(bool const &state) {
30
+ m_reactInstanceSettings.UseDeveloperSupport(state);
31
+
32
+ return *this;
33
+ }
34
+
35
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::BundleRootPath(hstring const &path) {
36
+ m_reactInstanceSettings.BundleRootPath(std::wstring(L"file://").append(path.c_str()).append(L"\\Bundle\\").c_str());
37
+
38
+ return *this;
39
+ }
40
+
41
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::DebugBundlePath(hstring const &path) {
42
+ m_reactInstanceSettings.DebugBundlePath(path.c_str());
43
+
44
+ return *this;
45
+ }
46
+
47
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::JavaScriptBundleFile(
48
+ hstring const &file) {
49
+ m_reactInstanceSettings.JavaScriptBundleFile(file.c_str());
50
+
51
+ return *this;
52
+ }
53
+
54
+ winrt::ReactNative::ReactInstanceSettingsBuilder ReactInstanceSettingsBuilder::UseFastRefresh(bool const &state) {
55
+ m_reactInstanceSettings.UseFastRefresh(state);
56
+
57
+ return *this;
58
+ }
59
+ } // namespace winrt::Microsoft::ReactNative::implementation
@@ -0,0 +1,23 @@
1
+ #pragma once
2
+ #include "ReactInstanceSettingsBuilder.g.h"
3
+
4
+ namespace winrt::Microsoft::ReactNative::implementation {
5
+ struct ReactInstanceSettingsBuilder : ReactInstanceSettingsBuilderT<ReactInstanceSettingsBuilder> {
6
+ ReactInstanceSettingsBuilder();
7
+
8
+ winrt::Microsoft::ReactNative::ReactInstanceSettings ReactInstanceSettings();
9
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder UseDirectDebugger(bool const &state);
10
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder UseDeveloperSupport(bool const &state);
11
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder BundleRootPath(hstring const &path);
12
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder DebugBundlePath(hstring const &path);
13
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder JavaScriptBundleFile(hstring const &file);
14
+ winrt::Microsoft::ReactNative::ReactInstanceSettingsBuilder UseFastRefresh(bool const &state);
15
+
16
+ private:
17
+ winrt::Microsoft::ReactNative::ReactInstanceSettings m_reactInstanceSettings{nullptr};
18
+ };
19
+ } // namespace winrt::Microsoft::ReactNative::implementation
20
+ namespace winrt::Microsoft::ReactNative::factory_implementation {
21
+ struct ReactInstanceSettingsBuilder
22
+ : ReactInstanceSettingsBuilderT<ReactInstanceSettingsBuilder, implementation::ReactInstanceSettingsBuilder> {};
23
+ } // namespace winrt::Microsoft::ReactNative::factory_implementation
@@ -0,0 +1,179 @@
1
+ #include "pch.h"
2
+ #include "ReactNativeAppBuilder.h"
3
+ #include "ReactNativeAppBuilder.g.cpp"
4
+ #include "IReactDispatcher.h"
5
+ #include "ReactNativeHost.h"
6
+ #include "ReactNativeWin32App.h"
7
+ #include "winrt/Microsoft.UI.Composition.h"
8
+ #include "winrt/Microsoft.UI.Dispatching.h"
9
+ #include "winrt/Microsoft.UI.Windowing.h"
10
+ #include "winrt/microsoft.UI.Interop.h"
11
+
12
+ // Scaling factor for the window's content based on the DPI of the display where the window is located.
13
+ float ScaleFactor(HWND hwnd) noexcept {
14
+ return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
15
+ }
16
+
17
+ void UpdateRootViewSizeToAppWindow(
18
+ winrt::Microsoft::ReactNative::ReactNativeIsland const &rootView,
19
+ winrt::Microsoft::UI::Windowing::AppWindow const &window) {
20
+ auto hwnd = winrt::Microsoft::UI::GetWindowFromWindowId(window.Id());
21
+ auto scaleFactor = ScaleFactor(hwnd);
22
+ winrt::Windows::Foundation::Size size{
23
+ window.ClientSize().Width / scaleFactor, window.ClientSize().Height / scaleFactor};
24
+ // Do not relayout when minimized
25
+ if (window.Presenter().as<winrt::Microsoft::UI::Windowing::OverlappedPresenter>().State() !=
26
+ winrt::Microsoft::UI::Windowing::OverlappedPresenterState::Minimized) {
27
+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
28
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
29
+ constraints.MaximumSize = constraints.MinimumSize = size;
30
+ rootView.Arrange(constraints, {0, 0});
31
+ }
32
+ }
33
+
34
+ namespace winrt::ReactNative {
35
+ using namespace winrt::Microsoft::ReactNative;
36
+ }
37
+
38
+ namespace winrt::UI {
39
+ using namespace winrt::Microsoft::UI;
40
+ }
41
+
42
+ namespace winrt::Microsoft::ReactNative::implementation {
43
+ ReactNativeAppBuilder::ReactNativeAppBuilder() {
44
+ m_reactNativeWin32App = winrt::make<implementation::ReactNativeWin32App>();
45
+ }
46
+
47
+ ReactNativeAppBuilder::~ReactNativeAppBuilder() {}
48
+
49
+ winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::AddPackageProviders(
50
+ winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::IReactPackageProvider> const
51
+ &packageProviders) {
52
+ for (auto const &provider : packageProviders) {
53
+ m_reactNativeWin32App.ReactNativeHost().PackageProviders().Append(provider);
54
+ }
55
+
56
+ return *this;
57
+ }
58
+
59
+ winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetReactInstanceSettings(
60
+ winrt::Microsoft::ReactNative::ReactInstanceSettings const &settings) {
61
+ m_reactNativeWin32App.ReactNativeHost().InstanceSettings(settings);
62
+
63
+ return *this;
64
+ }
65
+
66
+ winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetCompositor(
67
+ winrt::Microsoft::UI::Composition::Compositor const &compositor) {
68
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
69
+ return *this;
70
+ }
71
+
72
+ winrt::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetAppWindow(
73
+ winrt::Microsoft::UI::Windowing::AppWindow const &appWindow) {
74
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
75
+
76
+ return *this;
77
+ }
78
+
79
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder ReactNativeAppBuilder::SetReactViewOptions(
80
+ winrt::Microsoft::ReactNative::ReactViewOptions const &reactViewOptions) {
81
+ m_reactViewOptions = reactViewOptions;
82
+
83
+ return *this;
84
+ }
85
+
86
+ winrt::ReactNative::ReactNativeWin32App ReactNativeAppBuilder::Build() {
87
+ if (m_reactNativeWin32App.Compositor() == nullptr) {
88
+ // Create a DispatcherQueue for this thread. This is needed for Composition, Content, and
89
+ // Input APIs.
90
+ auto dispatcherQueueController =
91
+ winrt::Microsoft::UI::Dispatching::DispatcherQueueController::CreateOnCurrentThread();
92
+
93
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DispatchQueueController(
94
+ dispatcherQueueController);
95
+
96
+ // Create the compositor on behalf of the App Developer
97
+ auto compositor = winrt::Microsoft::UI::Composition::Compositor();
98
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->Compositor(compositor);
99
+ }
100
+
101
+ // Create the AppWindow if the developer doesn't provide one
102
+ if (m_reactNativeWin32App.AppWindow() == nullptr) {
103
+ auto appWindow = winrt::Microsoft::UI::Windowing::AppWindow::Create();
104
+ appWindow.Title(L"SampleApplication");
105
+ appWindow.Resize({1000, 1000});
106
+ appWindow.Show();
107
+
108
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->AppWindow(appWindow);
109
+ }
110
+
111
+ // Currently set the property to use current thread dispatcher as a default UI dispatcher.
112
+ // TODO: Provision for setting dispatcher based on the thread dispatcherQueueController is created.
113
+ m_reactNativeWin32App.ReactNativeHost().InstanceSettings().Properties().Set(
114
+ ReactDispatcherHelper::UIDispatcherProperty(), ReactDispatcherHelper::UIThreadDispatcher());
115
+
116
+ auto hwnd{winrt::UI::GetWindowFromWindowId(m_reactNativeWin32App.AppWindow().Id())};
117
+
118
+ winrt::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
119
+ m_reactNativeWin32App.ReactNativeHost().InstanceSettings().Properties(), reinterpret_cast<uint64_t>(hwnd));
120
+
121
+ winrt::ReactNative::Composition::CompositionUIService::SetCompositor(
122
+ m_reactNativeWin32App.ReactNativeHost().InstanceSettings(), m_reactNativeWin32App.Compositor());
123
+
124
+ // Start the react-native instance, which will create a JavaScript runtime and load the applications bundle.
125
+ m_reactNativeWin32App.ReactNativeHost().ReloadInstance();
126
+
127
+ // Create a RootView which will present a react-native component
128
+ auto reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland(m_reactNativeWin32App.Compositor());
129
+ reactNativeIsland.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(
130
+ m_reactNativeWin32App.ReactNativeHost(), m_reactViewOptions));
131
+
132
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->ReactNativeIsland(
133
+ std::move(reactNativeIsland));
134
+
135
+ // Update the size of the RootView when the AppWindow changes size
136
+ m_reactNativeWin32App.AppWindow().Changed(
137
+ [wkRootView = winrt::make_weak(m_reactNativeWin32App.ReactNativeIsland())](
138
+ winrt::Microsoft::UI::Windowing::AppWindow const &window,
139
+ winrt::Microsoft::UI::Windowing::AppWindowChangedEventArgs const &args) {
140
+ if (args.DidSizeChange() || args.DidVisibilityChange()) {
141
+ if (auto rootView = wkRootView.get()) {
142
+ UpdateRootViewSizeToAppWindow(rootView, window);
143
+ }
144
+ }
145
+ });
146
+
147
+ // Quit application when main window is closed
148
+ m_reactNativeWin32App.AppWindow().Destroying([this](
149
+ winrt::Microsoft::UI::Windowing::AppWindow const &window,
150
+ winrt::Windows::Foundation::IInspectable const & /*args*/) {
151
+ // Before we shutdown the application - unload the ReactNativeHost to give the javascript a chance to save any
152
+ // state
153
+ auto async = m_reactNativeWin32App.ReactNativeHost().UnloadInstance();
154
+ async.Completed([this](auto asyncInfo, winrt::Windows::Foundation::AsyncStatus asyncStatus) {
155
+ assert(asyncStatus == winrt::Windows::Foundation::AsyncStatus::Completed);
156
+ m_reactNativeWin32App.ReactNativeHost().InstanceSettings().UIDispatcher().Post([]() { PostQuitMessage(0); });
157
+ });
158
+ });
159
+
160
+ // DesktopChildSiteBridge create a ContentSite that can host the RootView ContentIsland
161
+ auto desktopChildSiteBridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
162
+ m_reactNativeWin32App.Compositor(), m_reactNativeWin32App.AppWindow().Id());
163
+
164
+ desktopChildSiteBridge.Connect(m_reactNativeWin32App.ReactNativeIsland().Island());
165
+
166
+ desktopChildSiteBridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
167
+
168
+ auto scaleFactor = ScaleFactor(hwnd);
169
+ m_reactNativeWin32App.ReactNativeIsland().ScaleFactor(scaleFactor);
170
+
171
+ UpdateRootViewSizeToAppWindow(reactNativeIsland, m_reactNativeWin32App.AppWindow());
172
+
173
+ m_reactNativeWin32App.as<implementation::ReactNativeWin32App>().get()->DesktopChildSiteBridge(
174
+ std::move(desktopChildSiteBridge));
175
+
176
+ return m_reactNativeWin32App;
177
+ }
178
+
179
+ } // namespace winrt::Microsoft::ReactNative::implementation
@@ -0,0 +1,35 @@
1
+ #pragma once
2
+ #include "ReactNativeAppBuilder.g.h"
3
+ #include <winrt/Microsoft.UI.Content.h>
4
+
5
+ namespace winrt::Microsoft::ReactNative::implementation {
6
+ struct ReactNativeAppBuilder : ReactNativeAppBuilderT<ReactNativeAppBuilder> {
7
+ ReactNativeAppBuilder();
8
+
9
+ ~ReactNativeAppBuilder();
10
+
11
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder AddPackageProviders(
12
+ winrt::Windows::Foundation::Collections::IVector<winrt::Microsoft::ReactNative::IReactPackageProvider> const
13
+ &packageProviders);
14
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetReactInstanceSettings(
15
+ winrt::Microsoft::ReactNative::ReactInstanceSettings const &settings);
16
+
17
+ // TODO: Currently, SetCompositor API is not exposed to the developer.
18
+ // Compositor depends on the DispatcherQueue created by DispatcherQueueController on a current thread
19
+ // or dedicated thread. So we also have to make a provision for setting DispatcherQueueController.
20
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetCompositor(
21
+ winrt::Microsoft::UI::Composition::Compositor const &compositor);
22
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetAppWindow(
23
+ winrt::Microsoft::UI::Windowing::AppWindow const &appWindow);
24
+ winrt::Microsoft::ReactNative::ReactNativeAppBuilder SetReactViewOptions(
25
+ winrt::Microsoft::ReactNative::ReactViewOptions const &reactViewOptions);
26
+ winrt::Microsoft::ReactNative::ReactNativeWin32App Build();
27
+
28
+ private:
29
+ winrt::Microsoft::ReactNative::ReactViewOptions m_reactViewOptions{};
30
+ winrt::Microsoft::ReactNative::ReactNativeWin32App m_reactNativeWin32App{nullptr};
31
+ };
32
+ } // namespace winrt::Microsoft::ReactNative::implementation
33
+ namespace winrt::Microsoft::ReactNative::factory_implementation {
34
+ struct ReactNativeAppBuilder : ReactNativeAppBuilderT<ReactNativeAppBuilder, implementation::ReactNativeAppBuilder> {};
35
+ } // namespace winrt::Microsoft::ReactNative::factory_implementation