From eadcba1fdc1e80d17f1401c2805859c1ee1e318c Mon Sep 17 00:00:00 2001 From: Tatiana Kapos Date: Wed, 15 Jan 2025 16:09:52 -0800 Subject: [PATCH 1/4] add modal implementation with PopupWindowSiteBridge --- .../WindowsModalHostViewComponentView.cpp | 73 ++++++++++++++++++- .../Fabric/Composition/ReactNativeIsland.cpp | 30 ++++---- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp index 6bb1de556d9..675f82695f0 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp @@ -37,6 +37,13 @@ struct ModalHostView : public winrt::implements( (parentRC.top + parentRC.bottom - layoutMetrics.Frame.Height * layoutMetrics.PointScaleFactor) / 2); +#ifdef USE_EXPERIMENTAL_WINUI3 + winrt::Windows::Graphics::RectInt32 rect2{ + (int)xCor, + (int)yCor, + static_cast(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)), + static_cast(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))}; + m_popUp.MoveAndResize(rect2); +#else // Adjust window position and size m_window.ResizeClient( {static_cast(layoutMetrics.Frame.Width * (layoutMetrics.PointScaleFactor)), static_cast(layoutMetrics.Frame.Height * (layoutMetrics.PointScaleFactor))}); m_window.Move({xCor, yCor}); +#endif }; void ShowOnUIThread(const winrt::Microsoft::ReactNative::ComponentView &view) { @@ -122,6 +137,24 @@ struct ModalHostView : public winrt::implements()); + auto result = navHost.NavigateFocus(winrt::Microsoft::UI::Input::FocusNavigationRequest::Create( + winrt::Microsoft::UI::Input::FocusNavigationReason::First)); + + // dispatch onShow event + if (auto eventEmitter = EventEmitter()) { + ::Microsoft::ReactNativeSpecs::ModalHostViewEventEmitter::OnShow eventArgs; + eventEmitter->onShow(eventArgs); + } + } +#endif + if (m_window && !m_window.IsVisible()) { m_bridge.Enable(); m_window.Show(true); @@ -146,6 +179,12 @@ struct ModalHostView : public winrt::implements()->GetHwndForParenting(); +#ifdef USE_EXPERIMENTAL_WINUI3 + m_bridge = winrt::Microsoft::UI::Content::DesktopChildSiteBridge::Create( + view.Parent().as().Compositor(), + winrt::Microsoft::UI::GetWindowIdFromWindow(m_parentHwnd)); + m_reactNativeIsland = winrt::Microsoft::ReactNative::ReactNativeIsland::CreatePortal( + view.as()); + auto contentIsland = m_reactNativeIsland.Island(); + + m_popUp = m_bridge.TryCreatePopupSiteBridge(); + m_popUp.Connect(contentIsland); + + auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge( + m_popUp.as()); + m_departFocusToken = navHost.DepartFocusRequested( + [wkView = winrt::make_weak(view)]( + const auto &sender, const winrt::Microsoft::UI::Input::FocusNavigationRequestEventArgs &args) { + if (auto strongView = wkView.get()) { + TrySetFocus(strongView.Parent()); + } + }); + + m_bridge.ResizePolicy(winrt::Microsoft::UI::Content::ContentSizePolicy::ResizeContentToParentWindow); +#else auto presenter = winrt::Microsoft::UI::Windowing::OverlappedPresenter::CreateForDialog(); presenter.SetBorderAndTitleBar(true, false); presenter.IsModal(true); @@ -202,9 +264,11 @@ struct ModalHostView : public winrt::implementsOnMounted(); - } - }); + if (!m_isFragment) { + m_islandConnectedToken = m_island.Connected( + [weakThis = get_weak()]( + winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) { + if (auto pThis = weakThis.get()) { + pThis->OnMounted(); + } + }); - m_islandDisconnectedToken = m_island.Disconnected( - [weakThis = get_weak()]( - winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) { - if (auto pThis = weakThis.get()) { - pThis->OnUnmounted(); - } - }); + m_islandDisconnectedToken = m_island.Disconnected( + [weakThis = get_weak()]( + winrt::IInspectable const &, winrt::Microsoft::UI::Content::ContentIsland const &island) { + if (auto pThis = weakThis.get()) { + pThis->OnUnmounted(); + } + }); + } #endif } return m_island; From 4e7feeb78662982dd8460610df321b54fec30c43 Mon Sep 17 00:00:00 2001 From: Tatiana Kapos Date: Wed, 15 Jan 2025 16:10:11 -0800 Subject: [PATCH 2/4] Change files --- ...ative-windows-6667ac90-8a6f-422f-917d-bba7f01145b6.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-6667ac90-8a6f-422f-917d-bba7f01145b6.json diff --git a/change/react-native-windows-6667ac90-8a6f-422f-917d-bba7f01145b6.json b/change/react-native-windows-6667ac90-8a6f-422f-917d-bba7f01145b6.json new file mode 100644 index 00000000000..937ef65b166 --- /dev/null +++ b/change/react-native-windows-6667ac90-8a6f-422f-917d-bba7f01145b6.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "add modal implementation with PopupWindowSiteBridge", + "packageName": "react-native-windows", + "email": "tatianakapos@microsoft.com", + "dependentChangeType": "patch" +} From 63899148dc250f3ee1e61c3417ab20b738e33c43 Mon Sep 17 00:00:00 2001 From: Tatiana Kapos Date: Thu, 16 Jan 2025 10:52:31 -0800 Subject: [PATCH 3/4] add conditional --- .../Modal/WindowsModalHostViewComponentView.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp index 675f82695f0..97b5cea9555 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp @@ -203,10 +203,15 @@ struct ModalHostView : public winrt::implements Date: Tue, 28 Jan 2025 13:20:29 -0800 Subject: [PATCH 4/4] feedback --- .../Composition/Modal/WindowsModalHostViewComponentView.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp index 97b5cea9555..509b5174d4f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/Modal/WindowsModalHostViewComponentView.cpp @@ -230,6 +230,11 @@ struct ModalHostView : public winrt::implements(winrt::Microsoft::UI::GetWindowFromWindowId(m_popUp.WindowId()))); + auto navHost = winrt::Microsoft::UI::Input::InputFocusNavigationHost::GetForSiteBridge( m_popUp.as()); m_departFocusToken = navHost.DepartFocusRequested( @@ -240,7 +245,6 @@ struct ModalHostView : public winrt::implements