react-native-windows 0.75.10 → 0.75.12
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.
- package/Libraries/Modal/Modal.windows.js +352 -0
- package/Microsoft.ReactNative/Fabric/ComponentView.cpp +26 -46
- package/Microsoft.ReactNative/Fabric/ComponentView.h +6 -19
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.cpp +160 -3
- package/Microsoft.ReactNative/Fabric/Composition/CompositionEventHandler.h +7 -0
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +15 -17
- package/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +6 -3
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.cpp +9 -2
- package/Microsoft.ReactNative/Fabric/Composition/ContentIslandComponentView.h +2 -1
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +59 -9
- package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.h +2 -0
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.cpp +78 -30
- package/Microsoft.ReactNative/Fabric/Composition/ReactCompositionViewComponentBuilder.h +21 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +8 -1
- package/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +3 -0
- package/Microsoft.ReactNative/IReactCompositionViewComponentBuilder.idl +25 -0
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/PropertySheets/React.Cpp.props +6 -0
- package/codegen/NativeAccessibilityInfoSpec.g.h +1 -0
- package/codegen/NativeAccessibilityManagerSpec.g.h +1 -0
- package/codegen/NativeActionSheetManagerSpec.g.h +1 -0
- package/codegen/NativeAlertManagerSpec.g.h +1 -0
- package/codegen/NativeAnimatedModuleSpec.g.h +1 -0
- package/codegen/NativeAnimatedTurboModuleSpec.g.h +1 -0
- package/codegen/NativeAppStateSpec.g.h +1 -0
- package/codegen/NativeAppThemeSpec.g.h +1 -0
- package/codegen/NativeAppearanceSpec.g.h +1 -0
- package/codegen/NativeBlobModuleSpec.g.h +1 -0
- package/codegen/NativeBugReportingSpec.g.h +1 -0
- package/codegen/NativeClipboardSpec.g.h +1 -0
- package/codegen/NativeDOMSpec.g.h +1 -0
- package/codegen/NativeDevLoadingViewSpec.g.h +1 -0
- package/codegen/NativeDevMenuSpec.g.h +1 -0
- package/codegen/NativeDevSettingsSpec.g.h +1 -0
- package/codegen/NativeDevToolsSettingsManagerSpec.g.h +1 -0
- package/codegen/NativeDeviceEventManagerSpec.g.h +1 -0
- package/codegen/NativeDeviceInfoSpec.g.h +1 -0
- package/codegen/NativeDialogManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeDialogManagerWindowsSpec.g.h +1 -0
- package/codegen/NativeExceptionsManagerSpec.g.h +1 -0
- package/codegen/NativeFileReaderModuleSpec.g.h +1 -0
- package/codegen/NativeFrameRateLoggerSpec.g.h +1 -0
- package/codegen/NativeHeadlessJsTaskSupportSpec.g.h +1 -0
- package/codegen/NativeI18nManagerSpec.g.h +1 -0
- package/codegen/NativeIdleCallbacksSpec.g.h +1 -0
- package/codegen/NativeImageEditorSpec.g.h +1 -0
- package/codegen/NativeImageLoaderAndroidSpec.g.h +1 -0
- package/codegen/NativeImageLoaderIOSSpec.g.h +1 -0
- package/codegen/NativeImageStoreAndroidSpec.g.h +1 -0
- package/codegen/NativeImageStoreIOSSpec.g.h +1 -0
- package/codegen/NativeIntentAndroidSpec.g.h +1 -0
- package/codegen/NativeIntersectionObserverSpec.g.h +1 -0
- package/codegen/NativeJSCHeapCaptureSpec.g.h +1 -0
- package/codegen/NativeJSCSamplingProfilerSpec.g.h +1 -0
- package/codegen/NativeKeyboardObserverSpec.g.h +1 -0
- package/codegen/NativeLinkingManagerSpec.g.h +1 -0
- package/codegen/NativeLogBoxSpec.g.h +1 -0
- package/codegen/NativeMicrotasksSpec.g.h +1 -0
- package/codegen/NativeModalManagerSpec.g.h +1 -0
- package/codegen/NativeMutationObserverSpec.g.h +1 -0
- package/codegen/NativeNetworkingAndroidSpec.g.h +1 -0
- package/codegen/NativeNetworkingIOSSpec.g.h +1 -0
- package/codegen/NativePerformanceObserverSpec.g.h +1 -0
- package/codegen/NativePerformanceSpec.g.h +1 -0
- package/codegen/NativePermissionsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsAndroidSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsIOSSpec.g.h +1 -0
- package/codegen/NativePlatformConstantsWindowsSpec.g.h +1 -0
- package/codegen/NativePushNotificationManagerIOSSpec.g.h +1 -0
- package/codegen/NativeReactNativeFeatureFlagsSpec.g.h +1 -0
- package/codegen/NativeRedBoxSpec.g.h +1 -0
- package/codegen/NativeSampleTurboModuleSpec.g.h +1 -0
- package/codegen/NativeSegmentFetcherSpec.g.h +1 -0
- package/codegen/NativeSettingsManagerSpec.g.h +1 -0
- package/codegen/NativeShareModuleSpec.g.h +1 -0
- package/codegen/NativeSoundManagerSpec.g.h +1 -0
- package/codegen/NativeSourceCodeSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerAndroidSpec.g.h +1 -0
- package/codegen/NativeStatusBarManagerIOSSpec.g.h +1 -0
- package/codegen/NativeTimingSpec.g.h +1 -0
- package/codegen/NativeToastAndroidSpec.g.h +1 -0
- package/codegen/NativeUIManagerSpec.g.h +1 -0
- package/codegen/NativeVibrationSpec.g.h +1 -0
- package/codegen/NativeWebSocketModuleSpec.g.h +1 -0
- package/package.json +3 -3
|
@@ -12,15 +12,18 @@
|
|
|
12
12
|
#include <Views/ShadowNodeBase.h>
|
|
13
13
|
#include <windows.h>
|
|
14
14
|
#include <windowsx.h>
|
|
15
|
+
#include <winrt/Windows.UI.Core.h>
|
|
15
16
|
#include <winrt/Windows.UI.Input.h>
|
|
16
17
|
#include "Composition.Input.h"
|
|
17
18
|
#include "CompositionViewComponentView.h"
|
|
18
19
|
#include "ReactNativeIsland.h"
|
|
19
20
|
#include "RootComponentView.h"
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
namespace ABI::Microsoft::UI::Input {
|
|
23
|
+
struct IInputCursor;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
#include <Microsoft.UI.Input.InputCursor.Interop.h>
|
|
24
27
|
|
|
25
28
|
namespace Microsoft::ReactNative {
|
|
26
29
|
|
|
@@ -328,6 +331,11 @@ CompositionEventHandler::~CompositionEventHandler() {
|
|
|
328
331
|
}
|
|
329
332
|
}
|
|
330
333
|
#endif
|
|
334
|
+
|
|
335
|
+
if (m_hcursorOwned) {
|
|
336
|
+
::DestroyCursor(m_hcursor);
|
|
337
|
+
m_hcursor = nullptr;
|
|
338
|
+
}
|
|
331
339
|
}
|
|
332
340
|
|
|
333
341
|
facebook::react::SurfaceId CompositionEventHandler::SurfaceId() const noexcept {
|
|
@@ -507,6 +515,10 @@ int64_t CompositionEventHandler::SendMessage(HWND hwnd, uint32_t msg, uint64_t w
|
|
|
507
515
|
}
|
|
508
516
|
break;
|
|
509
517
|
}
|
|
518
|
+
case WM_SETCURSOR: {
|
|
519
|
+
UpdateCursor();
|
|
520
|
+
return 1;
|
|
521
|
+
}
|
|
510
522
|
}
|
|
511
523
|
|
|
512
524
|
return 0;
|
|
@@ -753,6 +765,151 @@ void CompositionEventHandler::HandleIncomingPointerEvent(
|
|
|
753
765
|
hoveredViews.emplace_back(ReactTaggedView(componentViewDescriptor.view));
|
|
754
766
|
}
|
|
755
767
|
m_currentlyHoveredViewsPerPointer[pointerId] = std::move(hoveredViews);
|
|
768
|
+
|
|
769
|
+
if (IsMousePointerEvent(event)) {
|
|
770
|
+
UpdateCursor();
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
void CompositionEventHandler::UpdateCursor() noexcept {
|
|
775
|
+
for (auto &taggedView : m_currentlyHoveredViewsPerPointer[MOUSE_POINTER_ID]) {
|
|
776
|
+
if (auto view = taggedView.view()) {
|
|
777
|
+
if (auto viewcomponent =
|
|
778
|
+
view.try_as<winrt::Microsoft::ReactNative::Composition::implementation::ComponentView>()) {
|
|
779
|
+
auto cursorInfo = viewcomponent->cursor();
|
|
780
|
+
if (cursorInfo.first != facebook::react::Cursor::Auto || cursorInfo.second != nullptr) {
|
|
781
|
+
SetCursor(cursorInfo.first, cursorInfo.second);
|
|
782
|
+
return;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
SetCursor(facebook::react::Cursor::Auto, nullptr);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
void CompositionEventHandler::SetCursor(facebook::react::Cursor cursor, HCURSOR hcur) noexcept {
|
|
792
|
+
if (m_currentCursor == cursor && m_hcursor == hcur)
|
|
793
|
+
return;
|
|
794
|
+
|
|
795
|
+
if (auto strongRootView = m_wkRootView.get()) {
|
|
796
|
+
if (auto island = strongRootView.Island()) {
|
|
797
|
+
auto pointerSource = winrt::Microsoft::UI::Input::InputPointerSource::GetForIsland(island);
|
|
798
|
+
|
|
799
|
+
if (!hcur) {
|
|
800
|
+
winrt::Windows::UI::Core::CoreCursorType type = winrt::Windows::UI::Core::CoreCursorType::Arrow;
|
|
801
|
+
switch (cursor) {
|
|
802
|
+
case facebook::react::Cursor::Pointer:
|
|
803
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Hand;
|
|
804
|
+
break;
|
|
805
|
+
case facebook::react::Cursor::Help:
|
|
806
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Help;
|
|
807
|
+
break;
|
|
808
|
+
case facebook::react::Cursor::NotAllowed:
|
|
809
|
+
type = winrt::Windows::UI::Core::CoreCursorType::UniversalNo;
|
|
810
|
+
break;
|
|
811
|
+
case facebook::react::Cursor::Wait:
|
|
812
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Wait;
|
|
813
|
+
break;
|
|
814
|
+
case facebook::react::Cursor::Move:
|
|
815
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeAll;
|
|
816
|
+
break;
|
|
817
|
+
case facebook::react::Cursor::NESWResize:
|
|
818
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNortheastSouthwest;
|
|
819
|
+
break;
|
|
820
|
+
case facebook::react::Cursor::NSResize:
|
|
821
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNorthSouth;
|
|
822
|
+
break;
|
|
823
|
+
case facebook::react::Cursor::NWSEResize:
|
|
824
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeNorthwestSoutheast;
|
|
825
|
+
break;
|
|
826
|
+
case facebook::react::Cursor::EWResize:
|
|
827
|
+
type = winrt::Windows::UI::Core::CoreCursorType::SizeWestEast;
|
|
828
|
+
break;
|
|
829
|
+
case facebook::react::Cursor::Text:
|
|
830
|
+
type = winrt::Windows::UI::Core::CoreCursorType::IBeam;
|
|
831
|
+
break;
|
|
832
|
+
case facebook::react::Cursor::Progress:
|
|
833
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Wait; // IDC_APPSTARTING not mapped to CoreCursor?
|
|
834
|
+
break;
|
|
835
|
+
case facebook::react::Cursor::Crosshair:
|
|
836
|
+
type = winrt::Windows::UI::Core::CoreCursorType::Cross;
|
|
837
|
+
break;
|
|
838
|
+
default:
|
|
839
|
+
break;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
m_inputCursor = winrt::Microsoft::UI::Input::InputCursor::CreateFromCoreCursor(
|
|
843
|
+
winrt::Windows::UI::Core::CoreCursor(type, 0));
|
|
844
|
+
m_hcursor = hcur;
|
|
845
|
+
} else {
|
|
846
|
+
auto cursorInterop = winrt::get_activation_factory<
|
|
847
|
+
winrt::Microsoft::UI::Input::InputCursor,
|
|
848
|
+
ABI::Microsoft::UI::Input::IInputCursorStaticsInterop>();
|
|
849
|
+
winrt::com_ptr<IUnknown> spunk;
|
|
850
|
+
winrt::check_hresult(cursorInterop->CreateFromHCursor(
|
|
851
|
+
hcur, reinterpret_cast<ABI::Microsoft::UI::Input::IInputCursor **>(spunk.put_void())));
|
|
852
|
+
m_hcursor = hcur;
|
|
853
|
+
m_inputCursor = spunk.as<winrt::Microsoft::UI::Input::InputCursor>();
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
pointerSource.Cursor(m_inputCursor);
|
|
857
|
+
} else {
|
|
858
|
+
if (m_hcursorOwned) {
|
|
859
|
+
::DestroyCursor(m_hcursor);
|
|
860
|
+
m_hcursorOwned = false;
|
|
861
|
+
}
|
|
862
|
+
if (hcur == nullptr) {
|
|
863
|
+
const WCHAR *idc = IDC_ARROW;
|
|
864
|
+
switch (cursor) {
|
|
865
|
+
case facebook::react::Cursor::Pointer:
|
|
866
|
+
idc = IDC_HAND;
|
|
867
|
+
break;
|
|
868
|
+
case facebook::react::Cursor::Help:
|
|
869
|
+
idc = IDC_HELP;
|
|
870
|
+
break;
|
|
871
|
+
case facebook::react::Cursor::NotAllowed:
|
|
872
|
+
idc = IDC_NO;
|
|
873
|
+
break;
|
|
874
|
+
case facebook::react::Cursor::Wait:
|
|
875
|
+
idc = IDC_WAIT;
|
|
876
|
+
break;
|
|
877
|
+
case facebook::react::Cursor::Move:
|
|
878
|
+
idc = IDC_SIZEALL;
|
|
879
|
+
break;
|
|
880
|
+
case facebook::react::Cursor::NESWResize:
|
|
881
|
+
idc = IDC_SIZENESW;
|
|
882
|
+
break;
|
|
883
|
+
case facebook::react::Cursor::NSResize:
|
|
884
|
+
idc = IDC_SIZENS;
|
|
885
|
+
break;
|
|
886
|
+
case facebook::react::Cursor::NWSEResize:
|
|
887
|
+
idc = IDC_SIZENWSE;
|
|
888
|
+
break;
|
|
889
|
+
case facebook::react::Cursor::EWResize:
|
|
890
|
+
idc = IDC_SIZEWE;
|
|
891
|
+
break;
|
|
892
|
+
case facebook::react::Cursor::Text:
|
|
893
|
+
idc = IDC_IBEAM;
|
|
894
|
+
break;
|
|
895
|
+
case facebook::react::Cursor::Progress:
|
|
896
|
+
idc = IDC_APPSTARTING;
|
|
897
|
+
break;
|
|
898
|
+
case facebook::react::Cursor::Crosshair:
|
|
899
|
+
idc = IDC_CROSS;
|
|
900
|
+
break;
|
|
901
|
+
default:
|
|
902
|
+
break;
|
|
903
|
+
}
|
|
904
|
+
m_hcursor = ::LoadCursor(nullptr, idc);
|
|
905
|
+
m_hcursorOwned = true;
|
|
906
|
+
} else {
|
|
907
|
+
m_hcursor = hcur;
|
|
908
|
+
}
|
|
909
|
+
::SetCursor(m_hcursor);
|
|
910
|
+
}
|
|
911
|
+
m_currentCursor = cursor;
|
|
912
|
+
}
|
|
756
913
|
}
|
|
757
914
|
|
|
758
915
|
void CompositionEventHandler::UpdateActiveTouch(
|
|
@@ -147,6 +147,9 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
|
|
|
147
147
|
static void
|
|
148
148
|
UpdateActiveTouch(ActiveTouch &activeTouch, facebook::react::Point ptScaled, facebook::react::Point ptLocal) noexcept;
|
|
149
149
|
|
|
150
|
+
void UpdateCursor() noexcept;
|
|
151
|
+
void SetCursor(facebook::react::Cursor cursor, HCURSOR hcur) noexcept;
|
|
152
|
+
|
|
150
153
|
std::map<PointerId, ActiveTouch> m_activeTouches; // iOS is map of touch event args to ActiveTouch..?
|
|
151
154
|
PointerId m_touchId = 0;
|
|
152
155
|
int m_fragmentTag = -1;
|
|
@@ -157,6 +160,10 @@ class CompositionEventHandler : public std::enable_shared_from_this<CompositionE
|
|
|
157
160
|
|
|
158
161
|
facebook::react::Tag m_pointerCapturingComponentTag{-1}; // Component that has captured input
|
|
159
162
|
std::vector<PointerId> m_capturedPointers;
|
|
163
|
+
HCURSOR m_hcursor{nullptr};
|
|
164
|
+
bool m_hcursorOwned{false}; // If we create the cursor, so we need to destroy it
|
|
165
|
+
facebook::react::Cursor m_currentCursor{facebook::react::Cursor::Auto};
|
|
166
|
+
winrt::Microsoft::UI::Input::InputCursor m_inputCursor{nullptr};
|
|
160
167
|
|
|
161
168
|
#ifdef USE_WINUI3
|
|
162
169
|
winrt::event_token m_pointerPressedToken;
|
|
@@ -53,8 +53,9 @@ ComponentView::ComponentView(
|
|
|
53
53
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
54
54
|
facebook::react::Tag tag,
|
|
55
55
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
56
|
-
ComponentViewFeatures flags
|
|
57
|
-
|
|
56
|
+
ComponentViewFeatures flags,
|
|
57
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
|
|
58
|
+
: base_type(tag, reactContext, builder), m_compContext(compContext), m_flags(flags) {
|
|
58
59
|
m_outerVisual = compContext.CreateSpriteVisual(); // TODO could be a raw ContainerVisual if we had a
|
|
59
60
|
// CreateContainerVisual in ICompositionContext
|
|
60
61
|
}
|
|
@@ -791,6 +792,10 @@ void ComponentView::updateClippingPath(
|
|
|
791
792
|
}
|
|
792
793
|
}
|
|
793
794
|
|
|
795
|
+
std::pair<facebook::react::Cursor, HCURSOR> ComponentView::cursor() const noexcept {
|
|
796
|
+
return {viewProps()->cursor, nullptr};
|
|
797
|
+
}
|
|
798
|
+
|
|
794
799
|
void ComponentView::indexOffsetForBorder(uint32_t &index) const noexcept {
|
|
795
800
|
if (m_borderPrimitive) {
|
|
796
801
|
index += m_borderPrimitive->numberOfVisuals();
|
|
@@ -912,24 +917,15 @@ ViewComponentView::ViewComponentView(
|
|
|
912
917
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
913
918
|
facebook::react::Tag tag,
|
|
914
919
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
915
|
-
ComponentViewFeatures flags
|
|
916
|
-
|
|
920
|
+
ComponentViewFeatures flags,
|
|
921
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder)
|
|
922
|
+
: base_type(compContext, tag, reactContext, flags, builder),
|
|
917
923
|
m_props(defaultProps ? defaultProps : ViewComponentView::defaultProps()) {}
|
|
918
924
|
|
|
919
925
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual ViewComponentView::createVisual() noexcept {
|
|
920
926
|
return m_compContext.CreateSpriteVisual();
|
|
921
927
|
}
|
|
922
928
|
|
|
923
|
-
void ViewComponentView::CreateVisualHandler(
|
|
924
|
-
const winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate &handler) {
|
|
925
|
-
m_createVisualHandler = handler;
|
|
926
|
-
}
|
|
927
|
-
|
|
928
|
-
winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate ViewComponentView::CreateVisualHandler()
|
|
929
|
-
const noexcept {
|
|
930
|
-
return m_createVisualHandler;
|
|
931
|
-
}
|
|
932
|
-
|
|
933
929
|
void ViewComponentView::CreateInternalVisualHandler(
|
|
934
930
|
const winrt::Microsoft::ReactNative::Composition::Experimental::CreateInternalVisualDelegate &handler) {
|
|
935
931
|
m_createInternalVisualHandler = handler;
|
|
@@ -944,10 +940,10 @@ void ViewComponentView::ensureVisual() noexcept {
|
|
|
944
940
|
if (!m_visual) {
|
|
945
941
|
if (m_createInternalVisualHandler) {
|
|
946
942
|
m_visual = m_createInternalVisualHandler(*this);
|
|
947
|
-
} else if (
|
|
943
|
+
} else if (m_builder && m_builder->CreateVisualHandler()) {
|
|
948
944
|
m_visual =
|
|
949
945
|
winrt::Microsoft::ReactNative::Composition::Experimental::MicrosoftCompositionContextHelper::CreateVisual(
|
|
950
|
-
|
|
946
|
+
m_builder->CreateVisualHandler()(*this));
|
|
951
947
|
} else {
|
|
952
948
|
m_visual = createVisual();
|
|
953
949
|
}
|
|
@@ -965,6 +961,8 @@ winrt::Microsoft::ReactNative::ComponentView ViewComponentView::Create(
|
|
|
965
961
|
|
|
966
962
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual
|
|
967
963
|
ViewComponentView::VisualToMountChildrenInto() noexcept {
|
|
964
|
+
if (m_builder && m_builder->VisualToMountChildrenIntoHandler())
|
|
965
|
+
return m_builder->VisualToMountChildrenIntoHandler()(*this);
|
|
968
966
|
return Visual();
|
|
969
967
|
}
|
|
970
968
|
|
|
@@ -1212,7 +1210,7 @@ winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewProps() noexcept
|
|
|
1212
1210
|
|
|
1213
1211
|
winrt::Microsoft::ReactNative::ViewProps ViewComponentView::ViewPropsInner() noexcept {
|
|
1214
1212
|
// If we have AbiViewProps, then we dont need to new up a props wrapper
|
|
1215
|
-
if (
|
|
1213
|
+
if (m_builder) {
|
|
1216
1214
|
const auto &abiViewProps = *std::static_pointer_cast<const ::Microsoft::ReactNative::AbiViewProps>(m_props);
|
|
1217
1215
|
return abiViewProps.ViewProps();
|
|
1218
1216
|
}
|
|
@@ -35,7 +35,8 @@ struct ComponentView : public ComponentViewT<
|
|
|
35
35
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
36
36
|
facebook::react::Tag tag,
|
|
37
37
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
38
|
-
ComponentViewFeatures flags
|
|
38
|
+
ComponentViewFeatures flags,
|
|
39
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder);
|
|
39
40
|
virtual ~ComponentView();
|
|
40
41
|
|
|
41
42
|
virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual Visual() const noexcept {
|
|
@@ -106,6 +107,8 @@ struct ComponentView : public ComponentViewT<
|
|
|
106
107
|
void Toggle() noexcept override;
|
|
107
108
|
virtual winrt::Microsoft::ReactNative::implementation::ClipState getClipState() noexcept;
|
|
108
109
|
|
|
110
|
+
virtual std::pair<facebook::react::Cursor, HCURSOR> cursor() const noexcept;
|
|
111
|
+
|
|
109
112
|
const facebook::react::LayoutMetrics &layoutMetrics() const noexcept;
|
|
110
113
|
|
|
111
114
|
virtual std::string DefaultControlType() const noexcept;
|
|
@@ -206,7 +209,8 @@ struct ViewComponentView : public ViewComponentViewT<
|
|
|
206
209
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
207
210
|
facebook::react::Tag tag,
|
|
208
211
|
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
209
|
-
ComponentViewFeatures flags
|
|
212
|
+
ComponentViewFeatures flags,
|
|
213
|
+
winrt::Microsoft::ReactNative::Composition::ReactCompositionViewComponentBuilder *builder = nullptr);
|
|
210
214
|
|
|
211
215
|
virtual winrt::Microsoft::ReactNative::Composition::Experimental::IVisual createVisual() noexcept;
|
|
212
216
|
|
|
@@ -224,7 +228,6 @@ struct ViewComponentView : public ViewComponentViewT<
|
|
|
224
228
|
bool m_hasNonVisualChildren{false};
|
|
225
229
|
facebook::react::SharedViewProps m_props;
|
|
226
230
|
winrt::Microsoft::ReactNative::Composition::Experimental::IVisual m_visual{nullptr};
|
|
227
|
-
winrt::Microsoft::ReactNative::Composition::CreateVisualDelegate m_createVisualHandler{nullptr};
|
|
228
231
|
winrt::Microsoft::ReactNative::Composition::Experimental::CreateInternalVisualDelegate m_createInternalVisualHandler{
|
|
229
232
|
nullptr};
|
|
230
233
|
};
|
|
@@ -22,8 +22,15 @@ namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
|
22
22
|
ContentIslandComponentView::ContentIslandComponentView(
|
|
23
23
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
24
24
|
facebook::react::Tag tag,
|
|
25
|
-
winrt::Microsoft::ReactNative::ReactContext const &reactContext
|
|
26
|
-
|
|
25
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
26
|
+
ReactCompositionViewComponentBuilder *builder)
|
|
27
|
+
: base_type(
|
|
28
|
+
ViewComponentView::defaultProps(),
|
|
29
|
+
compContext,
|
|
30
|
+
tag,
|
|
31
|
+
reactContext,
|
|
32
|
+
ComponentViewFeatures::Default,
|
|
33
|
+
builder) {
|
|
27
34
|
m_mountedToken = Mounted([](const winrt::IInspectable &, const winrt::Microsoft::ReactNative::ComponentView &view) {
|
|
28
35
|
view.as<ContentIslandComponentView>()->OnMounted();
|
|
29
36
|
});
|
|
@@ -40,7 +40,8 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
|
|
|
40
40
|
ContentIslandComponentView(
|
|
41
41
|
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
|
|
42
42
|
facebook::react::Tag tag,
|
|
43
|
-
winrt::Microsoft::ReactNative::ReactContext const &reactContext
|
|
43
|
+
winrt::Microsoft::ReactNative::ReactContext const &reactContext,
|
|
44
|
+
ReactCompositionViewComponentBuilder *builder);
|
|
44
45
|
~ContentIslandComponentView() noexcept;
|
|
45
46
|
|
|
46
47
|
private:
|
package/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
#include "IReactContext.h"
|
|
25
25
|
#include "ReactHost/ReactInstanceWin.h"
|
|
26
26
|
#include "ReactNativeHost.h"
|
|
27
|
+
#include "WindowsModalHostViewShadowNode.h"
|
|
27
28
|
|
|
28
29
|
namespace winrt::Microsoft::ReactNative::Composition::implementation {
|
|
29
30
|
WindowsModalHostComponentView::WindowsModalHostComponentView(
|
|
@@ -33,6 +34,23 @@ WindowsModalHostComponentView::WindowsModalHostComponentView(
|
|
|
33
34
|
: Super(compContext, tag, reactContext) {}
|
|
34
35
|
|
|
35
36
|
WindowsModalHostComponentView::~WindowsModalHostComponentView() {
|
|
37
|
+
// dispatch onDismiss event
|
|
38
|
+
auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
|
|
39
|
+
facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
|
|
40
|
+
emitter->onDismiss(onDismissArgs);
|
|
41
|
+
|
|
42
|
+
// reset the topWindowID
|
|
43
|
+
if (m_prevWindowID) {
|
|
44
|
+
auto host =
|
|
45
|
+
winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
|
|
46
|
+
winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
|
|
47
|
+
host.InstanceSettings().Properties(), m_prevWindowID);
|
|
48
|
+
m_prevWindowID = 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// enable input to parent
|
|
52
|
+
EnableWindow(m_parentHwnd, true);
|
|
53
|
+
|
|
36
54
|
// Check if the window handle (m_hwnd) exists and destroy it if necessary
|
|
37
55
|
if (m_hwnd) {
|
|
38
56
|
// Close/Destroy the modal window
|
|
@@ -77,17 +95,19 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
|
|
|
77
95
|
m_prevWindowID =
|
|
78
96
|
winrt::Microsoft::ReactNative::ReactCoreInjection::GetTopLevelWindowId(m_reactContext.Properties().Handle());
|
|
79
97
|
|
|
80
|
-
|
|
98
|
+
m_parentHwnd = GetHwndForParenting();
|
|
99
|
+
|
|
100
|
+
auto windowsStyle = m_showTitleBar ? WS_OVERLAPPEDWINDOW : WS_POPUP;
|
|
81
101
|
|
|
82
102
|
m_hwnd = CreateWindow(
|
|
83
103
|
c_modalWindowClassName,
|
|
84
104
|
L"React-Native Modal",
|
|
85
|
-
|
|
105
|
+
windowsStyle,
|
|
86
106
|
CW_USEDEFAULT,
|
|
87
107
|
CW_USEDEFAULT,
|
|
88
108
|
MODAL_MIN_WIDTH,
|
|
89
109
|
MODAL_MIN_HEIGHT,
|
|
90
|
-
|
|
110
|
+
m_parentHwnd, // parent
|
|
91
111
|
nullptr,
|
|
92
112
|
hInstance,
|
|
93
113
|
spunk.get());
|
|
@@ -126,7 +146,7 @@ void WindowsModalHostComponentView::EnsureModalCreated() {
|
|
|
126
146
|
constraints.LayoutDirection = winrt::Microsoft::ReactNative::LayoutDirection::Undefined;
|
|
127
147
|
|
|
128
148
|
RECT rc;
|
|
129
|
-
GetClientRect(
|
|
149
|
+
GetClientRect(m_parentHwnd, &rc);
|
|
130
150
|
// Maximum size is set to size of parent hwnd
|
|
131
151
|
constraints.MaximumSize = {(rc.right - rc.left) * ScaleFactor(m_hwnd), (rc.bottom - rc.top) / ScaleFactor(m_hwnd)};
|
|
132
152
|
constraints.MinimumSize = {MODAL_MIN_WIDTH * ScaleFactor(m_hwnd), MODAL_MIN_HEIGHT * ScaleFactor(m_hwnd)};
|
|
@@ -141,6 +161,14 @@ void WindowsModalHostComponentView::ShowOnUIThread() {
|
|
|
141
161
|
ShowWindow(m_hwnd, SW_NORMAL);
|
|
142
162
|
BringWindowToTop(m_hwnd);
|
|
143
163
|
SetFocus(m_hwnd);
|
|
164
|
+
|
|
165
|
+
// disable input to parent
|
|
166
|
+
EnableWindow(m_parentHwnd, false);
|
|
167
|
+
|
|
168
|
+
// dispatch onShow event
|
|
169
|
+
auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
|
|
170
|
+
facebook::react::ModalHostViewEventEmitter::OnShow onShowArgs;
|
|
171
|
+
emitter->onShow(onShowArgs);
|
|
144
172
|
}
|
|
145
173
|
}
|
|
146
174
|
|
|
@@ -149,12 +177,21 @@ void WindowsModalHostComponentView::HideOnUIThread() noexcept {
|
|
|
149
177
|
SendMessage(m_hwnd, WM_CLOSE, 0, 0);
|
|
150
178
|
}
|
|
151
179
|
|
|
180
|
+
// dispatch onDismiss event
|
|
181
|
+
auto emitter = std::static_pointer_cast<const facebook::react::ModalHostViewEventEmitter>(m_eventEmitter);
|
|
182
|
+
facebook::react::ModalHostViewEventEmitter::OnDismiss onDismissArgs;
|
|
183
|
+
emitter->onDismiss(onDismissArgs);
|
|
184
|
+
|
|
185
|
+
// enable input to parent
|
|
186
|
+
EnableWindow(m_parentHwnd, true);
|
|
187
|
+
|
|
152
188
|
// reset the topWindowID
|
|
153
189
|
if (m_prevWindowID) {
|
|
154
190
|
auto host =
|
|
155
191
|
winrt::Microsoft::ReactNative::implementation::ReactNativeHost::GetReactNativeHost(m_reactContext.Properties());
|
|
156
192
|
winrt::Microsoft::ReactNative::ReactCoreInjection::SetTopLevelWindowId(
|
|
157
193
|
host.InstanceSettings().Properties(), m_prevWindowID);
|
|
194
|
+
m_prevWindowID = 0;
|
|
158
195
|
}
|
|
159
196
|
}
|
|
160
197
|
|
|
@@ -266,22 +303,32 @@ void WindowsModalHostComponentView::AdjustWindowSize() noexcept {
|
|
|
266
303
|
if (m_layoutMetrics.overflowInset.right == 0 && m_layoutMetrics.overflowInset.bottom == 0) {
|
|
267
304
|
return;
|
|
268
305
|
}
|
|
306
|
+
|
|
269
307
|
// Modal's size is based on it's children, use the overflow to calculate the width/height
|
|
270
308
|
float xPos = (-m_layoutMetrics.overflowInset.right * (m_layoutMetrics.pointScaleFactor));
|
|
271
309
|
float yPos = (-m_layoutMetrics.overflowInset.bottom * (m_layoutMetrics.pointScaleFactor));
|
|
272
310
|
RECT rc;
|
|
273
311
|
GetClientRect(m_hwnd, &rc);
|
|
274
312
|
RECT rect = {0, 0, (int)xPos, (int)yPos};
|
|
275
|
-
|
|
276
|
-
|
|
313
|
+
|
|
314
|
+
if (m_showTitleBar) {
|
|
315
|
+
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE); // Adjust for title bar and borders
|
|
316
|
+
}
|
|
277
317
|
|
|
278
318
|
// 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};
|
|
319
|
+
m_layoutMetrics.frame.size = {(float)rect.right - rect.left, (float)rect.bottom - rect.top};
|
|
282
320
|
m_layoutMetrics.overflowInset.right = 0;
|
|
283
321
|
m_layoutMetrics.overflowInset.bottom = 0;
|
|
284
322
|
|
|
323
|
+
// get Modal's position based on parent
|
|
324
|
+
RECT parentRC;
|
|
325
|
+
GetWindowRect(m_parentHwnd, &parentRC);
|
|
326
|
+
float xCor = (parentRC.left + parentRC.right - m_layoutMetrics.frame.size.width) / 2; // midpointx - width / 2
|
|
327
|
+
float yCor = (parentRC.top + parentRC.bottom - m_layoutMetrics.frame.size.height) / 2; // midpointy - height / 2
|
|
328
|
+
|
|
329
|
+
// Adjust window position and size
|
|
330
|
+
MoveWindow(m_hwnd, (int)xCor, (int)yCor, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true);
|
|
331
|
+
|
|
285
332
|
// Let RNWIsland know that Modal's size has changed
|
|
286
333
|
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ReactNativeIsland>(m_reactNativeIsland)
|
|
287
334
|
->NotifySizeChanged();
|
|
@@ -294,6 +341,9 @@ void WindowsModalHostComponentView::updateProps(
|
|
|
294
341
|
*std::static_pointer_cast<const facebook::react::ModalHostViewProps>(oldProps ? oldProps : viewProps());
|
|
295
342
|
const auto &newModalProps = *std::static_pointer_cast<const facebook::react::ModalHostViewProps>(props);
|
|
296
343
|
newModalProps.visible ? m_isVisible = true : m_isVisible = false;
|
|
344
|
+
if (!m_isVisible) {
|
|
345
|
+
HideOnUIThread();
|
|
346
|
+
}
|
|
297
347
|
base_type::updateProps(props, oldProps);
|
|
298
348
|
}
|
|
299
349
|
|
|
@@ -60,9 +60,11 @@ struct WindowsModalHostComponentView
|
|
|
60
60
|
static void RegisterWndClass() noexcept;
|
|
61
61
|
|
|
62
62
|
private:
|
|
63
|
+
HWND m_parentHwnd{nullptr};
|
|
63
64
|
HWND m_hwnd{nullptr};
|
|
64
65
|
uint64_t m_prevWindowID;
|
|
65
66
|
bool m_isVisible{false};
|
|
67
|
+
bool m_showTitleBar{false};
|
|
66
68
|
winrt::Microsoft::ReactNative::ReactNativeIsland m_reactNativeIsland;
|
|
67
69
|
};
|
|
68
70
|
|