From 3828e289265bb09eba9f805e9e5ce187353a0c4a Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Tue, 18 Apr 2023 13:19:59 -0700 Subject: [PATCH 1/6] working impl of getBoundingRect and ElementProviderFromPoint --- .../Fabric/ComponentView.h | 2 +- .../AbiCompositionViewComponentView.cpp | 5 +- .../AbiCompositionViewComponentView.h | 2 +- .../Composition/ComponentViewRegistry.cpp | 2 +- .../CompositionDynamicAutomationProvider.cpp | 29 +++++++++-- .../CompositionRootAutomationProvider.cpp | 51 +++++++++++++++++-- .../CompositionViewComponentView.cpp | 8 +-- .../CompositionViewComponentView.h | 2 +- .../Fabric/Composition/ImageComponentView.cpp | 7 +-- .../Fabric/Composition/ImageComponentView.h | 2 +- .../Composition/ParagraphComponentView.cpp | 5 +- .../Composition/ParagraphComponentView.h | 2 +- .../Fabric/Composition/RootComponentView.cpp | 32 ++++++++++-- .../Fabric/Composition/RootComponentView.h | 9 +++- .../Composition/ScrollViewComponentView.cpp | 6 +-- .../Composition/ScrollViewComponentView.h | 2 +- .../Composition/SwitchComponentView.cpp | 4 +- .../Fabric/Composition/SwitchComponentView.h | 2 +- .../WindowsTextInputComponentView.cpp | 4 +- .../TextInput/WindowsTextInputComponentView.h | 2 +- .../Fabric/Composition/UiaHelpers.cpp | 24 +++++++-- .../Fabric/Composition/UiaHelpers.h | 3 ++ .../UnimplementedNativeViewComponentView.cpp | 5 +- .../UnimplementedNativeViewComponentView.h | 2 +- 24 files changed, 167 insertions(+), 45 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h index 456ba502155..3cf4a89cc4f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h @@ -60,7 +60,7 @@ struct IComponentView { virtual facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept = 0; virtual facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept = 0; virtual facebook::react::Tag tag() const noexcept = 0; - virtual facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept = 0; + virtual facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept = 0; virtual int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept = 0; virtual winrt::IInspectable EnsureUiaProvider() noexcept = 0; }; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp index 717cffc534e..ca45969953d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp @@ -119,10 +119,11 @@ winrt::Microsoft::ReactNative::Composition::IVisual AbiCompositionViewComponentV facebook::react::Tag AbiCompositionViewComponentView::hitTest( facebook::react::Point pt, - facebook::react::Point &localPt) const noexcept { + facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || + m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h index 0b59d40a095..540918d9d89 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h @@ -43,7 +43,7 @@ struct AbiCompositionViewComponentView : CompositionBaseComponentView { std::vector supplementalComponentDescriptorProviders() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; private: diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp index a10a337a714..b1fa25d5f51 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ComponentViewRegistry.cpp @@ -58,7 +58,7 @@ ComponentViewDescriptor const &ComponentViewRegistry::dequeueComponentViewWithCo } else if (componentHandle == facebook::react::SwitchShadowNode::Handle()) { view = SwitchComponentView::Create(compContext, tag, m_context); } else if (componentHandle == facebook::react::RootShadowNode::Handle()) { - view = RootComponentView::Create(compContext, tag); + view = RootComponentView::Create(compContext, tag, m_context); } else if ( componentHandle == facebook::react::RawTextShadowNode::Handle() || componentHandle == facebook::react::TextShadowNode::Handle()) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index 6edf62b2b55..7ff4237418f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -59,6 +59,27 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_BoundingRectangle(Ui if (pRetVal == nullptr) return E_POINTER; + auto hr = UiaGetBoundingRectangleHelper(m_view, *pRetVal); + if (FAILED(hr)) + return hr; + + winrt::com_ptr spFragmentRoot = nullptr; + hr = get_FragmentRoot(spFragmentRoot.put()); + if (FAILED(hr)) + return hr; + + auto spFragment = spFragmentRoot.try_as(); + if (spFragment == nullptr) + return E_FAIL; + + UiaRect rect; + hr = spFragment->get_BoundingRectangle(&rect); + if (FAILED(hr)) + return hr; + + pRetVal->left += rect.left; + pRetVal->top += rect.top; + return S_OK; } @@ -89,10 +110,9 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_FragmentRoot(IRawEle return UIA_E_ELEMENTNOTAVAILABLE; auto uiaProvider = rootCV->EnsureUiaProvider(); - if (uiaProvider != nullptr) { - winrt::com_ptr spReps; - uiaProvider.as(spReps); - *pRetVal = spReps.detach(); + auto spFragmentRoot = uiaProvider.try_as(); + if (spFragmentRoot) { + *pRetVal = spFragmentRoot.detach(); } return S_OK; @@ -184,6 +204,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT if (strongView == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; + // TODO auto props = std::static_pointer_cast(strongView->props()); if (props == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp index 3b6b3282abb..492ff230844 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp @@ -55,6 +55,7 @@ HRESULT __stdcall CompositionRootAutomationProvider::get_HostRawElementProvider( if (pRetVal == nullptr) return E_POINTER; + // TODO: assumes windowed if (!IsWindow(m_hwnd)) return UIA_E_ELEMENTNOTAVAILABLE; @@ -67,6 +68,24 @@ HRESULT __stdcall CompositionRootAutomationProvider::get_BoundingRectangle(UiaRe if (pRetVal == nullptr) return E_POINTER; + // TODO: Need host site offsets + // Assume we're hosted in some other visual-based hosting site + if (m_hwnd == nullptr || !IsWindow(m_hwnd)) { + return UiaGetBoundingRectangleHelper(m_view, *pRetVal); + } + + POINT point{0, 0}; + ClientToScreen(m_hwnd, &point); + pRetVal->left = point.x; + pRetVal->top = point.y; + RECT rect; + GetClientRect(m_hwnd, &rect); + point.x = rect.right; + point.y = rect.bottom; + ClientToScreen(m_hwnd, &point); + pRetVal->width = point.x - pRetVal->left; + pRetVal->height = point.y - pRetVal->top; + return S_OK; } @@ -97,6 +116,31 @@ HRESULT __stdcall CompositionRootAutomationProvider::ElementProviderFromPoint( *pRetVal = nullptr; + auto strongView = m_view.view(); + + if (strongView == nullptr) { + return UIA_E_ELEMENTNOTAVAILABLE; + } + + auto spRootView = strongView->rootComponentView(); + if (spRootView == nullptr) { + return UIA_E_ELEMENTNOTAVAILABLE; + } + + if (m_hwnd == nullptr || !IsWindow(m_hwnd)) { + // TODO + return E_FAIL; + } + + POINT clientPoint{static_cast(x), static_cast(y)}; + ScreenToClient(m_hwnd, &clientPoint); + + auto provider = spRootView->UiaProviderFromPoint(clientPoint); + auto spFragment = provider.try_as(); + if (spFragment) { + *pRetVal = spFragment.detach(); + } + return S_OK; } @@ -117,9 +161,10 @@ HRESULT __stdcall CompositionRootAutomationProvider::GetFocus(IRawElementProvide if (focusedComponent) { auto focusedUiaProvider = focusedComponent->EnsureUiaProvider(); - winrt::com_ptr spFragment; - focusedUiaProvider.as(spFragment); - *pRetVal = spFragment.detach(); + auto spFragment = focusedUiaProvider.try_as(); + if (spFragment) { + *pRetVal = spFragment.detach(); + } } return S_OK; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index 658ea0fd3cd..18fc28fdd1f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -1267,13 +1267,14 @@ void CompositionViewComponentView::updateProps( m_props = std::static_pointer_cast(props); } -facebook::react::Tag CompositionViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag CompositionViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || + m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) && std::any_of(m_children.rbegin(), m_children.rend(), [&targetTag, &ptLocal, &localPt](auto child) { targetTag = static_cast(child)->hitTest(ptLocal, localPt); @@ -1281,7 +1282,8 @@ facebook::react::Tag CompositionViewComponentView::hitTest(facebook::react::Poin })) return targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || + m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h index f2c41f62feb..3a9d1f35c2d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h @@ -114,7 +114,7 @@ struct CompositionViewComponentView : public CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept override; bool ScrollWheel(facebook::react::Point pt, int32_t delta) noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp index f445eb1dc2b..5822813c723 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp @@ -362,13 +362,14 @@ facebook::react::Props::Shared ImageComponentView::props() noexcept { return m_props; } -facebook::react::Tag ImageComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag ImageComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || + m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) && std::any_of(m_children.rbegin(), m_children.rend(), [&targetTag, &ptLocal, &localPt](auto child) { targetTag = static_cast(child)->hitTest(ptLocal, localPt); @@ -376,7 +377,7 @@ facebook::react::Tag ImageComponentView::hitTest(facebook::react::Point pt, face })) return targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h index f324f52a536..0cfaed8a872 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h @@ -49,7 +49,7 @@ struct ImageComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; void OnRenderingDeviceLost() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; bool focusable() const noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp index 4804d964bb9..5571a40b6f9 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp @@ -99,7 +99,7 @@ facebook::react::Props::Shared ParagraphComponentView::props() noexcept { return m_props; } -facebook::react::Tag ParagraphComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag ParagraphComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; @@ -115,7 +115,8 @@ facebook::react::Tag ParagraphComponentView::hitTest(facebook::react::Point pt, return targetTag; */ - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || + m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h index 22d8bc81d8f..e1a9959fc9c 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h @@ -36,7 +36,7 @@ struct ParagraphComponentView : CompositionBaseComponentView { void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override; void prepareForRecycle() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; void OnRenderingDeviceLost() noexcept override; facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp index 700f22cd6c7..99550e5934a 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp @@ -8,18 +8,21 @@ #include "CompositionRootAutomationProvider.h" #include "CompositionRootView.h" +#include namespace Microsoft::ReactNative { RootComponentView::RootComponentView( const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext, - facebook::react::Tag tag) - : Super(compContext, tag) {} + facebook::react::Tag tag, + winrt::Microsoft::ReactNative::ReactContext const &reactContext) + : Super(compContext, tag), m_context(reactContext) {} std::shared_ptr RootComponentView::Create( const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext, - facebook::react::Tag tag) noexcept { - return std::shared_ptr(new RootComponentView(compContext, tag)); + facebook::react::Tag tag, + winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept { + return std::shared_ptr(new RootComponentView(compContext, tag, reactContext)); } RootComponentView *RootComponentView::rootComponentView() noexcept { @@ -113,4 +116,25 @@ std::shared_ptr RootComponentView::getPtr() { return std::static_pointer_cast(shared_from_this()); } +winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixels) noexcept { + + facebook::react::Point ptDips{ + static_cast(ptPixels.x) / m_layoutMetrics.pointScaleFactor, + static_cast(ptPixels.y) / m_layoutMetrics.pointScaleFactor + }; + + facebook::react::Point localPt; + auto tag = hitTest(ptDips, localPt, true); + + auto uiManager = ::Microsoft::ReactNative::FabricUIManager::FromProperties(m_context.Properties()); + if (uiManager == nullptr) + return nullptr; + + auto view = uiManager->GetViewRegistry().findComponentViewWithTag(tag); + if (view == nullptr) + return nullptr; + + return view->EnsureUiaProvider(); +} + } // namespace Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h index 35dd7169746..189db874cdf 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h @@ -18,7 +18,8 @@ struct RootComponentView : CompositionViewComponentView { [[nodiscard]] static std::shared_ptr Create( const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext, - facebook::react::Tag tag) noexcept; + facebook::react::Tag tag, + winrt::Microsoft::ReactNative::ReactContext const &reactContext) noexcept; std::shared_ptr getPtr(); @@ -33,11 +34,15 @@ struct RootComponentView : CompositionViewComponentView { winrt::IInspectable EnsureUiaProvider() noexcept override; + winrt::IInspectable UiaProviderFromPoint(const POINT& ptPixels) noexcept; + private: RootComponentView( const winrt::Microsoft::ReactNative::Composition::ICompositionContext &compContext, - facebook::react::Tag tag); + facebook::react::Tag tag, + winrt::Microsoft::ReactNative::ReactContext const &reactContext); ::Microsoft::ReactNative::IComponentView *m_focusedComponent = nullptr; + winrt::Microsoft::ReactNative::ReactContext m_context; }; } // namespace Microsoft::ReactNative diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp index c1fd976ecc9..961fd360306 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp @@ -335,7 +335,7 @@ void ScrollViewComponentView::ensureVisual() noexcept { } } -facebook::react::Tag ScrollViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag ScrollViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptViewport{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; @@ -344,7 +344,7 @@ facebook::react::Tag ScrollViewComponentView::hitTest(facebook::react::Point pt, ptViewport.y + m_scrollVisual.ScrollPosition().y / m_layoutMetrics.pointScaleFactor}; facebook::react::Tag targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) && std::any_of(m_children.rbegin(), m_children.rend(), [&targetTag, &ptContent, &localPt](auto child) { targetTag = static_cast(child)->hitTest(ptContent, localPt); @@ -352,7 +352,7 @@ facebook::react::Tag ScrollViewComponentView::hitTest(facebook::react::Point pt, })) return targetTag; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptViewport.x >= 0 && ptViewport.x <= m_layoutMetrics.frame.size.width && ptViewport.y >= 0 && ptViewport.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h index c9336666050..103d9fb46b4 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h @@ -71,7 +71,7 @@ struct ScrollInteractionTrackerOwner : public winrt::implements< facebook::react::Props::Shared props() noexcept override; void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; // void OnPointerDown(const winrt::Windows::UI::Input::PointerPoint &pp) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp index 8f1a5bc8bff..0c0df83f1fb 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp @@ -214,11 +214,11 @@ void SwitchComponentView::ensureDrawingSurface() noexcept { } } -facebook::react::Tag SwitchComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag SwitchComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h index 3a27b0449b0..82023e5880c 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h @@ -38,7 +38,7 @@ struct SwitchComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; bool focusable() const noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp index 2cee4ebef50..0e903656f4e 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp @@ -1021,7 +1021,7 @@ void WindowsTextInputComponentView::DrawText() noexcept { m_needsRedraw = false; } -facebook::react::Tag WindowsTextInputComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt) +facebook::react::Tag WindowsTextInputComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; @@ -1037,7 +1037,7 @@ facebook::react::Tag WindowsTextInputComponentView::hitTest(facebook::react::Poi return targetTag; */ - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h index a64875fcea0..a2f42840915 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h @@ -43,7 +43,7 @@ struct WindowsTextInputComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override; int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept override; void OnRenderingDeviceLost() noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; void onFocusLost() noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp index f423ea86edb..21aee3f0220 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp @@ -61,11 +61,29 @@ HRESULT UiaNavigateHelper( } break; } - if (uiaProvider != nullptr) { - winrt::com_ptr spFragment; - uiaProvider.as(spFragment); + auto spFragment = uiaProvider.try_as(); + if (spFragment != nullptr) { retVal = spFragment.detach(); } + + return S_OK; +} + +HRESULT UiaGetBoundingRectangleHelper(::Microsoft::ReactNative::ReactTaggedView &view, UiaRect &rect) noexcept +{ + auto strongView = view.view(); + + if (strongView == nullptr) { + return UIA_E_ELEMENTNOTAVAILABLE; + } + + auto clientRect = strongView->getClientRect(); + + rect.left = clientRect.left; + rect.top = clientRect.top; + rect.width = clientRect.right - clientRect.left; + rect.height = clientRect.bottom - clientRect.top; + return S_OK; } diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h index 4b533cfa6ae..ceb2b72054d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h @@ -13,4 +13,7 @@ UiaNavigateHelper( NavigateDirection direction, IRawElementProviderFragment *&retVal) noexcept; +HRESULT UiaGetBoundingRectangleHelper(::Microsoft::ReactNative::ReactTaggedView &view, UiaRect &rect) noexcept; + + } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp index 8e9872d17ab..40e3dc7b3d5 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.cpp @@ -151,10 +151,11 @@ winrt::Microsoft::ReactNative::Composition::IVisual UnimplementedNativeViewCompo facebook::react::Tag UnimplementedNativeViewComponentView::hitTest( facebook::react::Point pt, - facebook::react::Point &localPt) const noexcept { + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; - if ((m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h index 06297f084e1..1bdc8e41f65 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h @@ -34,7 +34,7 @@ struct UnimplementedNativeViewComponentView : CompositionBaseComponentView { void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override; void prepareForRecycle() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual OuterVisual() const noexcept override; From 754ebcdf7c951ea30aafd1c34f45242aac52b37d Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Tue, 18 Apr 2023 13:20:35 -0700 Subject: [PATCH 2/6] yarn format --- vnext/Microsoft.ReactNative/Fabric/ComponentView.h | 5 ++++- .../Composition/AbiCompositionViewComponentView.cpp | 6 +++--- .../Composition/AbiCompositionViewComponentView.h | 3 ++- .../CompositionRootAutomationProvider.cpp | 4 ++-- .../Composition/CompositionViewComponentView.cpp | 12 ++++++------ .../Composition/CompositionViewComponentView.h | 5 ++++- .../Fabric/Composition/ImageComponentView.cpp | 9 +++++---- .../Fabric/Composition/ImageComponentView.h | 3 ++- .../Fabric/Composition/ParagraphComponentView.cpp | 9 +++++---- .../Fabric/Composition/ParagraphComponentView.h | 3 ++- .../Fabric/Composition/RootComponentView.cpp | 6 ++---- .../Fabric/Composition/RootComponentView.h | 2 +- .../Fabric/Composition/ScrollViewComponentView.cpp | 6 ++++-- .../Fabric/Composition/ScrollViewComponentView.h | 3 ++- .../Fabric/Composition/SwitchComponentView.cpp | 6 ++++-- .../Fabric/Composition/SwitchComponentView.h | 3 ++- .../TextInput/WindowsTextInputComponentView.cpp | 6 ++++-- .../TextInput/WindowsTextInputComponentView.h | 5 ++++- .../Fabric/Composition/UiaHelpers.cpp | 3 +-- .../Fabric/Composition/UiaHelpers.h | 1 - .../UnimplementedNativeViewComponentView.h | 3 ++- 21 files changed, 61 insertions(+), 42 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h index 3cf4a89cc4f..856b765f6c7 100644 --- a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h @@ -60,7 +60,10 @@ struct IComponentView { virtual facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept = 0; virtual facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept = 0; virtual facebook::react::Tag tag() const noexcept = 0; - virtual facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept = 0; + virtual facebook::react::Tag hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents = false) const noexcept = 0; virtual int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept = 0; virtual winrt::IInspectable EnsureUiaProvider() noexcept = 0; }; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp index ca45969953d..9d96550668f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.cpp @@ -119,11 +119,11 @@ winrt::Microsoft::ReactNative::Composition::IVisual AbiCompositionViewComponentV facebook::react::Tag AbiCompositionViewComponentView::hitTest( facebook::react::Point pt, - facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept { + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; - if ((ignorePointerEvents || - m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h index 540918d9d89..98e0e9550c1 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/AbiCompositionViewComponentView.h @@ -43,7 +43,8 @@ struct AbiCompositionViewComponentView : CompositionBaseComponentView { std::vector supplementalComponentDescriptorProviders() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; private: diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp index 492ff230844..c83f462eca0 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp @@ -126,12 +126,12 @@ HRESULT __stdcall CompositionRootAutomationProvider::ElementProviderFromPoint( if (spRootView == nullptr) { return UIA_E_ELEMENTNOTAVAILABLE; } - + if (m_hwnd == nullptr || !IsWindow(m_hwnd)) { // TODO return E_FAIL; } - + POINT clientPoint{static_cast(x), static_cast(y)}; ScreenToClient(m_hwnd, &clientPoint); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index 18fc28fdd1f..a9f0c1e56bb 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -1267,14 +1267,15 @@ void CompositionViewComponentView::updateProps( m_props = std::static_pointer_cast(props); } -facebook::react::Tag CompositionViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag CompositionViewComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; - if ((ignorePointerEvents || - m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) && std::any_of(m_children.rbegin(), m_children.rend(), [&targetTag, &ptLocal, &localPt](auto child) { targetTag = static_cast(child)->hitTest(ptLocal, localPt); @@ -1282,8 +1283,7 @@ facebook::react::Tag CompositionViewComponentView::hitTest(facebook::react::Poin })) return targetTag; - if ((ignorePointerEvents || - m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h index 3a9d1f35c2d..cb89637f25f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.h @@ -114,7 +114,10 @@ struct CompositionViewComponentView : public CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept override; + facebook::react::Tag hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents = false) const noexcept override; bool ScrollWheel(facebook::react::Point pt, int32_t delta) noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp index 5822813c723..66f4cda1c1b 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.cpp @@ -362,14 +362,15 @@ facebook::react::Props::Shared ImageComponentView::props() noexcept { return m_props; } -facebook::react::Tag ImageComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag ImageComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; - if ((ignorePointerEvents || - m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxNone) && std::any_of(m_children.rbegin(), m_children.rend(), [&targetTag, &ptLocal, &localPt](auto child) { targetTag = static_cast(child)->hitTest(ptLocal, localPt); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h index 0cfaed8a872..ab80d091e9f 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ImageComponentView.h @@ -49,7 +49,8 @@ struct ImageComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; void OnRenderingDeviceLost() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; bool focusable() const noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp index 5571a40b6f9..829054d9314 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.cpp @@ -99,8 +99,10 @@ facebook::react::Props::Shared ParagraphComponentView::props() noexcept { return m_props; } -facebook::react::Tag ParagraphComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag ParagraphComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; @@ -115,8 +117,7 @@ facebook::react::Tag ParagraphComponentView::hitTest(facebook::react::Point pt, return targetTag; */ - if ((ignorePointerEvents || - m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || + if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || m_props->pointerEvents == facebook::react::PointerEventsMode::BoxOnly) && ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 && ptLocal.y <= m_layoutMetrics.frame.size.height) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h index e1a9959fc9c..530785676f1 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ParagraphComponentView.h @@ -36,7 +36,8 @@ struct ParagraphComponentView : CompositionBaseComponentView { void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override; void prepareForRecycle() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; void OnRenderingDeviceLost() noexcept override; facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp index 99550e5934a..c0c6929e7c7 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.cpp @@ -6,9 +6,9 @@ #include "RootComponentView.h" +#include #include "CompositionRootAutomationProvider.h" #include "CompositionRootView.h" -#include namespace Microsoft::ReactNative { @@ -117,11 +117,9 @@ std::shared_ptr RootComponentView::getPtr() { } winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixels) noexcept { - facebook::react::Point ptDips{ static_cast(ptPixels.x) / m_layoutMetrics.pointScaleFactor, - static_cast(ptPixels.y) / m_layoutMetrics.pointScaleFactor - }; + static_cast(ptPixels.y) / m_layoutMetrics.pointScaleFactor}; facebook::react::Point localPt; auto tag = hitTest(ptDips, localPt, true); diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h index 189db874cdf..032907025eb 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/RootComponentView.h @@ -34,7 +34,7 @@ struct RootComponentView : CompositionViewComponentView { winrt::IInspectable EnsureUiaProvider() noexcept override; - winrt::IInspectable UiaProviderFromPoint(const POINT& ptPixels) noexcept; + winrt::IInspectable UiaProviderFromPoint(const POINT &ptPixels) noexcept; private: RootComponentView( diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp index 961fd360306..a073d204f37 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.cpp @@ -335,8 +335,10 @@ void ScrollViewComponentView::ensureVisual() noexcept { } } -facebook::react::Tag ScrollViewComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag ScrollViewComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptViewport{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Point ptContent{ diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h index 103d9fb46b4..f7c21368558 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/ScrollViewComponentView.h @@ -71,7 +71,8 @@ struct ScrollInteractionTrackerOwner : public winrt::implements< facebook::react::Props::Shared props() noexcept override; void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; // void OnPointerDown(const winrt::Windows::UI::Input::PointerPoint &pp) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp index 0c0df83f1fb..f58e8fd3f99 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.cpp @@ -214,8 +214,10 @@ void SwitchComponentView::ensureDrawingSurface() noexcept { } } -facebook::react::Tag SwitchComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag SwitchComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; if ((ignorePointerEvents || m_props->pointerEvents == facebook::react::PointerEventsMode::Auto || diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h index 82023e5880c..46f53e28301 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/SwitchComponentView.h @@ -38,7 +38,8 @@ struct SwitchComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; bool focusable() const noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp index f680d6b50ec..c7a79973a3b 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.cpp @@ -1031,8 +1031,10 @@ void WindowsTextInputComponentView::DrawText() noexcept { m_needsRedraw = false; } -facebook::react::Tag WindowsTextInputComponentView::hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) - const noexcept { +facebook::react::Tag WindowsTextInputComponentView::hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents) const noexcept { facebook::react::Point ptLocal{pt.x - m_layoutMetrics.frame.origin.x, pt.y - m_layoutMetrics.frame.origin.y}; facebook::react::Tag targetTag; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h index a2f42840915..f8f608e2ce6 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentView.h @@ -43,7 +43,10 @@ struct WindowsTextInputComponentView : CompositionBaseComponentView { facebook::react::Props::Shared props() noexcept override; void handleCommand(std::string const &commandName, folly::dynamic const &arg) noexcept override; int64_t sendMessage(uint32_t msg, uint64_t wParam, int64_t lParam) noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents = false) const noexcept override; + facebook::react::Tag hitTest( + facebook::react::Point pt, + facebook::react::Point &localPt, + bool ignorePointerEvents = false) const noexcept override; void OnRenderingDeviceLost() noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; void onFocusLost() noexcept override; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp index 21aee3f0220..2cc2f1d542b 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.cpp @@ -69,8 +69,7 @@ HRESULT UiaNavigateHelper( return S_OK; } -HRESULT UiaGetBoundingRectangleHelper(::Microsoft::ReactNative::ReactTaggedView &view, UiaRect &rect) noexcept -{ +HRESULT UiaGetBoundingRectangleHelper(::Microsoft::ReactNative::ReactTaggedView &view, UiaRect &rect) noexcept { auto strongView = view.view(); if (strongView == nullptr) { diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h index ceb2b72054d..e296786c0f8 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UiaHelpers.h @@ -15,5 +15,4 @@ UiaNavigateHelper( HRESULT UiaGetBoundingRectangleHelper(::Microsoft::ReactNative::ReactTaggedView &view, UiaRect &rect) noexcept; - } // namespace winrt::Microsoft::ReactNative::implementation diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h index 1bdc8e41f65..ddf8c284bfb 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/UnimplementedNativeViewComponentView.h @@ -34,7 +34,8 @@ struct UnimplementedNativeViewComponentView : CompositionBaseComponentView { void finalizeUpdates(RNComponentViewUpdateMask updateMask) noexcept override; void prepareForRecycle() noexcept override; facebook::react::Props::Shared props() noexcept override; - facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override; + facebook::react::Tag hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) + const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual Visual() const noexcept override; winrt::Microsoft::ReactNative::Composition::IVisual OuterVisual() const noexcept override; From c7c21be8fc8a820a2daa90eb2da3a94ccc806529 Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Tue, 18 Apr 2023 13:21:07 -0700 Subject: [PATCH 3/6] Change files --- ...ative-windows-dd7d3409-cce5-4725-b7d9-722b0e961a78.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-dd7d3409-cce5-4725-b7d9-722b0e961a78.json diff --git a/change/react-native-windows-dd7d3409-cce5-4725-b7d9-722b0e961a78.json b/change/react-native-windows-dd7d3409-cce5-4725-b7d9-722b0e961a78.json new file mode 100644 index 00000000000..c22c630e43e --- /dev/null +++ b/change/react-native-windows-dd7d3409-cce5-4725-b7d9-722b0e961a78.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "working impl of getBoundingRect and ElementProviderFromPoint", + "packageName": "react-native-windows", + "email": "adrum@microsoft.com", + "dependentChangeType": "patch" +} From 77c9a3907d7ef55166d265eaf5144e7f1f753199 Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Tue, 18 Apr 2023 13:54:03 -0700 Subject: [PATCH 4/6] Minor polish --- vnext/Microsoft.ReactNative/Fabric/ComponentView.h | 2 ++ .../Composition/CompositionDynamicAutomationProvider.cpp | 4 +++- .../Fabric/Composition/CompositionRootAutomationProvider.cpp | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h index 856b765f6c7..bdeef7cd2b1 100644 --- a/vnext/Microsoft.ReactNative/Fabric/ComponentView.h +++ b/vnext/Microsoft.ReactNative/Fabric/ComponentView.h @@ -60,6 +60,8 @@ struct IComponentView { virtual facebook::react::SharedTouchEventEmitter touchEventEmitterAtPoint(facebook::react::Point pt) noexcept = 0; virtual facebook::react::SharedTouchEventEmitter touchEventEmitter() noexcept = 0; virtual facebook::react::Tag tag() const noexcept = 0; + // By default, hitTests according the pointerEvents prop on the Component. + // If ignorePointerEvents = true, all Components are treated as valid targets virtual facebook::react::Tag hitTest( facebook::react::Point pt, facebook::react::Point &localPt, diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index 7ff4237418f..abf08866296 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -63,6 +63,9 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_BoundingRectangle(Ui if (FAILED(hr)) return hr; + // Since get_BoundingRectangle needs to provide real screen coordinates back to the UIA client + // we'll use the FragmentRoot's origin to offset our rect because that should have been taken + // into account already. winrt::com_ptr spFragmentRoot = nullptr; hr = get_FragmentRoot(spFragmentRoot.put()); if (FAILED(hr)) @@ -204,7 +207,6 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::GetPropertyValue(PROPERT if (strongView == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; - // TODO auto props = std::static_pointer_cast(strongView->props()); if (props == nullptr) return UIA_E_ELEMENTNOTAVAILABLE; diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp index c83f462eca0..8ed4f784d5e 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionRootAutomationProvider.cpp @@ -128,7 +128,7 @@ HRESULT __stdcall CompositionRootAutomationProvider::ElementProviderFromPoint( } if (m_hwnd == nullptr || !IsWindow(m_hwnd)) { - // TODO + // TODO: Add support for non-HWND based hosting return E_FAIL; } From a3d41b14880db977769102b33c95ce0d6c4ea0b0 Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Tue, 18 Apr 2023 15:01:51 -0700 Subject: [PATCH 5/6] yarn format --- .../Fabric/Composition/CompositionDynamicAutomationProvider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp index abf08866296..8b873f050ef 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionDynamicAutomationProvider.cpp @@ -64,7 +64,7 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::get_BoundingRectangle(Ui return hr; // Since get_BoundingRectangle needs to provide real screen coordinates back to the UIA client - // we'll use the FragmentRoot's origin to offset our rect because that should have been taken + // we'll use the FragmentRoot's origin to offset our rect because that should have been taken // into account already. winrt::com_ptr spFragmentRoot = nullptr; hr = get_FragmentRoot(spFragmentRoot.put()); From 6ffed656c4c2735f311f73a6718f1a127d45fa2f Mon Sep 17 00:00:00 2001 From: Alicia Drummond Date: Wed, 19 Apr 2023 12:19:04 -0700 Subject: [PATCH 6/6] fix upstream break in TurboModule.h --- .../react/nativemodule/core/ReactCommon/TurboModule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h index 3c8edc194bc..2cc96d83ada 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModule.h @@ -120,7 +120,7 @@ class JSI_EXPORT TurboModule : public facebook::jsi::HostObject { static_cast(meta.argCount), [this, meta]( jsi::Runtime &rt, - const jsi::Value &/*&thisVal*/, + const jsi::Value & _thisVal, const jsi::Value *args, size_t count) { return meta.invoker(rt, *this, args, count); });