Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "prerelease",
"comment": "Introduce xamlhost component",
"packageName": "react-native-windows",
"email": "[email protected]",
"dependentChangeType": "patch"
}
81 changes: 40 additions & 41 deletions packages/sample-app-fabric/windows/SampleAppFabric.sln
Original file line number Diff line number Diff line change
Expand Up @@ -36,62 +36,50 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Include", "..\..\..\vnext\include\Include.vcxitems", "{EF074BA1-2D54-4D49-A28E-5E040B47CD2E}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\..\..\vnext\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
..\..\..\vnext\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
..\..\..\vnext\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
..\..\..\vnext\include\Include.vcxitems*{ef074ba1-2d54-4d49-a28e-5e040b47cd2e}*SharedItemsImports = 9
..\..\..\vnext\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Debug|ARM64 = Debug|ARM64
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
Release|ARM64 = Release|ARM64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.Build.0 = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.Deploy.0 = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x64.ActiveCfg = Debug|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x64.Build.0 = Debug|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x64.Deploy.0 = Debug|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x86.ActiveCfg = Debug|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x86.Build.0 = Debug|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|x86.Deploy.0 = Debug|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.Build.0 = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Debug|ARM64.Deploy.0 = Debug|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.ActiveCfg = Release|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.Build.0 = Release|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.Deploy.0 = Release|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x64.ActiveCfg = Release|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x64.Build.0 = Release|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x64.Deploy.0 = Release|x64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x86.ActiveCfg = Release|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x86.Build.0 = Release|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|x86.Deploy.0 = Release|x86
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.ActiveCfg = Release|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.Build.0 = Release|ARM64
{7E2B86E3-E6B0-409D-812E-0D81DFFACA9D}.Release|ARM64.Deploy.0 = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.Build.0 = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.Deploy.0 = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x64.ActiveCfg = Debug|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x64.Build.0 = Debug|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x64.Deploy.0 = Debug|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x86.ActiveCfg = Debug|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x86.Build.0 = Debug|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|x86.Deploy.0 = Debug|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.ActiveCfg = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.Build.0 = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Debug|ARM64.Deploy.0 = Debug|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.ActiveCfg = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.Build.0 = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.Deploy.0 = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x64.ActiveCfg = Release|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x64.Build.0 = Release|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x64.Deploy.0 = Release|x64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x86.ActiveCfg = Release|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x86.Build.0 = Release|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|x86.Deploy.0 = Release|Win32
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.ActiveCfg = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.Build.0 = Release|ARM64
{E278ABE5-5A88-48C5-A949-CA00B489643F}.Release|ARM64.Deploy.0 = Release|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|ARM64.Build.0 = Debug|ARM64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Debug|x64.ActiveCfg = Debug|x64
Expand All @@ -104,6 +92,20 @@ Global
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x64.Build.0 = Release|x64
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.ActiveCfg = Release|Win32
{A990658C-CE31-4BCC-976F-0FC6B1AF693D}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.Build.0 = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.ActiveCfg = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.Build.0 = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.ActiveCfg = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Build.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Deploy.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.ActiveCfg = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.Build.0 = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.ActiveCfg = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.Build.0 = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Deploy.0 = Release|Win32
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.ActiveCfg = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|ARM64.Build.0 = Debug|ARM64
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD}.Debug|x64.ActiveCfg = Debug|x64
Expand Down Expand Up @@ -140,26 +142,13 @@ Global
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x64.Build.0 = Release|x64
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.ActiveCfg = Release|Win32
{FCA38F3C-7C73-4C47-BE4E-32F77FA8538D}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|ARM64.Build.0 = Debug|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.ActiveCfg = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x64.Build.0 = Debug|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.ActiveCfg = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Build.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Debug|x86.Deploy.0 = Debug|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.ActiveCfg = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|ARM64.Build.0 = Release|ARM64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.ActiveCfg = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x64.Build.0 = Release|x64
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.ActiveCfg = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Build.0 = Release|Win32
{14B93DC8-FD93-4A6D-81CB-8BC96644501C}.Release|x86.Deploy.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{A990658C-CE31-4BCC-976F-0FC6B1AF693D} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{14B93DC8-FD93-4A6D-81CB-8BC96644501C} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{A9D95A91-4DB7-4F72-BEB6-FE8A5C89BFBD} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{C38970C0-5FBF-4D69-90D8-CBAC225AE895} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{F7D32BD0-2749-483E-9A0D-1635EF7E3136} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
Expand All @@ -168,9 +157,19 @@ Global
{2049DBE9-8D13-42C9-AE4B-413AE38FFFD0} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{84E05BFA-CBAF-4F0D-BFB6-4CE85742A57E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{EF074BA1-2D54-4D49-A28E-5E040B47CD2E} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
{14B93DC8-FD93-4A6D-81CB-8BC96644501C} = {5EA20F54-880A-49F3-99FA-4B3FE54E8AB1}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D43FAD39-F619-437D-BB40-04A3982ACB6A}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\..\..\vnext\Shared\Shared.vcxitems*{2049dbe9-8d13-42c9-ae4b-413ae38fffd0}*SharedItemsImports = 9
..\..\..\vnext\Mso\Mso.vcxitems*{84e05bfa-cbaf-4f0d-bfb6-4ce85742a57e}*SharedItemsImports = 9
..\..\..\vnext\Chakra\Chakra.vcxitems*{c38970c0-5fbf-4d69-90d8-cbac225ae895}*SharedItemsImports = 9
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{da8b35b3-da00-4b02-bde6-6a397b3fd46b}*SharedItemsImports = 9
..\..\..\vnext\include\Include.vcxitems*{ef074ba1-2d54-4d49-a28e-5e040b47cd2e}*SharedItemsImports = 9
..\..\..\vnext\Chakra\Chakra.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Microsoft.ReactNative.Cxx\Microsoft.ReactNative.Cxx.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Mso\Mso.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
..\..\..\vnext\Shared\Shared.vcxitems*{f7d32bd0-2749-483e-9a0d-1635ef7e3136}*SharedItemsImports = 4
EndGlobalSection
EndGlobal
5 changes: 5 additions & 0 deletions vnext/Microsoft.ReactNative/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Application
x:Class="Microsoft.ReactNative.Xaml.XamlApplication"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
</Application>
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,13 @@ HRESULT __stdcall CompositionDynamicAutomationProvider::SetFocus(void) {
return UiaSetFocusHelper(m_view);
}

winrt::IUnknown CompositionDynamicAutomationProvider::TryGetChildSiteLinkAutomationProvider() {
if (m_childSiteLink) {
return m_childSiteLink.AutomationProvider().as<winrt::IUnknown>();
}
return nullptr;
}

HRESULT __stdcall CompositionDynamicAutomationProvider::get_FragmentRoot(IRawElementProviderFragmentRoot **pRetVal) {
if (pRetVal == nullptr)
return E_POINTER;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,14 @@ class CompositionDynamicAutomationProvider : public winrt::implements<
void AddToSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item);
void RemoveFromSelectionItems(winrt::com_ptr<IRawElementProviderSimple> &item);

void SetChildSiteLink(winrt::Microsoft::UI::Content::ChildSiteLink childSiteLink) {
m_childSiteLink = childSiteLink;
}

// If this object is for a ChildSiteLink, returns the ChildSiteLink's automation provider.
// This will be a provider object from the hosted framework (for example, WinUI).
winrt::IUnknown TryGetChildSiteLinkAutomationProvider();

private:
::Microsoft::ReactNative::ReactTaggedView m_view;
winrt::com_ptr<ITextProvider2> m_textProvider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,8 @@ HRESULT __stdcall CompositionRootAutomationProvider::ElementProviderFromPoint(
auto local = rootView->ConvertScreenToLocal({static_cast<float>(x), static_cast<float>(y)});
auto provider = rootView->UiaProviderFromPoint(
{static_cast<LONG>(local.X * rootView->LayoutMetrics().PointScaleFactor),
static_cast<LONG>(local.Y * rootView->LayoutMetrics().PointScaleFactor)});
static_cast<LONG>(local.Y * rootView->LayoutMetrics().PointScaleFactor)},
{static_cast<LONG>(x), static_cast<LONG>(y)});
auto spFragment = provider.try_as<IRawElementProviderFragment>();
if (spFragment) {
*pRetVal = spFragment.detach();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,14 +178,12 @@ ContentIslandComponentView::~ContentIslandComponentView() noexcept {
void ContentIslandComponentView::MountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
assert(false);
base_type::MountChildComponentView(childComponentView, index);
}

void ContentIslandComponentView::UnmountChildComponentView(
const winrt::Microsoft::ReactNative::ComponentView &childComponentView,
uint32_t index) noexcept {
assert(false);
Comment on lines -181 to -188
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Were these asserts originally put to ensure control doesn't reach here? More like unreachable code but now we've a genuine islands scenario that have them removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sundar

base_type::UnmountChildComponentView(childComponentView, index);
}

Expand All @@ -212,6 +210,25 @@ void ContentIslandComponentView::prepareForRecycle() noexcept {
Super::prepareForRecycle();
}

facebook::react::Tag ContentIslandComponentView::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};

// This is similar to ViewComponentView::hitTest, but we don't want to hit test the children of this node,
// because the child ComponentView is kind of a dummy representation of the XamlElement and doesn't do anything.
// So, we just hit test the ContentIsland itself to make the UIA ElementProviderFromPoint call work.
// TODO: Will this cause a problem -- does this function need to do something different for non-UIA scenarios?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious of Andrew's thoughts on the best way to handle ContentIslandComponentView::hitTest

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this override? What kinds of components are you putting in the ContentIslandComponentView? I'd expect that the components you'd be putting in the XamlHost view would be Xaml components. And those should not inherit from ViewComponent, so they would be ignored by the default hit test, no?

if (ptLocal.x >= 0 && ptLocal.x <= m_layoutMetrics.frame.size.width && ptLocal.y >= 0 &&
ptLocal.y <= m_layoutMetrics.frame.size.height) {
localPt = ptLocal;
return Tag();
}

return -1;
}

void ContentIslandComponentView::ConfigureChildSiteLinkAutomation() noexcept {
// This automation mode must be set before connecting the child ContentIsland.
// It puts the child content into a mode where it won't own its own framework root. Instead, the child island's
Expand Down Expand Up @@ -262,6 +279,12 @@ void ContentIslandComponentView::ConfigureChildSiteLinkAutomation() noexcept {
args.AutomationProvider(nullptr);
args.Handled(true);
});

if (m_uiaProvider) {
auto providerImpl =
m_uiaProvider.as<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>();
providerImpl->SetChildSiteLink(m_childSiteLink);
}
}

} // namespace winrt::Microsoft::ReactNative::Composition::implementation
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ struct ContentIslandComponentView : ContentIslandComponentViewT<ContentIslandCom
ReactCompositionViewComponentBuilder *builder);
~ContentIslandComponentView() noexcept;

virtual facebook::react::Tag
hitTest(facebook::react::Point pt, facebook::react::Point &localPt, bool ignorePointerEvents) const noexcept override;

private:
void OnMounted() noexcept;
void OnUnmounted() noexcept;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include <Fabric/FabricUIManagerModule.h>
#include <winrt/Microsoft.UI.Input.h>
#include "CompositionDynamicAutomationProvider.h"
#include "CompositionRootAutomationProvider.h"
#include "ReactNativeIsland.h"
#include "Theme.h"
Expand Down Expand Up @@ -275,7 +276,7 @@ facebook::react::Point RootComponentView::getClientOffset() const noexcept {
return {};
}

winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixels) noexcept {
winrt::IUnknown RootComponentView::UiaProviderFromPoint(const POINT &ptPixels, const POINT &ptScreen) noexcept {
facebook::react::Point ptDips{
static_cast<facebook::react::Float>(ptPixels.x) / m_layoutMetrics.pointScaleFactor,
static_cast<facebook::react::Float>(ptPixels.y) / m_layoutMetrics.pointScaleFactor};
Expand All @@ -295,7 +296,41 @@ winrt::IInspectable RootComponentView::UiaProviderFromPoint(const POINT &ptPixel
if (view == nullptr)
return nullptr;

return winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)->EnsureUiaProvider();
auto uiaProvider =
winrt::get_self<winrt::Microsoft::ReactNative::implementation::ComponentView>(view)->EnsureUiaProvider();

// TODO: Avoid exposing CompositionDynamicAutomationProvider in RootComponentView
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please file a follow-up task for this and paste its link here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#15317 - I already created a task and adding pending sub tasks to it. Will add this here.

auto dynamicProvider =
uiaProvider.try_as<winrt::Microsoft::ReactNative::implementation::CompositionDynamicAutomationProvider>();
if (dynamicProvider) {
if (auto childProvider = dynamicProvider->TryGetChildSiteLinkAutomationProvider()) {
// ChildProvider is the the automation provider from the ChildSiteLink. In the case of WinUI, this
// is a pointer to WinUI's internal CUIAHostWindow object.
// It seems odd, but even though this node doesn't behave as a fragment root in our case (the real fragment root
// is the RootComponentView's UIA provider), we still use its IRawElementProviderFragmentRoot -- just so
// we can do the ElementProviderFromPoint call. (this was recommended by the team who did the initial
// architecture work).
if (auto fragmentRoot = childProvider.try_as<IRawElementProviderFragmentRoot>()) {
com_ptr<IRawElementProviderFragment> frag;
// WinUI then does its own hitTest inside the XAML tree.
fragmentRoot->ElementProviderFromPoint(
ptScreen
.x, // Note since we're going through IRawElementProviderFragment the coordinates are in screen space.
ptScreen.y,
frag.put());
// We return the specific child provider(frag) when hosted XAML has an element
// under the cursor. This satisfies the UIA "element at point" contract and exposes
// the control’s patterns/properties. If the hosted tree finds nothing, we fall back
// to the RNW container’s provider (uiaProvider) to keep the island accessible.
// (A Microsoft_UI_Xaml!CUIAWrapper object)
if (frag) {
return frag.as<winrt::IUnknown>();
}
}
}
}

return uiaProvider;
}

float RootComponentView::FontSizeMultiplier() const noexcept {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ struct RootComponentView : RootComponentViewT<RootComponentView, ViewComponentVi
facebook::react::LayoutMetrics const &layoutMetrics,
facebook::react::LayoutMetrics const &oldLayoutMetrics) noexcept override;

winrt::Windows::Foundation::IInspectable UiaProviderFromPoint(const POINT &ptPixels) noexcept;
winrt::Windows::Foundation::IUnknown UiaProviderFromPoint(const POINT &ptPixels, const POINT &ptScreen) noexcept;

RootComponentView(
const winrt::Microsoft::ReactNative::Composition::Experimental::ICompositionContext &compContext,
Expand Down
1 change: 0 additions & 1 deletion vnext/Microsoft.ReactNative/IReactPackageProvider.idl
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ namespace Microsoft.ReactNative
"Use the @IReactPackageBuilder to register custom native modules and view managers.")
void CreatePackage(IReactPackageBuilder packageBuilder);
};

} // namespace Microsoft.ReactNative
11 changes: 11 additions & 0 deletions vnext/Microsoft.ReactNative/IXamlProvider.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#include "DocString.h"

namespace Microsoft.ReactNative.Xaml {
[webhosthidden]
interface IXamlControl {
DOC_STRING(
"Native components that want to be Xaml-based can implement IXamlControl to allow their object to be parented to a XamlHost.")
Microsoft.UI.Xaml.UIElement GetXamlElement();
};
} // namespace Microsoft.ReactNative. Xaml
Loading
Loading