react-native-windows 0.75.9 → 0.75.10

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 (49) hide show
  1. package/Microsoft.ReactNative/CompositionComponentView.idl +2 -1
  2. package/Microsoft.ReactNative/Fabric/AbiComponentDescriptor.cpp +4 -1
  3. package/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +1 -1
  4. package/Microsoft.ReactNative/Fabric/AbiViewProps.cpp +7 -0
  5. package/Microsoft.ReactNative/Fabric/AbiViewProps.h +2 -0
  6. package/Microsoft.ReactNative/Fabric/ComponentView.cpp +19 -4
  7. package/Microsoft.ReactNative/Fabric/ComponentView.h +8 -3
  8. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.cpp +931 -0
  9. package/Microsoft.ReactNative/Fabric/Composition/BorderPrimitive.h +80 -0
  10. package/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +31 -13
  11. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +27 -3
  12. package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +3 -1
  13. package/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +8 -32
  14. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +302 -895
  15. package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +26 -26
  16. package/Microsoft.ReactNative/Fabric/Composition/DebuggingOverlayComponentView.cpp +1 -1
  17. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +130 -122
  18. package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +14 -8
  19. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +34 -20
  20. package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +5 -3
  21. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.cpp +63 -2
  22. package/Microsoft.ReactNative/Fabric/Composition/ReactNativeIsland.h +12 -0
  23. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +51 -3
  24. package/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +3 -0
  25. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +18 -8
  26. package/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +3 -0
  27. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +46 -4
  28. package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +5 -0
  29. package/Microsoft.ReactNative/Fabric/Composition/Theme.cpp +9 -3
  30. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +11 -0
  31. package/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +2 -0
  32. package/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +1 -1
  33. package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +1 -0
  34. package/Microsoft.ReactNative/IReactViewComponentBuilder.idl +1 -1
  35. package/Microsoft.ReactNative/ReactNativeAppBuilder.cpp +25 -129
  36. package/Microsoft.ReactNative/ReactNativeAppBuilder.h +5 -13
  37. package/Microsoft.ReactNative/ReactNativeAppBuilder.idl +13 -34
  38. package/Microsoft.ReactNative/ReactNativeIsland.idl +3 -2
  39. package/Microsoft.ReactNative/ReactNativeWin32App.cpp +129 -18
  40. package/Microsoft.ReactNative/ReactNativeWin32App.h +14 -5
  41. package/Microsoft.ReactNative/ViewProps.idl +2 -0
  42. package/Microsoft.ReactNative.Cxx/ComponentView.Experimental.interop.h +14 -0
  43. package/PropertySheets/Generated/PackageVersion.g.props +3 -3
  44. package/Shared/Shared.vcxitems +3 -10
  45. package/Shared/Shared.vcxitems.filters +1 -0
  46. package/package.json +3 -3
  47. package/templates/cpp-app/windows/MyApp/MyApp.cpp +46 -130
  48. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.cpp +0 -59
  49. package/Microsoft.ReactNative/ReactInstanceSettingsBuilder.h +0 -23
@@ -8,6 +8,7 @@
8
8
  #include <Microsoft.ReactNative.Cxx/ReactContext.h>
9
9
  #include <react/renderer/components/view/ViewEventEmitter.h>
10
10
  #include <react/renderer/components/view/ViewProps.h>
11
+ #include "BorderPrimitive.h"
11
12
  #include "CompositionHelpers.h"
12
13
 
13
14
  #include "Composition.ComponentView.g.h"
@@ -19,12 +20,17 @@ struct CompContext;
19
20
 
20
21
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
21
22
 
23
+ struct FocusPrimitive {
24
+ std::shared_ptr<BorderPrimitive> m_focusInnerPrimitive;
25
+ std::shared_ptr<BorderPrimitive> m_focusOuterPrimitive;
26
+ winrt::com_ptr<ComponentView> m_focusVisualComponent{nullptr}; // The owning component of focus visuals being hosted
27
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_focusVisual{nullptr};
28
+ };
29
+
22
30
  struct ComponentView : public ComponentViewT<
23
31
  ComponentView,
24
32
  winrt::Microsoft::ReactNative::implementation::ComponentView,
25
33
  winrt::Microsoft::ReactNative::Composition::Experimental::IInternalComponentView> {
26
- static constexpr size_t SpecialBorderLayerCount = 8;
27
-
28
34
  ComponentView(
29
35
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
30
36
  facebook::react::Tag tag,
@@ -56,6 +62,7 @@ struct ComponentView : public ComponentViewT<
56
62
  void onGotFocus(const winrt::Microsoft::ReactNative::Composition::Input::RoutedEventArgs &args) noexcept override;
57
63
  bool CapturePointer(const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer) noexcept;
58
64
  void ReleasePointerCapture(const winrt::Microsoft::ReactNative::Composition::Input::Pointer &pointer) noexcept;
65
+ void SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept;
59
66
 
60
67
  std::vector<facebook::react::ComponentDescriptorProvider> supplementalComponentDescriptorProviders() noexcept
61
68
  override;
@@ -123,39 +130,32 @@ struct ComponentView : public ComponentViewT<
123
130
  winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext m_compContext;
124
131
  comp::CompositionPropertySet m_centerPropSet{nullptr};
125
132
  facebook::react::SharedViewEventEmitter m_eventEmitter;
126
- bool m_needsBorderUpdate{false};
127
- bool m_hasTransformMatrixFacade{false};
128
- bool m_enableFocusVisual{false};
129
- uint8_t m_numBorderVisuals{0};
130
133
 
131
134
  private:
132
- void updateBorderProps(
133
- const facebook::react::ViewProps &oldViewProps,
134
- const facebook::react::ViewProps &newViewProps) noexcept;
135
- void updateBorderLayoutMetrics(
135
+ void updateFocusLayoutMetrics() noexcept;
136
+ void updateClippingPath(
136
137
  facebook::react::LayoutMetrics const &layoutMetrics,
137
138
  const facebook::react::ViewProps &viewProps) noexcept;
138
- void finalizeBorderUpdates(
139
- facebook::react::LayoutMetrics const &layoutMetrics,
140
- const facebook::react::ViewProps &viewProps) noexcept;
141
- bool TryUpdateSpecialBorderLayers(
142
- winrt::Microsoft::ReactNative::Composition::implementation::Theme *theme,
143
- std::array<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual, SpecialBorderLayerCount>
144
- &spBorderVisuals,
145
- facebook::react::LayoutMetrics const &layoutMetrics,
146
- const facebook::react::ViewProps &viewProps) noexcept;
147
- std::array<winrt::Microsoft::ReactNative::Composition::Experimental::ISpriteVisual, SpecialBorderLayerCount>
148
- FindSpecialBorderLayers() const noexcept;
149
139
  void UpdateCenterPropertySet() noexcept;
150
140
  void FinalizeTransform(
151
141
  facebook::react::LayoutMetrics const &layoutMetrics,
152
142
  const facebook::react::ViewProps &viewProps) noexcept;
143
+ facebook::react::LayoutMetrics focusLayoutMetrics(bool inner) const noexcept;
144
+ facebook::react::BorderMetrics focusBorderMetrics(bool inner, const facebook::react::LayoutMetrics &layoutMetrics)
145
+ const noexcept;
146
+
147
+ virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual visualToHostFocus() noexcept;
148
+ virtual winrt::com_ptr<ComponentView> focusVisualRoot(const facebook::react::Rect &focusRect) noexcept;
153
149
 
154
- bool m_FinalizeTransform{false};
155
- bool m_tooltipTracked{false};
150
+ bool m_hasTransformMatrixFacade : 1 {false};
151
+ bool m_FinalizeTransform : 1 {false};
152
+ bool m_tooltipTracked : 1 {false};
156
153
  ComponentViewFeatures m_flags;
157
- void showFocusVisual(bool show) noexcept;
158
- winrt::Microsoft::ReactNative::Composition::Experimental::IFocusVisual m_focusVisual{nullptr};
154
+ void hostFocusVisual(bool show, winrt::com_ptr<ComponentView> view) noexcept;
155
+ winrt::com_ptr<ComponentView>
156
+ m_componentHostingFocusVisual; // The component that we are showing our focus visuals within
157
+ std::shared_ptr<BorderPrimitive> m_borderPrimitive;
158
+ std::unique_ptr<FocusPrimitive> m_focusPrimitive{nullptr};
159
159
  winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_outerVisual{nullptr};
160
160
  winrt::event<winrt::Windows::Foundation::EventHandler<winrt::IInspectable>> m_themeChangedEvent;
161
161
  };
@@ -169,6 +169,7 @@ struct ViewComponentView : public ViewComponentViewT<
169
169
  facebook::react::Tag tag,
170
170
  winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
171
171
 
172
+ virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual VisualToMountChildrenInto() noexcept;
172
173
  void MountChildComponentView(
173
174
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
174
175
  uint32_t index) noexcept override;
@@ -181,7 +182,6 @@ struct ViewComponentView : public ViewComponentViewT<
181
182
  facebook::react::LayoutMetrics const &layoutMetrics,
182
183
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
183
184
  void prepareForRecycle() noexcept override;
184
- bool TryFocus() noexcept;
185
185
  bool focusable() const noexcept override;
186
186
  void OnKeyDown(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
187
187
  void OnKeyUp(const winrt::Microsoft::ReactNative::Composition::Input::KeyRoutedEventArgs &args) noexcept override;
@@ -21,7 +21,7 @@ DebuggingOverlayComponentView::DebuggingOverlayComponentView(
21
21
  reactContext,
22
22
  ComponentViewFeatures::Default &
23
23
  ~(ComponentViewFeatures::Background | ComponentViewFeatures::ShadowProps |
24
- ComponentViewFeatures::NativeBorder)) {}
24
+ ComponentViewFeatures::NativeBorder | ComponentViewFeatures::FocusVisual)) {}
25
25
 
26
26
  void DebuggingOverlayComponentView::MountChildComponentView(
27
27
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
@@ -10,8 +10,16 @@
10
10
  #include "../CompositionDynamicAutomationProvider.h"
11
11
  #include "Unicode.h"
12
12
 
13
+ #include <DispatcherQueue.h>
14
+ #include <Fabric/ComponentView.h>
13
15
  #include <Fabric/Composition/CompositionContextHelper.h>
14
16
  #include <Fabric/Composition/CompositionUIService.h>
17
+ #include <Fabric/Composition/ReactNativeIsland.h>
18
+ #include <windows.ui.composition.interop.h>
19
+ #include <winrt/Microsoft.ReactNative.Composition.Experimental.h>
20
+ #include <winrt/Microsoft.UI.Content.h>
21
+ #include <winrt/Microsoft.UI.interop.h>
22
+ #include <winrt/Windows.UI.Composition.Desktop.h>
15
23
  #include <winrt/Windows.UI.Composition.h>
16
24
  #include "IReactContext.h"
17
25
  #include "ReactHost/ReactInstanceWin.h"
@@ -22,13 +30,15 @@ WindowsModalHostComponentView::WindowsModalHostComponentView(
22
30
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
23
31
  facebook::react::Tag tag,
24
32
  winrt::Microsoft::ReactNative::ReactContext const &reactContext)
25
- : Super(
26
- WindowsModalHostComponentView::defaultProps(),
27
- compContext,
28
- tag,
29
- reactContext,
30
- ComponentViewFeatures::Default & ~ComponentViewFeatures::Background) {
31
- m_context = reactContext; // save context
33
+ : Super(compContext, tag, reactContext) {}
34
+
35
+ WindowsModalHostComponentView::~WindowsModalHostComponentView() {
36
+ // Check if the window handle (m_hwnd) exists and destroy it if necessary
37
+ if (m_hwnd) {
38
+ // Close/Destroy the modal window
39
+ SendMessage(m_hwnd, WM_DESTROY, 0, 0);
40
+ m_hwnd = nullptr;
41
+ }
32
42
  }
33
43
 
34
44
  winrt::Microsoft::ReactNative::ComponentView WindowsModalHostComponentView::Create(
@@ -38,34 +48,36 @@ winrt::Microsoft::ReactNative::ComponentView WindowsModalHostComponentView::Crea
38
48
  return winrt::make<WindowsModalHostComponentView>(compContext, tag, reactContext);
39
49
  }
40
50
 
41
- // constants for creating a new windows (code mostly taken from LogBox)
51
+ // constants for creating a new windows
42
52
  constexpr PCWSTR c_modalWindowClassName = L"MS_REACTNATIVE_MODAL";
43
53
  constexpr auto CompHostProperty = L"CompHost";
44
- const int MODAL_DEFAULT_WIDTH = 500;
45
- const int MODAL_DEFAULT_HEIGHT = 500;
54
+ const int MODAL_MIN_WIDTH = 50;
55
+ const int MODAL_MIN_HEIGHT = 50;
56
+
57
+ float ScaleFactor(HWND hwnd) noexcept {
58
+ return GetDpiForWindow(hwnd) / static_cast<float>(USER_DEFAULT_SCREEN_DPI);
59
+ }
46
60
 
47
61
  // creates a new modal window
48
62
  void WindowsModalHostComponentView::EnsureModalCreated() {
49
63
  auto host =
50
- winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_context.Properties());
64
+ winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
65
+
51
66
  // return if hwnd already exists
52
67
  if (!host || m_hwnd) {
53
68
  return;
54
69
  }
55
70
 
56
- RegisterWndClass(); // creates and register a windows class
57
- auto CompositionHwndHost = winrt::Microsoft::ReactNative::CompositionHwndHost();
58
- winrt::Microsoft::ReactNative::ReactViewOptions viewOptions;
59
- viewOptions.ComponentName(L"Modal");
60
- CompositionHwndHost.ReactViewHost(winrt::Microsoft::ReactNative::ReactCoreInjection::MakeViewHost(host, viewOptions));
71
+ RegisterWndClass();
72
+
61
73
  HINSTANCE hInstance = GetModuleHandle(NULL);
62
- winrt::impl::abi<winrt::Microsoft::ReactNative::ICompositionHwndHost>::type *pHost{nullptr};
63
74
  winrt::com_ptr<::IUnknown> spunk;
64
- CompositionHwndHost.as(spunk);
65
75
 
66
76
  // get the root hwnd
67
- auto roothwnd = reinterpret_cast<HWND>(
68
- winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_context.Properties().Handle()));
77
+ m_prevWindowID =
78
+ winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_reactContext.Properties().Handle());
79
+
80
+ auto roothwnd = GetHwndForParenting();
69
81
 
70
82
  m_hwnd = CreateWindow(
71
83
  c_modalWindowClassName,
@@ -73,8 +85,8 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
73
85
  WS_OVERLAPPEDWINDOW,
74
86
  CW_USEDEFAULT,
75
87
  CW_USEDEFAULT,
76
- MODAL_DEFAULT_WIDTH,
77
- MODAL_DEFAULT_HEIGHT,
88
+ MODAL_MIN_WIDTH,
89
+ MODAL_MIN_HEIGHT,
78
90
  roothwnd, // parent
79
91
  nullptr,
80
92
  hInstance,
@@ -85,11 +97,47 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
85
97
  throw std::exception("Failed to create new hwnd for Modal: " + GetLastError());
86
98
  }
87
99
 
100
+ // Disable user sizing of the hwnd
101
+ ::SetWindowLong(m_hwnd, GWL_STYLE, GetWindowLong(m_hwnd, GWL_STYLE) & ~WS_SIZEBOX);
102
+
103
+ // set the top-level windows as the new hwnd
104
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
105
+ host.InstanceSettings().Properties(), reinterpret_cast<uint64_t>(m_hwnd));
106
+
107
+ // get current compositor - handles the creation/manipulation of visual objects
108
+ auto compositionContext = CompositionContext();
109
+ auto compositor =
110
+ winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::InnerCompositor(
111
+ compositionContext);
112
+
113
+ // create a react native island - code taken from CompositionHwndHost
114
+ auto bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create(
115
+ compositor, winrt::Microsoft::UI::GetWindowIdFromWindow(m_hwnd));
116
+ m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland(compositor, m_reactContext.Handle(), *this);
117
+ auto contentIsland = m_reactNativeIsland.Island();
118
+ bridge.Connect(contentIsland);
119
+ bridge.Show();
120
+
121
+ // set ScaleFactor
122
+ ScaleFactor(m_hwnd);
123
+
124
+ // set layout contraints
125
+ winrt::Microsoft::ReactNative::LayoutConstraints constraints;
126
+ constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
127
+
128
+ RECT rc;
129
+ GetClientRect(roothwnd, &rc);
130
+ // Maximum size is set to size of parent hwnd
131
+ constraints.MaximumSize = {(rc.right - rc.left) * ScaleFactor(m_hwnd), (rc.bottom - rc.top) / ScaleFactor(m_hwnd)};
132
+ constraints.MinimumSize = {MODAL_MIN_WIDTH * ScaleFactor(m_hwnd), MODAL_MIN_HEIGHT * ScaleFactor(m_hwnd)};
133
+ m_reactNativeIsland.Arrange(constraints, {0, 0});
134
+ bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow);
135
+
88
136
  spunk.detach();
89
137
  }
90
138
 
91
139
  void WindowsModalHostComponentView::ShowOnUIThread() {
92
- if (m_hwnd) {
140
+ if (m_hwnd && !IsWindowVisible(m_hwnd)) {
93
141
  ShowWindow(m_hwnd, SW_NORMAL);
94
142
  BringWindowToTop(m_hwnd);
95
143
  SetFocus(m_hwnd);
@@ -98,7 +146,15 @@ void WindowsModalHostComponentView::ShowOnUIThread() {
98
146
 
99
147
  void WindowsModalHostComponentView::HideOnUIThread() noexcept {
100
148
  if (m_hwnd) {
101
- ::ShowWindow(m_hwnd, SW_HIDE);
149
+ SendMessage(m_hwnd, WM_CLOSE, 0, 0);
150
+ }
151
+
152
+ // reset the topWindowID
153
+ if (m_prevWindowID) {
154
+ auto host =
155
+ winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
156
+ winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
157
+ host.InstanceSettings().Properties(), m_prevWindowID);
102
158
  }
103
159
  }
104
160
 
@@ -121,23 +177,22 @@ LRESULT CALLBACK ModalBoxWndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
121
177
  }
122
178
 
123
179
  switch (message) {
124
- case WM_NCCREATE: { // sent before WM_CREATE, lparam should be identical to members of CreateWindowEx
180
+ case WM_NCCREATE: { // called before WM_CREATE, lparam should be identical to members of CreateWindowEx
125
181
  auto createStruct = reinterpret_cast<CREATESTRUCT *>(lparam); // CreateStruct
126
182
  data = static_cast<::IUnknown *>(createStruct->lpCreateParams);
127
183
  SetProp(hwnd, CompHostProperty, data); // adds new properties to window
128
184
  break;
129
185
  }
130
- case WM_CREATE: { // recieves after window is created but before visible
131
- // host.Initialize((uint64_t)hwnd); cause Modal to throw a not registered error
132
- break;
133
- }
134
186
  case WM_CLOSE: {
135
187
  // Just hide the window instead of destroying it
136
188
  ::ShowWindow(hwnd, SW_HIDE);
137
189
  return 0;
138
190
  }
139
191
  case WM_DESTROY: { // called when we want to destroy the window
140
- data->Release();
192
+ ::ShowWindow(hwnd, SW_HIDE);
193
+ if (data) {
194
+ data->Release();
195
+ }
141
196
  SetProp(hwnd, CompHostProperty, nullptr);
142
197
  break;
143
198
  }
@@ -174,121 +229,74 @@ void WindowsModalHostComponentView::RegisterWndClass() noexcept {
174
229
  registered = true;
175
230
  }
176
231
 
232
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
233
+ WindowsModalHostComponentView::VisualToMountChildrenInto() noexcept {
234
+ return m_reactNativeIsland
235
+ .as<winrt::Microsoft::ReactNative::Composition::Experimental::IInternalCompositionRootView>()
236
+ .InternalRootVisual();
237
+ }
238
+
239
+ // childComponentView - reference to the child component view
240
+ // index - the position in which the childComponentView should be mounted
177
241
  void WindowsModalHostComponentView::MountChildComponentView(
178
242
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
179
243
  uint32_t index) noexcept {
180
- // Disabled due to partial Modal implementation. Tracking re-enablement with task list here:
181
- // https://github.com/microsoft/react-native-windows/issues/11157 assert(false);
244
+ EnsureModalCreated();
182
245
  base_type::MountChildComponentView(childComponentView, index);
183
246
  }
184
247
 
185
248
  void WindowsModalHostComponentView::UnmountChildComponentView(
186
249
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
187
250
  uint32_t index) noexcept {
188
- // Disabled due to partial Modal implementation.Tracking re-enablement with task list here : https : //
189
- // github.com/microsoft/react-native-windows/issues/11157 assert(false);
190
251
  base_type::UnmountChildComponentView(childComponentView, index);
191
252
  }
192
253
 
193
- void WindowsModalHostComponentView::HandleCommand(
194
- const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept {
195
- Super::HandleCommand(args);
254
+ void WindowsModalHostComponentView::updateLayoutMetrics(
255
+ facebook::react::LayoutMetrics const &layoutMetrics,
256
+ facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
257
+ base_type::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
258
+ if (m_hwnd) {
259
+ EnsureModalCreated();
260
+ AdjustWindowSize();
261
+ ShowOnUIThread();
262
+ }
196
263
  }
197
264
 
265
+ void WindowsModalHostComponentView::AdjustWindowSize() noexcept {
266
+ if (m_layoutMetrics.overflowInset.right == 0 && m_layoutMetrics.overflowInset.bottom == 0) {
267
+ return;
268
+ }
269
+ // Modal's size is based on it's children, use the overflow to calculate the width/height
270
+ float xPos = (-m_layoutMetrics.overflowInset.right * (m_layoutMetrics.pointScaleFactor));
271
+ float yPos = (-m_layoutMetrics.overflowInset.bottom * (m_layoutMetrics.pointScaleFactor));
272
+ RECT rc;
273
+ GetClientRect(m_hwnd, &rc);
274
+ RECT rect = {0, 0, (int)xPos, (int)yPos};
275
+ AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); // Adjust for title bar and borders
276
+ MoveWindow(m_hwnd, 0, 0, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true);
277
+
278
+ // set the layoutMetrics
279
+ m_layoutMetrics.frame.size = {
280
+ (float)rect.right - rect.left + m_layoutMetrics.frame.origin.x,
281
+ (float)rect.bottom - rect.top + m_layoutMetrics.frame.origin.y};
282
+ m_layoutMetrics.overflowInset.right = 0;
283
+ m_layoutMetrics.overflowInset.bottom = 0;
284
+
285
+ // Let RNWIsland know that Modal's size has changed
286
+ winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(m_reactNativeIsland)
287
+ ->NotifySizeChanged();
288
+ };
289
+
198
290
  void WindowsModalHostComponentView::updateProps(
199
291
  facebook::react::Props::Shared const &props,
200
292
  facebook::react::Props::Shared const &oldProps) noexcept {
201
293
  const auto &oldModalProps =
202
294
  *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(oldProps ? oldProps : viewProps());
203
295
  const auto &newModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(props);
204
-
205
- // currently Modal only gets Destroyed by closing the window
206
- if (newModalProps.visible) {
207
- EnsureModalCreated();
208
- ShowOnUIThread();
209
- }
210
-
296
+ newModalProps.visible ? m_isVisible = true : m_isVisible = false;
211
297
  base_type::updateProps(props, oldProps);
212
298
  }
213
299
 
214
- void WindowsModalHostComponentView::updateLayoutMetrics(
215
- facebook::react::LayoutMetrics const &layoutMetrics,
216
- facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept {
217
- Super::updateLayoutMetrics(layoutMetrics, oldLayoutMetrics);
218
-
219
- // Temporary placeholder for Modal, draws on main hwnd
220
- if (m_layoutMetrics.frame.size != layoutMetrics.frame.size ||
221
- m_layoutMetrics.pointScaleFactor != layoutMetrics.pointScaleFactor || m_layoutMetrics.frame.size.width == 0) {
222
- // Always make visual a min size, so that even if its laid out at zero size, its clear an unimplemented view was
223
- // rendered
224
- float width = std::max(m_layoutMetrics.frame.size.width, 200.0f);
225
- float height = std::max(m_layoutMetrics.frame.size.width, 50.0f);
226
-
227
- winrt::Windows::Foundation::Size surfaceSize = {
228
- width * m_layoutMetrics.pointScaleFactor, height * m_layoutMetrics.pointScaleFactor};
229
- auto drawingSurface = m_compContext.CreateDrawingSurfaceBrush(
230
- surfaceSize,
231
- winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized,
232
- winrt::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied);
233
-
234
- drawingSurface.HorizontalAlignmentRatio(0.f);
235
- drawingSurface.VerticalAlignmentRatio(0.f);
236
- drawingSurface.Stretch(winrt::Microsoft::ReactNative::Composition::Experimental::CompositionStretch::None);
237
- Visual().as<Experimental::ISpriteVisual>().Brush(drawingSurface);
238
- Visual().Size(surfaceSize);
239
- Visual().Offset({
240
- layoutMetrics.frame.origin.x * layoutMetrics.pointScaleFactor,
241
- layoutMetrics.frame.origin.y * layoutMetrics.pointScaleFactor,
242
- 0.0f,
243
- });
244
-
245
- POINT offset;
246
- {
247
- ::Microsoft::ReactNative::Composition::AutoDrawDrawingSurface autoDraw(
248
- drawingSurface, m_layoutMetrics.pointScaleFactor, &offset);
249
- if (auto d2dDeviceContext = autoDraw.GetRenderTarget()) {
250
- d2dDeviceContext->Clear(D2D1::ColorF(D2D1::ColorF::Blue, 0.3f));
251
- assert(d2dDeviceContext->GetUnitMode() == D2D1_UNIT_MODE_DIPS);
252
-
253
- float offsetX = static_cast<float>(offset.x / m_layoutMetrics.pointScaleFactor);
254
- float offsetY = static_cast<float>(offset.y / m_layoutMetrics.pointScaleFactor);
255
-
256
- winrt::com_ptr<IDWriteTextFormat> spTextFormat;
257
- winrt::check_hresult(::Microsoft::ReactNative::DWriteFactory()->CreateTextFormat(
258
- L"Segoe UI",
259
- nullptr, // Font collection (nullptr sets it to use the system font collection).
260
- DWRITE_FONT_WEIGHT_REGULAR,
261
- DWRITE_FONT_STYLE_NORMAL,
262
- DWRITE_FONT_STRETCH_NORMAL,
263
- 12,
264
- L"",
265
- spTextFormat.put()));
266
-
267
- winrt::com_ptr<ID2D1SolidColorBrush> textBrush;
268
- winrt::check_hresult(
269
- d2dDeviceContext->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), textBrush.put()));
270
-
271
- const D2D1_RECT_F rect = {
272
- static_cast<float>(offset.x), static_cast<float>(offset.y), width + offset.x, height + offset.y};
273
-
274
- auto label = ::Microsoft::Common::Unicode::Utf8ToUtf16(std::string("This is a Modal"));
275
- d2dDeviceContext->DrawText(
276
- label.c_str(),
277
- static_cast<UINT32>(label.length()),
278
- spTextFormat.get(),
279
- rect,
280
- textBrush.get(),
281
- D2D1_DRAW_TEXT_OPTIONS_NONE,
282
- DWRITE_MEASURING_MODE_NATURAL);
283
- }
284
- }
285
- }
286
- }
287
-
288
- void WindowsModalHostComponentView::updateState(
289
- facebook::react::State::Shared const &state,
290
- facebook::react::State::Shared const &oldState) noexcept {}
291
-
292
300
  facebook::react::SharedViewProps WindowsModalHostComponentView::defaultProps() noexcept {
293
301
  static auto const defaultProps = std::make_shared<facebook::react::ModalHostViewProps const>();
294
302
  return defaultProps;
@@ -9,34 +9,38 @@
9
9
  #include "Composition.WindowsModalHostComponentView.g.h"
10
10
  #include "../CompositionViewComponentView.h"
11
11
 
12
+ #include <Fabric/Composition/RootComponentView.h>
12
13
  #include <react/components/rnwcore/ShadowNodes.h>
13
14
 
14
15
  namespace winrt::Microsoft::ReactNative::Composition::implementation {
15
16
 
16
17
  struct WindowsModalHostComponentView
17
- : WindowsModalHostComponentViewT<WindowsModalHostComponentView, ViewComponentView> {
18
- using Super = WindowsModalHostComponentViewT<WindowsModalHostComponentView, ViewComponentView>;
18
+ : WindowsModalHostComponentViewT<WindowsModalHostComponentView, RootComponentView> {
19
+ using Super = WindowsModalHostComponentViewT<WindowsModalHostComponentView, RootComponentView>;
20
+
21
+ ~WindowsModalHostComponentView();
19
22
 
20
23
  [[nodiscard]] static winrt::Microsoft::ReactNative::ComponentView Create(
21
24
  const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
22
25
  facebook::react::Tag tag,
23
26
  winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept;
24
27
 
28
+ winrt::Microsoft::ReactNative::Composition::Experimental::IVisual VisualToMountChildrenInto() noexcept override;
25
29
  void MountChildComponentView(
26
30
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
27
31
  uint32_t index) noexcept override;
28
32
  void UnmountChildComponentView(
29
33
  const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
30
34
  uint32_t index) noexcept override;
31
- void HandleCommand(const winrt::Microsoft::ReactNative::HandleCommandArgs &args) noexcept override;
32
- void updateState(facebook::react::State::Shared const &state, facebook::react::State::Shared const &oldState) noexcept
33
- override;
34
35
 
35
- void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
36
- override;
36
+ void AdjustWindowSize() noexcept;
37
+
37
38
  void updateLayoutMetrics(
38
39
  facebook::react::LayoutMetrics const &layoutMetrics,
39
40
  facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;
41
+
42
+ void updateProps(facebook::react::Props::Shared const &props, facebook::react::Props::Shared const &oldProps) noexcept
43
+ override;
40
44
  static facebook::react::SharedViewProps defaultProps() noexcept;
41
45
  const facebook::react::ModalHostViewProps &modalHostViewProps() const noexcept;
42
46
  bool focusable() const noexcept override;
@@ -57,7 +61,9 @@ struct WindowsModalHostComponentView
57
61
 
58
62
  private:
59
63
  HWND m_hwnd{nullptr};
60
- winrt::Microsoft::ReactNative::ReactContext m_context;
64
+ uint64_t m_prevWindowID;
65
+ bool m_isVisible{false};
66
+ winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland;
61
67
  };
62
68
 
63
69
  } // namespace winrt::Microsoft::ReactNative::Composition::implementation
@@ -21,8 +21,10 @@ void ReactCompositionViewComponentBuilder::SetCreateProps(ViewPropsFactory impl)
21
21
  m_propsFactory = impl;
22
22
  }
23
23
 
24
- IComponentProps ReactCompositionViewComponentBuilder::CreateProps(ViewProps props) noexcept {
25
- return m_propsFactory(props);
24
+ IComponentProps ReactCompositionViewComponentBuilder::CreateProps(
25
+ ViewProps props,
26
+ const IComponentProps &cloneFrom) noexcept {
27
+ return m_propsFactory(props, cloneFrom);
26
28
  }
27
29
 
28
30
  void ReactCompositionViewComponentBuilder::CreateShadowNode(ShadowNode shadowNode) noexcept {
@@ -72,12 +74,15 @@ void ReactCompositionViewComponentBuilder::InitializeComponentView(
72
74
 
73
75
  void ReactCompositionViewComponentBuilder::SetComponentViewInitializer(
74
76
  const ComponentViewInitializer &initializer) noexcept {
75
- m_fnCreateView =
76
- [initializer](const IReactContext &reactContext, int32_t tag, const Experimental::ICompositionContext &context) {
77
- auto view = winrt::make<winrt::Microsoft::ReactNative::implementation::ComponentView>(tag, reactContext);
78
- initializer(view);
79
- return view;
80
- };
77
+ m_fnCreateView = [initializer](
78
+ const IReactContext &reactContext,
79
+ int32_t tag,
80
+ const Experimental::ICompositionContext &context,
81
+ ComponentViewFeatures) {
82
+ auto view = winrt::make<winrt::Microsoft::ReactNative::implementation::ComponentView>(tag, reactContext);
83
+ initializer(view);
84
+ return view;
85
+ };
81
86
  m_descriptorConstructorFactory = []() {
82
87
  return &facebook::react::concreteComponentDescriptorConstructor<::Microsoft::ReactNative::AbiComponentDescriptor>;
83
88
  };
@@ -85,14 +90,16 @@ void ReactCompositionViewComponentBuilder::SetComponentViewInitializer(
85
90
 
86
91
  void ReactCompositionViewComponentBuilder::SetViewComponentViewInitializer(
87
92
  const ViewComponentViewInitializer &initializer) noexcept {
88
- m_fnCreateView =
89
- [initializer](const IReactContext &reactContext, int32_t tag, const Experimental::ICompositionContext &context) {
90
- auto view = winrt::Microsoft::ReactNative::Composition::implementation::ViewComponentView::Create(
91
- context, tag, reactContext)
92
- .as<winrt::Microsoft::ReactNative::Composition::ViewComponentView>();
93
- initializer(view);
94
- return view;
95
- };
93
+ m_fnCreateView = [initializer](
94
+ const IReactContext &reactContext,
95
+ int32_t tag,
96
+ const Experimental::ICompositionContext &context,
97
+ ComponentViewFeatures features) {
98
+ auto view = winrt::make<implementation::ViewComponentView>(
99
+ implementation::ViewComponentView::defaultProps(), context, tag, reactContext, features);
100
+ initializer(view);
101
+ return view;
102
+ };
96
103
  m_descriptorConstructorFactory = []() {
97
104
  return &facebook::react::concreteComponentDescriptorConstructor<
98
105
  ::Microsoft::ReactNative::AbiViewComponentDescriptor>;
@@ -101,9 +108,12 @@ void ReactCompositionViewComponentBuilder::SetViewComponentViewInitializer(
101
108
 
102
109
  void ReactCompositionViewComponentBuilder::SetContentIslandComponentViewInitializer(
103
110
  const ComponentIslandComponentViewInitializer &initializer) noexcept {
104
- m_fnCreateView = [initializer](
105
- const IReactContext &reactContext, int32_t tag, const Experimental::ICompositionContext &context)
106
- -> winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView {
111
+ m_fnCreateView =
112
+ [initializer](
113
+ const IReactContext &reactContext,
114
+ int32_t tag,
115
+ const Experimental::ICompositionContext &context,
116
+ ComponentViewFeatures) -> winrt::Microsoft::ReactNative::Composition::ContentIslandComponentView {
107
117
  auto view = winrt::make<winrt::Microsoft::ReactNative::Composition::implementation::ContentIslandComponentView>(
108
118
  context, tag, reactContext);
109
119
  initializer(view);
@@ -186,12 +196,16 @@ void ReactCompositionViewComponentBuilder::SetCreateVisualHandler(CreateVisualDe
186
196
  m_createVisualHandler = impl;
187
197
  }
188
198
 
199
+ void ReactCompositionViewComponentBuilder::SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept {
200
+ m_features = viewFeatures;
201
+ }
202
+
189
203
  winrt::Microsoft::ReactNative::ComponentView ReactCompositionViewComponentBuilder::CreateView(
190
204
  const IReactContext &reactContext,
191
205
  int32_t tag,
192
206
  const Experimental::ICompositionContext &context) noexcept {
193
207
  assert(m_fnCreateView);
194
- auto view = m_fnCreateView(reactContext, tag, context);
208
+ auto view = m_fnCreateView(reactContext, tag, context, m_features);
195
209
  InitializeComponentView(view);
196
210
  return view;
197
211
  }
@@ -42,11 +42,11 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
42
42
  public: // Composition::IReactCompositionViewComponentBuilder
43
43
  void SetViewComponentViewInitializer(const ViewComponentViewInitializer &initializer) noexcept;
44
44
  void SetContentIslandComponentViewInitializer(const ComponentIslandComponentViewInitializer &initializer) noexcept;
45
-
46
45
  void SetCreateVisualHandler(CreateVisualDelegate impl) noexcept;
46
+ void SetViewFeatures(ComponentViewFeatures viewFeatures) noexcept;
47
47
 
48
48
  public:
49
- IComponentProps CreateProps(ViewProps props) noexcept;
49
+ IComponentProps CreateProps(ViewProps props, const IComponentProps &cloneFrom) noexcept;
50
50
  void CreateShadowNode(ShadowNode shadowNode) noexcept;
51
51
  void CloneShadowNode(ShadowNode shadowNode, ShadowNode sourceShadowNode) noexcept;
52
52
  winrt::Windows::Foundation::IInspectable InitialStateData(
@@ -69,10 +69,12 @@ struct ReactCompositionViewComponentBuilder : winrt::implements<
69
69
  InitialStateDataFactory m_initialStateDataFactory;
70
70
  winrt::Microsoft::ReactNative::MeasureContentHandler m_measureContent;
71
71
  winrt::Microsoft::ReactNative::LayoutHandler m_layoutHandler;
72
+ ComponentViewFeatures m_features{ComponentViewFeatures::Default};
72
73
  std::function<winrt::Microsoft::ReactNative::ComponentView(
73
74
  const IReactContext &reactContext,
74
75
  int32_t tag,
75
- const Experimental::ICompositionContext &context)>
76
+ const Experimental::ICompositionContext &context,
77
+ ComponentViewFeatures features)>
76
78
  m_fnCreateView;
77
79
  std::function<facebook::react::ComponentDescriptorConstructor *()> m_descriptorConstructorFactory;
78
80
  winrt::Microsoft::ReactNative::HandleCommandDelegate m_customCommandHandler;