react-native-windows 0.78.3 → 0.78.5

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 (30) hide show
  1. package/Libraries/Modal/Modal.windows.js +4 -1
  2. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.cpp +97 -0
  3. package/Microsoft.ReactNative/Fabric/AbiPortalShadowNode.h +53 -0
  4. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +160 -17
  5. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +182 -14
  6. package/Microsoft.ReactNative/Fabric/Composition/PortalComponentView.cpp +12 -0
  7. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +2 -1
  8. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +0 -1
  9. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +16 -14
  10. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +10 -1
  11. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  12. package/Shared/Networking/WinRTWebSocketResource.cpp +82 -96
  13. package/Shared/Networking/WinRTWebSocketResource.h +91 -7
  14. package/Shared/Shared.vcxitems +3 -3
  15. package/Shared/Shared.vcxitems.filters +1 -1
  16. package/codegen/react/components/rnwcore/ActivityIndicatorView.g.h +1 -1
  17. package/codegen/react/components/rnwcore/AndroidDrawerLayout.g.h +1 -1
  18. package/codegen/react/components/rnwcore/AndroidHorizontalScrollContentView.g.h +1 -1
  19. package/codegen/react/components/rnwcore/AndroidProgressBar.g.h +1 -1
  20. package/codegen/react/components/rnwcore/AndroidSwipeRefreshLayout.g.h +1 -1
  21. package/codegen/react/components/rnwcore/AndroidSwitch.g.h +1 -1
  22. package/codegen/react/components/rnwcore/DebuggingOverlay.g.h +1 -1
  23. package/codegen/react/components/rnwcore/InputAccessory.g.h +1 -1
  24. package/codegen/react/components/rnwcore/ModalHostView.g.h +1 -1
  25. package/codegen/react/components/rnwcore/PullToRefreshView.g.h +1 -1
  26. package/codegen/react/components/rnwcore/SafeAreaView.g.h +1 -1
  27. package/codegen/react/components/rnwcore/Switch.g.h +1 -1
  28. package/codegen/react/components/rnwcore/UnimplementedNativeView.g.h +1 -1
  29. package/package.json +3 -3
  30. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +0 -191
@@ -14,6 +14,24 @@
14
14
 
15
15
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
16
16
 
17
+ struct ModalHostState
18
+ : winrt::implements<ModalHostState, winrt::Microsoft::ReactNative::Composition::IPortalStateData> {
19
+ ModalHostState(winrt::Microsoft::ReactNative::LayoutConstraints layoutConstraints, float scaleFactor)
20
+ : m_layoutConstraints(layoutConstraints), m_pointScaleFactor(scaleFactor) {}
21
+
22
+ winrt::Microsoft::ReactNative::LayoutConstraints LayoutConstraints() const noexcept {
23
+ return m_layoutConstraints;
24
+ }
25
+
26
+ float PointScaleFactor() const noexcept {
27
+ return m_pointScaleFactor;
28
+ }
29
+
30
+ private:
31
+ float m_pointScaleFactor{1.0f};
32
+ winrt::Microsoft::ReactNative::LayoutConstraints m_layoutConstraints;
33
+ };
34
+
17
35
  struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::Foundation::IInspectable>,
18
36
  ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView> {
19
37
  ~ModalHostView() {
@@ -37,6 +55,13 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
37
55
  m_window.Destroy();
38
56
  m_window = nullptr;
39
57
  }
58
+
59
+ #ifdef USE_EXPERIMENTAL_WINUI3
60
+ if (m_popUp) {
61
+ m_popUp.Close();
62
+ m_popUp = nullptr;
63
+ }
64
+ #endif
40
65
  }
41
66
 
42
67
  void InitializePortalViewComponent(
@@ -65,13 +90,32 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
65
90
  ::Microsoft::ReactNativeSpecs::BaseModalHostView<ModalHostView>::UpdateProps(view, newProps, oldProps);
66
91
  }
67
92
 
68
- void UpdateLayoutMetrics(
69
- const winrt::Microsoft::ReactNative::ComponentView &view,
70
- const winrt::Microsoft::ReactNative::LayoutMetrics &newLayoutMetrics,
71
- const winrt::Microsoft::ReactNative::LayoutMetrics & /*oldLayoutMetrics*/) noexcept override {
72
- if (m_window) {
73
- AdjustWindowSize(newLayoutMetrics);
74
- }
93
+ void UpdateState(
94
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
95
+ const winrt::Microsoft::ReactNative::IComponentState &newState) noexcept override {
96
+ m_state = newState;
97
+ }
98
+
99
+ void MountChildComponentView(
100
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
101
+ const winrt::Microsoft::ReactNative::MountChildComponentViewArgs &args) noexcept override {
102
+ AdjustWindowSize(args.Child().LayoutMetrics());
103
+ assert(!m_childLayoutMetricsToken);
104
+ m_childLayoutMetricsToken = args.Child().LayoutMetricsChanged(
105
+ [wkThis = get_weak()](
106
+ auto &sender, const winrt::Microsoft::ReactNative::LayoutMetricsChangedArgs &layoutMetricsChangedArgs) {
107
+ if (auto strongThis = wkThis.get()) {
108
+ strongThis->AdjustWindowSize(layoutMetricsChangedArgs.NewLayoutMetrics());
109
+ }
110
+ });
111
+ }
112
+
113
+ void UnmountChildComponentView(
114
+ const winrt::Microsoft::ReactNative::ComponentView & /*view*/,
115
+ const winrt::Microsoft::ReactNative::UnmountChildComponentViewArgs &args) noexcept override {
116
+ assert(m_childLayoutMetricsToken);
117
+ args.Child().LayoutMetricsChanged(m_childLayoutMetricsToken);
118
+ m_childLayoutMetricsToken.value = 0;
75
119
  }
76
120
 
77
121
  void FinalizeUpdate(
@@ -85,7 +129,6 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
85
129
  private:
86
130
  void OnMounted(const winrt::Microsoft::ReactNative::ComponentView &view) noexcept {
87
131
  m_mounted = true;
88
-
89
132
  if (m_showQueued) {
90
133
  ShowOnUIThread(view);
91
134
  }
@@ -96,6 +139,14 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
96
139
  }
97
140
 
98
141
  void AdjustWindowSize(const winrt::Microsoft::ReactNative::LayoutMetrics &layoutMetrics) noexcept {
142
+ #ifdef USE_EXPERIMENTAL_WINUI3
143
+ if (!m_popUp) {
144
+ #else
145
+ if (!m_window) {
146
+ #endif
147
+ return;
148
+ }
149
+
99
150
  if (layoutMetrics.Frame.Width == 0 && layoutMetrics.Frame.Height == 0) {
100
151
  return;
101
152
  }
@@ -108,11 +159,23 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
108
159
  int32_t yCor = static_cast<int32_t>(
109
160
  (parentRC.top + parentRC.bottom - layoutMetrics.Frame.Height * layoutMetrics.PointScaleFactor) / 2);
110
161
 
162
+ #ifdef USE_EXPERIMENTAL_WINUI3
163
+ winrt::Windows::Graphics::RectInt32 rect2{
164
+ (int)xCor,
165
+ (int)yCor,
166
+ static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
167
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))};
168
+ m_popUp.MoveAndResize(rect2);
169
+ #else
170
+ // Fix for https://github.com/microsoft/microsoft-ui-xaml/issues/9529
171
+ auto titleBarHeight = m_window.TitleBar().Height();
172
+
111
173
  // Adjust window position and size
112
174
  m_window.ResizeClient(
113
175
  {static_cast<int32_t>(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)),
114
- static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))});
176
+ static_cast<int32_t>(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor)) - titleBarHeight});
115
177
  m_window.Move({xCor, yCor});
178
+ #endif
116
179
  };
117
180
 
118
181
  void ShowOnUIThread(const winrt::Microsoft::ReactNative::ComponentView &view) {
@@ -122,6 +185,24 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
122
185
  m_showQueued = false;
123
186
  EnsureModalCreated(view);
124
187
 
188
+ #ifdef USE_EXPERIMENTAL_WINUI3
189
+ if (m_popUp) {
190
+ m_bridge.Enable();
191
+ m_popUp.Show();
192
+
193
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
194
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
195
+ auto result = navHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create(
196
+ winrt::Microsoft::UI::Input::FocusNavigationReason::First));
197
+
198
+ // dispatch onShow event
199
+ if (auto eventEmitter = EventEmitter()) {
200
+ ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs;
201
+ eventEmitter->onShow(eventArgs);
202
+ }
203
+ }
204
+ #endif
205
+
125
206
  if (m_window && !m_window.IsVisible()) {
126
207
  m_bridge.Enable();
127
208
  m_window.Show(true);
@@ -146,6 +227,12 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
146
227
  m_window.Hide();
147
228
  }
148
229
 
230
+ #ifdef USE_EXPERIMENTAL_WINUI3
231
+ if (m_popUp) {
232
+ m_popUp.Hide();
233
+ }
234
+ #endif
235
+
149
236
  // dispatch onDismiss event
150
237
  if (auto eventEmitter = EventEmitter()) {
151
238
  ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnDismiss eventArgs;
@@ -168,6 +255,11 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
168
255
  return;
169
256
  }
170
257
 
258
+ #ifdef USE_EXPERIMENTAL_WINUI3
259
+ if (m_popUp) {
260
+ return;
261
+ }
262
+ #endif
171
263
  // get the root hwnd
172
264
  m_prevWindowID =
173
265
  winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(view.ReactContext().Properties());
@@ -175,6 +267,34 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
175
267
  m_parentHwnd =
176
268
  view.as<::Microsoft::ReactNative::Composition::Experimental::IComponentViewInterop>()->GetHwndForParenting();
177
269
 
270
+ auto portal = view.as<winrt::Microsoft::ReactNative::Composition::PortalComponentView>();
271
+
272
+ #ifdef USE_EXPERIMENTAL_WINUI3
273
+ m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
274
+ view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(),
275
+ winrt::Microsoft::UI::GetWindowIdFromWindow(m_parentHwnd));
276
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
277
+ auto contentIsland = m_reactNativeIsland.Island();
278
+
279
+ m_popUp = m_bridge.TryCreatePopupSiteBridge();
280
+ m_popUp.Connect(contentIsland);
281
+
282
+ // set the top-level windows as the new hwnd
283
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
284
+ view.ReactContext().Properties(),
285
+ reinterpret_cast<uint64_t>(winrt::Microsoft::UI::GetWindowFromWindowId(m_popUp.WindowId())));
286
+
287
+ auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(
288
+ m_popUp.as<winrt::Microsoft::UI::Content::IContentSiteBridge>());
289
+ m_departFocusToken = navHost.DepartFocusRequested(
290
+ [wkView = winrt::make_weak(view)](
291
+ const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) {
292
+ if (auto strongView = wkView.get()) {
293
+ TrySetFocus(strongView.Parent());
294
+ }
295
+ });
296
+
297
+ #else
178
298
  auto presenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::CreateForDialog();
179
299
  presenter.SetBorderAndTitleBar(true, false);
180
300
  presenter.IsModal(true);
@@ -190,8 +310,7 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
190
310
  // create a react native island - code taken from CompositionHwndHost
191
311
  m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
192
312
  view.Parent().as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Compositor(), m_window.Id());
193
- m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(
194
- view.as<winrt::Microsoft::ReactNative::Composition::PortalComponentView>());
313
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal(portal);
195
314
  auto contentIsland = m_reactNativeIsland.Island();
196
315
 
197
316
  auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge(m_bridge);
@@ -202,13 +321,56 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
202
321
  TrySetFocus(strongView.Parent());
203
322
  }
204
323
  });
205
-
206
- m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
207
324
  m_bridge.Connect(contentIsland);
208
- AdjustWindowSize(view.LayoutMetrics());
325
+ #endif
326
+ m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
327
+
328
+ m_islandStateChangedToken =
329
+ contentIsland.StateChanged([weakThis = get_weak()](
330
+ winrt::Microsoft::UI::Content::ContentIsland const &island,
331
+ winrt::Microsoft::UI::Content::ContentIslandStateChangedEventArgs const &args) {
332
+ if (auto pThis = weakThis.get()) {
333
+ if (args.DidRasterizationScaleChange() || args.DidLayoutDirectionChange()) {
334
+ pThis->UpdateConstraints();
335
+ }
336
+ }
337
+ });
338
+
339
+ UpdateConstraints();
340
+
341
+ if (portal.ContentRoot().Children().Size()) {
342
+ AdjustWindowSize(portal.ContentRoot().Children().GetAt(0).LayoutMetrics());
343
+ }
209
344
  m_bridge.Show();
210
345
  }
211
346
 
347
+ void UpdateConstraints() noexcept {
348
+ auto displayArea = winrt::Microsoft::UI::Windowing::DisplayArea::GetFromDisplayId(
349
+ m_bridge.SiteView().EnvironmentView().DisplayId());
350
+ auto workArea = displayArea.WorkArea();
351
+
352
+ float scale = m_reactNativeIsland.Island().RasterizationScale();
353
+
354
+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
355
+ constraints.MinimumSize = {0, 0};
356
+ // Constrain the size of the modal to 90% of the screen size
357
+ constraints.MaximumSize = {
358
+ static_cast<float>((workArea.Width / scale) * 0.9), static_cast<float>((workArea.Height / scale) * 0.9)};
359
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
360
+
361
+ auto layoutDirection = m_reactNativeIsland.Island().LayoutDirection();
362
+ if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::LeftToRight)
363
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::LeftToRight;
364
+ else if (layoutDirection == winrt::Microsoft::UI::Content::ContentLayoutDirection::RightToLeft)
365
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::RightToLeft;
366
+
367
+ // By setting a custom contraint here the behavior of the modal slightly changes.
368
+ // When no constraint is set (maxSize is std::numeric_limits<Float>::infinity()), yoga will layout the content to a
369
+ // desired size If we provide a specific max size, then contents with a flex:1 will expand to fill that size. We
370
+ // might want to provide a windows specific property to control this behavior.
371
+ m_state.UpdateState(winrt::make<ModalHostState>(constraints, m_reactNativeIsland.Island().RasterizationScale()));
372
+ }
373
+
212
374
  static void TrySetFocus(const winrt::Microsoft::ReactNative::ComponentView &view) {
213
375
  auto focusController = winrt::Microsoft::UI::Input::InputFocusController::GetForIsland(
214
376
  view.as<winrt::Microsoft::ReactNative::Composition::ComponentView>().Root().ReactNativeIsland().Island());
@@ -222,10 +384,16 @@ struct ModalHostView : public winrt::implements<ModalHostView, winrt::Windows::F
222
384
  bool m_showTitleBar{false};
223
385
  bool m_showQueued{false};
224
386
  bool m_mounted{false};
387
+ winrt::event_token m_islandStateChangedToken;
225
388
  winrt::Microsoft::UI::Input::InputFocusNavigationHost::DepartFocusRequested_revoker m_departFocusRevoker;
226
389
  winrt::event_token m_departFocusToken;
390
+ winrt::event_token m_childLayoutMetricsToken;
391
+ winrt::Microsoft::ReactNative::IComponentState m_state{nullptr};
227
392
  winrt::Microsoft::UI::Content::DesktopChildSiteBridge m_bridge{nullptr};
228
393
  winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland{nullptr};
394
+ #ifdef USE_EXPERIMENTAL_WINUI3
395
+ winrt::Microsoft::UI::Content::PopupWindowSiteBridge m_popUp{nullptr};
396
+ #endif
229
397
  };
230
398
 
231
399
  void RegisterWindowsModalHostNativeComponent(
@@ -30,11 +30,23 @@ void PortalComponentView::MountChildComponentView(
30
30
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
31
31
  uint32_t index) noexcept {
32
32
  m_rootComponentView->MountChildComponentView(childComponentView, index);
33
+ if (m_builder && m_builder->MountChildComponentViewHandler()) {
34
+ m_builder->MountChildComponentViewHandler()(
35
+ *this,
36
+ winrt::make<winrt::Microsoft::ReactNative::implementation::MountChildComponentViewArgs>(
37
+ childComponentView, index));
38
+ }
33
39
  }
34
40
 
35
41
  void PortalComponentView::UnmountChildComponentView(
36
42
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
37
43
  uint32_t index) noexcept {
44
+ if (m_builder && m_builder->UnmountChildComponentViewHandler()) {
45
+ m_builder->UnmountChildComponentViewHandler()(
46
+ *this,
47
+ winrt::make<winrt::Microsoft::ReactNative::implementation::UnmountChildComponentViewArgs>(
48
+ childComponentView, index));
49
+ }
38
50
  m_rootComponentView->UnmountChildComponentView(childComponentView, index);
39
51
  }
40
52
 
@@ -3,6 +3,7 @@
3
3
 
4
4
  #include "pch.h"
5
5
  #include "ReactCompositionViewComponentBuilder.h"
6
+ #include <Fabric/AbiViewComponentDescriptor.h>
6
7
  #include <Fabric/Composition/CompositionViewComponentView.h>
7
8
  #include <Fabric/Composition/ContentIslandComponentView.h>
8
9
  #include <Fabric/Composition/PortalComponentView.h>
@@ -128,7 +129,7 @@ void ReactCompositionViewComponentBuilder::SetPortalComponentViewInitializer(
128
129
  };
129
130
  m_descriptorConstructorFactory = []() {
130
131
  return &facebook::react::concreteComponentDescriptorConstructor<
131
- ::Microsoft::ReactNative::AbiViewComponentDescriptor>;
132
+ ::Microsoft::ReactNative::AbiPortalComponentDescriptor>;
132
133
  };
133
134
  }
134
135
 
@@ -3,7 +3,6 @@
3
3
  // Licensed under the MIT License.
4
4
 
5
5
  #include <Fabric/AbiComponentDescriptor.h>
6
- #include <Fabric/AbiViewComponentDescriptor.h>
7
6
  #include <react/renderer/componentregistry/ComponentDescriptorProvider.h>
8
7
  #include <react/renderer/core/ReactPrimitives.h>
9
8
  #include "winrt/Microsoft.ReactNative.Composition.Experimental.h"
@@ -913,21 +913,23 @@ winrt::Microsoft::UI::Content::ContentIsland ReactNativeIsland::Island() {
913
913
  }
914
914
  });
915
915
  #ifdef USE_EXPERIMENTAL_WINUI3
916
- m_islandConnectedToken = m_island.Connected(
917
- [weakThis = get_weak()](
918
- winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
919
- if (auto pThis = weakThis.get()) {
920
- pThis->OnMounted();
921
- }
922
- });
916
+ if (!m_isFragment) {
917
+ m_islandConnectedToken = m_island.Connected(
918
+ [weakThis = get_weak()](
919
+ winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
920
+ if (auto pThis = weakThis.get()) {
921
+ pThis->OnMounted();
922
+ }
923
+ });
923
924
 
924
- m_islandDisconnectedToken = m_island.Disconnected(
925
- [weakThis = get_weak()](
926
- winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
927
- if (auto pThis = weakThis.get()) {
928
- pThis->OnUnmounted();
929
- }
930
- });
925
+ m_islandDisconnectedToken = m_island.Disconnected(
926
+ [weakThis = get_weak()](
927
+ winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) {
928
+ if (auto pThis = weakThis.get()) {
929
+ pThis->OnUnmounted();
930
+ }
931
+ });
932
+ }
931
933
  #endif
932
934
  }
933
935
  return m_island;
@@ -52,6 +52,15 @@ namespace Microsoft.ReactNative.Composition
52
52
  };
53
53
  }
54
54
 
55
+ [webhosthidden]
56
+ [experimental]
57
+ DOC_STRING("StateData type to be used with a PortalComponentView. The LayoutConstraints and PointScaleFactor will be used to layout the content of the Portal")
58
+ interface IPortalStateData
59
+ {
60
+ Microsoft.ReactNative.LayoutConstraints LayoutConstraints { get; };
61
+ Single PointScaleFactor { get; };
62
+ };
63
+
55
64
  [webhosthidden]
56
65
  [experimental]
57
66
  DOC_STRING(".")
@@ -66,4 +75,4 @@ namespace Microsoft.ReactNative.Composition
66
75
  void SetVisualToMountChildrenIntoHandler(VisualToMountChildrenIntoDelegate impl);
67
76
  };
68
77
 
69
- } // namespace Microsoft.ReactNative
78
+ } // namespace Microsoft.ReactNative.Composition
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.78.3</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.78.5</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>78</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>3</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>5</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>04930ad6dce2cbc6d2e5d79760b13b77443912e4</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>70356efc9bee07541301328d98c4a78b7f89637f</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -89,7 +89,6 @@ DispatchQueue GetCurrentOrSerialQueue() noexcept {
89
89
 
90
90
  return queue;
91
91
  }
92
-
93
92
  } // namespace
94
93
 
95
94
  namespace Microsoft::React::Networking {
@@ -104,7 +103,6 @@ WinRTWebSocketResource2::WinRTWebSocketResource2(
104
103
  : m_socket{std::move(socket)},
105
104
  m_writer(std::move(writer)),
106
105
  m_readyState{ReadyState::Connecting},
107
- m_connectPerformed{CreateEvent(/*attributes*/ nullptr, /*manual reset*/ true, /*state*/ false, /*name*/ nullptr)},
108
106
  m_callingQueue{callingQueue} {
109
107
  for (const auto &certException : certExceptions) {
110
108
  m_socket.Control().IgnorableServerCertificateErrors().Append(certException);
@@ -221,120 +219,112 @@ void WinRTWebSocketResource2::OnClosed(IWebSocket const &sender, IWebSocketClose
221
219
 
222
220
  fire_and_forget WinRTWebSocketResource2::PerformConnect(Uri &&uri) noexcept {
223
221
  auto self = shared_from_this();
224
- auto coUri = std::move(uri);
222
+ auto movedUri = std::move(uri);
225
223
 
226
224
  co_await resume_in_queue(self->m_backgroundQueue);
227
225
 
228
- auto async = self->m_socket.ConnectAsync(coUri);
229
- co_await lessthrow_await_adapter<IAsyncAction>{async};
230
-
231
- co_await resume_in_queue(self->m_callingQueue);
232
-
233
- auto result = async.ErrorCode();
234
-
235
- try {
236
- if (result >= 0) { // Non-failing HRESULT
237
- co_await resume_in_queue(self->m_backgroundQueue);
238
- self->m_readyState = ReadyState::Open;
239
-
240
- co_await resume_in_queue(self->m_callingQueue);
241
- if (self->m_connectHandler) {
242
- self->m_connectHandler();
243
- }
244
- } else {
245
- self->Fail(std::move(result), ErrorType::Connection);
246
- }
247
- } catch (hresult_error const &e) {
248
- self->Fail(e, ErrorType::Connection);
249
- } catch (std::exception const &e) {
250
- self->Fail(e.what(), ErrorType::Connection);
251
- }
252
-
253
- SetEvent(self->m_connectPerformed.get());
226
+ co_await self->m_sequencer.QueueTaskAsync(
227
+ [self = self->shared_from_this(), coUri = std::move(movedUri)]() -> IAsyncAction {
228
+ auto coSelf = self->shared_from_this();
229
+
230
+ auto async = coSelf->m_socket.ConnectAsync(coUri);
231
+ co_await lessthrow_await_adapter<IAsyncAction>{async};
232
+
233
+ auto result = async.ErrorCode();
234
+ try {
235
+ if (result >= 0) { // Non-failing HRESULT
236
+ coSelf->m_readyState = ReadyState::Open;
237
+
238
+ co_await resume_in_queue(coSelf->m_callingQueue);
239
+ if (coSelf->m_connectHandler) {
240
+ coSelf->m_connectHandler();
241
+ }
242
+ } else {
243
+ coSelf->Fail(std::move(result), ErrorType::Connection);
244
+ }
245
+ } catch (hresult_error const &e) {
246
+ coSelf->Fail(e, ErrorType::Connection);
247
+ } catch (std::exception const &e) {
248
+ coSelf->Fail(e.what(), ErrorType::Connection);
249
+ }
250
+ });
254
251
  }
255
252
 
256
253
  fire_and_forget WinRTWebSocketResource2::PerformClose() noexcept {
257
254
  auto self = shared_from_this();
258
255
 
259
- co_await resume_on_signal(self->m_connectPerformed.get());
260
-
261
256
  co_await resume_in_queue(self->m_backgroundQueue);
262
257
 
263
- // See https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/close
264
- co_await self->SendPendingMessages();
258
+ co_await self->m_sequencer.QueueTaskAsync([self = self->shared_from_this()]() -> IAsyncAction {
259
+ auto coSelf = self->shared_from_this();
265
260
 
266
- try {
267
- self->m_socket.Close(static_cast<uint16_t>(m_closeCode), winrt::to_hstring(m_closeReason));
268
- self->m_readyState = ReadyState::Closing;
269
- } catch (winrt::hresult_invalid_argument const &e) {
270
- Fail(e, ErrorType::Close);
271
- } catch (hresult_error const &e) {
272
- Fail(e, ErrorType::Close);
273
- } catch (const std::exception &e) {
274
- Fail(e.what(), ErrorType::Close);
275
- }
261
+ try {
262
+ coSelf->m_socket.Close(static_cast<uint16_t>(coSelf->m_closeCode), winrt::to_hstring(coSelf->m_closeReason));
263
+ coSelf->m_readyState = ReadyState::Closing;
264
+ } catch (winrt::hresult_invalid_argument const &e) {
265
+ coSelf->Fail(e, ErrorType::Close);
266
+ } catch (hresult_error const &e) {
267
+ coSelf->Fail(e, ErrorType::Close);
268
+ } catch (const std::exception &e) {
269
+ coSelf->Fail(e.what(), ErrorType::Close);
270
+ }
271
+
272
+ co_return;
273
+ });
276
274
  }
277
275
 
278
- fire_and_forget WinRTWebSocketResource2::PerformWrite(string &&message, bool isBinary) noexcept {
276
+ fire_and_forget WinRTWebSocketResource2::EnqueueWrite(string &&message, bool isBinary) noexcept {
279
277
  auto self = shared_from_this();
280
278
  string coMessage = std::move(message);
281
279
 
282
- co_await resume_in_queue(self->m_backgroundQueue); // Ensure writes happen sequentially
283
- self->m_outgoingMessages.emplace(std::move(coMessage), isBinary);
284
-
285
- co_await resume_on_signal(self->m_connectPerformed.get());
286
-
287
280
  co_await resume_in_queue(self->m_backgroundQueue);
288
281
 
289
- co_await self->SendPendingMessages();
282
+ co_await self->m_sequencer.QueueTaskAsync(
283
+ [self = self->shared_from_this(), message = std::move(coMessage), isBinary]() -> IAsyncAction {
284
+ auto coSelf = self->shared_from_this();
285
+ auto coMessage = std::move(message);
286
+
287
+ co_await coSelf->PerformWrite(std::move(coMessage), isBinary);
288
+ });
290
289
  }
291
290
 
292
- IAsyncAction WinRTWebSocketResource2::SendPendingMessages() noexcept {
291
+ IAsyncAction WinRTWebSocketResource2::PerformWrite(string &&message, bool isBinary) noexcept {
293
292
  auto self = shared_from_this();
294
293
 
295
- while (!self->m_outgoingMessages.empty()) {
296
- if (self->m_readyState != ReadyState::Open) {
297
- co_return;
298
- }
299
-
300
- size_t length = 0;
301
- string messageLocal;
302
- bool isBinaryLocal;
303
- try {
304
- std::tie(messageLocal, isBinaryLocal) = self->m_outgoingMessages.front();
305
- self->m_outgoingMessages.pop();
306
- if (isBinaryLocal) {
307
- self->m_socket.Control().MessageType(SocketMessageType::Binary);
308
-
309
- auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(messageLocal));
310
- if (buffer) {
311
- length = buffer.Length();
312
- self->m_writer.WriteBuffer(buffer);
313
- }
314
- } else {
315
- self->m_socket.Control().MessageType(SocketMessageType::Utf8);
294
+ try {
295
+ if (isBinary) {
296
+ self->m_socket.Control().MessageType(SocketMessageType::Binary);
316
297
 
317
- length = messageLocal.size();
318
- winrt::array_view<const uint8_t> view(
319
- CheckedReinterpretCast<const uint8_t *>(messageLocal.c_str()),
320
- CheckedReinterpretCast<const uint8_t *>(messageLocal.c_str()) + messageLocal.length());
321
- self->m_writer.WriteBytes(view);
298
+ auto buffer = CryptographicBuffer::DecodeFromBase64String(winrt::to_hstring(message));
299
+ if (buffer) {
300
+ self->m_writer.WriteBuffer(buffer);
322
301
  }
323
- } catch (hresult_error const &e) { // TODO: Remove after fixing unit tests exceptions.
324
- self->Fail(e, ErrorType::Send);
325
- co_return;
326
- } catch (const std::exception &e) {
327
- self->Fail(e.what(), ErrorType::Send);
328
- co_return;
302
+ } else {
303
+ self->m_socket.Control().MessageType(SocketMessageType::Utf8);
304
+
305
+ winrt::array_view<const uint8_t> view(
306
+ CheckedReinterpretCast<const uint8_t *>(message.c_str()),
307
+ CheckedReinterpretCast<const uint8_t *>(message.c_str()) + message.length());
308
+ self->m_writer.WriteBytes(view);
329
309
  }
310
+ } catch (hresult_error const &e) { // TODO: Remove after fixing unit tests exceptions.
311
+ self->Fail(e, ErrorType::Send);
312
+ } catch (const std::exception &e) {
313
+ self->Fail(e.what(), ErrorType::Send);
314
+ }
330
315
 
331
- auto async = self->m_writer.StoreAsync();
332
- co_await lessthrow_await_adapter<DataWriterStoreOperation>{async};
316
+ co_await resume_in_queue(self->m_backgroundQueue);
317
+ // If an exception occurred, abort write process.
318
+ if (self->m_readyState != ReadyState::Open) {
319
+ co_return;
320
+ }
333
321
 
334
- auto result = async.ErrorCode();
335
- if (result < 0) {
336
- Fail(std::move(result), ErrorType::Send);
337
- }
322
+ auto async = self->m_writer.StoreAsync();
323
+ co_await lessthrow_await_adapter<DataWriterStoreOperation>{async};
324
+
325
+ auto result = async.ErrorCode();
326
+ if (result < 0) {
327
+ self->Fail(std::move(result), ErrorType::Send);
338
328
  }
339
329
  }
340
330
 
@@ -388,11 +378,7 @@ void WinRTWebSocketResource2::Connect(string &&url, const Protocols &protocols,
388
378
  m_socket.SetRequestHeader(L"Origin", std::move(origin));
389
379
  }
390
380
  } catch (hresult_error const &e) {
391
- Fail(e, ErrorType::Connection);
392
-
393
- SetEvent(m_connectPerformed.get());
394
-
395
- return;
381
+ return Fail(e, ErrorType::Connection);
396
382
  }
397
383
 
398
384
  PerformConnect(std::move(uri));
@@ -401,11 +387,11 @@ void WinRTWebSocketResource2::Connect(string &&url, const Protocols &protocols,
401
387
  void WinRTWebSocketResource2::Ping() noexcept {}
402
388
 
403
389
  void WinRTWebSocketResource2::Send(string &&message) noexcept {
404
- PerformWrite(std::move(message), false);
390
+ EnqueueWrite(std::move(message), false);
405
391
  }
406
392
 
407
393
  void WinRTWebSocketResource2::SendBinary(string &&base64String) noexcept {
408
- PerformWrite(std::move(base64String), true);
394
+ EnqueueWrite(std::move(base64String), true);
409
395
  }
410
396
 
411
397
  void WinRTWebSocketResource2::Close(CloseCode code, const string &reason) noexcept {