From 1b2cf7872a2e3219b94b9306dd893b7c4df57f9e Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Wed, 3 Mar 2021 17:45:15 -0800 Subject: [PATCH 01/10] Add functionality to setAccessibilityFocus method --- .../Modules/AccessibilityInfoModule.cpp | 23 +++++++++++++++++-- .../AccessibilityInfo.windows.js | 4 +++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index ee4e68f5674..b1c589974f8 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -5,11 +5,13 @@ #include "AccessibilityInfoModule.h" #include #include +#include #include #include #include #include #include +#include "XamlUIService.h" #include "Unicode.h" #include "Utils/Helpers.h" @@ -35,8 +37,25 @@ void AccessibilityInfo::isTouchExplorationEnabled( onSuccess(UiaClientsAreListening()); } -void AccessibilityInfo::setAccessibilityFocus(double /*reactTag*/) noexcept { - // no-op - This appears to be unused in RN +void AccessibilityInfo::setAccessibilityFocus(double reactTag) noexcept { + m_context.UIDispatcher().Post([context = m_context, reactTag = std::move(reactTag)] { + auto service = winrt::Microsoft::ReactNative::XamlUIService::FromContext(context.Handle()); + auto element = service.ElementFromReactTag(int64_t(reactTag)); + + if (!element) { + return; + } + + auto frameworkElement = element.try_as(); + xaml::Input::FocusManager::TryFocusAsync(frameworkElement, xaml::FocusState::Programmatic); + auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(frameworkElement); + + if (!peer) { + return; + } + + peer.RaiseAutomationEvent(xaml::Automation::Peers::AutomationEvents::AutomationFocusChanged); + }); } void AccessibilityInfo::announceForAccessibility(std::string announcement) noexcept { diff --git a/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js b/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js index d619b897254..a555d7c95cc 100644 --- a/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +++ b/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js @@ -151,7 +151,9 @@ const AccessibilityInfo = { * See https://reactnative.dev/docs/accessibilityinfo.html#setaccessibilityfocus */ setAccessibilityFocus: function(reactTag: number): void { - legacySendAccessibilityEvent(reactTag, 'focus'); + if (NativeAccessibilityInfo) { + NativeAccessibilityInfo.setAccessibilityFocus(reactTag); + } }, /** From 7905f7fdc6626c74919a9a8792d8a09f991bb9b7 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:04:15 -0800 Subject: [PATCH 02/10] Add method support for Xaml Islands --- .../Modules/AccessibilityInfoModule.cpp | 45 +++++++++---------- vnext/Microsoft.ReactNative/XamlUIService.cpp | 17 +++++++ vnext/Microsoft.ReactNative/XamlUIService.h | 2 + vnext/Microsoft.ReactNative/XamlUIService.idl | 3 ++ 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index b1c589974f8..1fd6eec0871 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -5,13 +5,11 @@ #include "AccessibilityInfoModule.h" #include #include -#include #include #include #include #include #include -#include "XamlUIService.h" #include "Unicode.h" #include "Utils/Helpers.h" @@ -38,38 +36,37 @@ void AccessibilityInfo::isTouchExplorationEnabled( } void AccessibilityInfo::setAccessibilityFocus(double reactTag) noexcept { - m_context.UIDispatcher().Post([context = m_context, reactTag = std::move(reactTag)] { - auto service = winrt::Microsoft::ReactNative::XamlUIService::FromContext(context.Handle()); - auto element = service.ElementFromReactTag(int64_t(reactTag)); - - if (!element) { - return; - } - - auto frameworkElement = element.try_as(); - xaml::Input::FocusManager::TryFocusAsync(frameworkElement, xaml::FocusState::Programmatic); - auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(frameworkElement); - - if (!peer) { - return; - } - - peer.RaiseAutomationEvent(xaml::Automation::Peers::AutomationEvents::AutomationFocusChanged); - }); + // no-op - This appears to be unused in RN } void AccessibilityInfo::announceForAccessibility(std::string announcement) noexcept { m_context.UIDispatcher().Post([context = m_context, announcement = std::move(announcement)] { // Windows requires a specific element to announce from. Unfortunately the react-native API does not provide a tag - // So we need to add a temporary control to raise the notification event from. + // So we need to find something to raise the notification event from. + xaml::UIElement element{nullptr}; + + if (react::uwp::Is19H1OrHigher()) { + // XamlRoot added in 19H1 + if (auto xamlRoot = + winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleXamlRoot(context.Properties().Handle())) { + element = xamlRoot.Content(); + } else { + return; + } + } - auto textBlock = xaml::Controls::TextBlock(); + if (!element) { + if (auto window = xaml::Window::Current()) { + element = window.Content(); + element.SetValue(xaml::Automation::AutomationProperties::LandmarkTypeProperty(), winrt::box_value(80002)); + } + } - if (!textBlock) { + if (!element) { return; } - auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(textBlock); + auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element); if (!peer) { return; diff --git a/vnext/Microsoft.ReactNative/XamlUIService.cpp b/vnext/Microsoft.ReactNative/XamlUIService.cpp index e59154f4bc6..b671ba35dd0 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.cpp +++ b/vnext/Microsoft.ReactNative/XamlUIService.cpp @@ -6,10 +6,12 @@ #include "XamlUIService.g.cpp" #include #include +#include #include "DynamicWriter.h" #include "ShadowNodeBase.h" #include "Views/ShadowNodeBase.h" + namespace winrt::Microsoft::ReactNative::implementation { XamlUIService::XamlUIService(Mso::CntPtr &&context) noexcept : m_context(context) {} @@ -56,16 +58,31 @@ ReactPropertyId XamlRootProperty() noexcept { return propId; } +ReactPropertyId AccessibleXamlRootProperty() noexcept { + static ReactPropertyId propId{L"ReactNative.UIManager", L"AccessibleXamlRoot"}; + return propId; +} + /*static*/ void XamlUIService::SetXamlRoot( IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept { winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(XamlRootProperty(), xamlRoot); } +/*static*/ void XamlUIService::SetAccessibleXamlRoot( + IReactPropertyBag const &properties, + xaml::XamlRoot const &xamlRoot) noexcept { + winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(AccessibleXamlRootProperty(), xamlRoot); +} + /*static*/ xaml::XamlRoot XamlUIService::GetXamlRoot(IReactPropertyBag const &properties) noexcept { return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(XamlRootProperty()); } +/*static*/ xaml::XamlRoot XamlUIService::GetAccessibleXamlRoot(IReactPropertyBag const &properties) noexcept { + return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(AccessibleXamlRootProperty()); +} + ReactPropertyId XamlIslandProperty() noexcept { static ReactPropertyId propId{L"ReactNative.UIManager", L"XamlIsland"}; return propId; diff --git a/vnext/Microsoft.ReactNative/XamlUIService.h b/vnext/Microsoft.ReactNative/XamlUIService.h index d3a9249a33f..917f239c075 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.h +++ b/vnext/Microsoft.ReactNative/XamlUIService.h @@ -23,7 +23,9 @@ struct XamlUIService : XamlUIServiceT { JSValueArgWriter const &eventDataArgWriter) noexcept; static void SetXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; + static void SetAccessibleXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; static xaml::XamlRoot GetXamlRoot(IReactPropertyBag const &properties) noexcept; + static xaml::XamlRoot GetAccessibleXamlRoot(IReactPropertyBag const &properties) noexcept; static void SetIslandWindowHandle(IReactPropertyBag const &properties, uint64_t hwnd) noexcept; static uint64_t GetIslandWindowHandle(IReactPropertyBag const &properties) noexcept; diff --git a/vnext/Microsoft.ReactNative/XamlUIService.idl b/vnext/Microsoft.ReactNative/XamlUIService.idl index dcb2594ace6..2cb2f7906ff 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.idl +++ b/vnext/Microsoft.ReactNative/XamlUIService.idl @@ -24,7 +24,10 @@ namespace Microsoft.ReactNative { // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands static void SetXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); + // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands + static void SetAccessibleXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); static XAML_NAMESPACE.XamlRoot GetXamlRoot(IReactPropertyBag properties); + static XAML_NAMESPACE.XamlRoot GetAccessibleXamlRoot(IReactPropertyBag properties); static UInt64 GetIslandWindowHandle(IReactPropertyBag properties); DOC_STRING("Sets the windowHandle HWND (as an uint64) to be the XAML Island window for the current React instance. Pass the value returned by IDesktopWindowXamlSourceNative get_WindowHandle.") From 881a4afb64cc371fa6421e17cd1247a2db35cfa7 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:10:14 -0800 Subject: [PATCH 03/10] Remove Unneeded Change --- vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index 1fd6eec0871..fa3b027a6f7 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -35,7 +35,7 @@ void AccessibilityInfo::isTouchExplorationEnabled( onSuccess(UiaClientsAreListening()); } -void AccessibilityInfo::setAccessibilityFocus(double reactTag) noexcept { +void AccessibilityInfo::setAccessibilityFocus(double /*reactTag*/) noexcept { // no-op - This appears to be unused in RN } From 7c4da711bc611dab1ed75bf4e111a9cf84fce3c1 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:12:51 -0800 Subject: [PATCH 04/10] Remove Unneeded Change --- vnext/Microsoft.ReactNative/XamlUIService.cpp | 2 -- .../Components/AccessibilityInfo/AccessibilityInfo.windows.js | 4 +--- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/vnext/Microsoft.ReactNative/XamlUIService.cpp b/vnext/Microsoft.ReactNative/XamlUIService.cpp index b671ba35dd0..f5696f37158 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.cpp +++ b/vnext/Microsoft.ReactNative/XamlUIService.cpp @@ -6,12 +6,10 @@ #include "XamlUIService.g.cpp" #include #include -#include #include "DynamicWriter.h" #include "ShadowNodeBase.h" #include "Views/ShadowNodeBase.h" - namespace winrt::Microsoft::ReactNative::implementation { XamlUIService::XamlUIService(Mso::CntPtr &&context) noexcept : m_context(context) {} diff --git a/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js b/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js index a555d7c95cc..d619b897254 100644 --- a/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js +++ b/vnext/src/Libraries/Components/AccessibilityInfo/AccessibilityInfo.windows.js @@ -151,9 +151,7 @@ const AccessibilityInfo = { * See https://reactnative.dev/docs/accessibilityinfo.html#setaccessibilityfocus */ setAccessibilityFocus: function(reactTag: number): void { - if (NativeAccessibilityInfo) { - NativeAccessibilityInfo.setAccessibilityFocus(reactTag); - } + legacySendAccessibilityEvent(reactTag, 'focus'); }, /** From 9a7a35dc2b176be32258a576a32257815b7f13af Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Fri, 5 Mar 2021 12:16:51 -0800 Subject: [PATCH 05/10] Change files --- ...ative-windows-2fe5aef3-7497-4418-8cf6-038834f023b1.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-2fe5aef3-7497-4418-8cf6-038834f023b1.json diff --git a/change/react-native-windows-2fe5aef3-7497-4418-8cf6-038834f023b1.json b/change/react-native-windows-2fe5aef3-7497-4418-8cf6-038834f023b1.json new file mode 100644 index 00000000000..b7863e7bf47 --- /dev/null +++ b/change/react-native-windows-2fe5aef3-7497-4418-8cf6-038834f023b1.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Add method support for Xaml Islands", + "packageName": "react-native-windows", + "email": "34109996+chiaramooney@users.noreply.github.com", + "dependentChangeType": "patch" +} From 046ffdf0596694d36913c6dcd3e706f763034de1 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Fri, 5 Mar 2021 14:22:44 -0800 Subject: [PATCH 06/10] Fix Logic Bug --- .../Modules/AccessibilityInfoModule.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index fa3b027a6f7..7c793884808 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -47,11 +47,13 @@ void AccessibilityInfo::announceForAccessibility(std::string announcement) noexc if (react::uwp::Is19H1OrHigher()) { // XamlRoot added in 19H1 - if (auto xamlRoot = - winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleXamlRoot(context.Properties().Handle())) { - element = xamlRoot.Content(); - } else { - return; + if (winrt::Microsoft::ReactNative::XamlUIService::GetXamlRoot(context.Properties().Handle())) { + if (auto xamlroot = + winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleXamlRoot(context.Properties().Handle())) { + element = xamlroot.Content(); + } else { + return; + } } } @@ -62,10 +64,6 @@ void AccessibilityInfo::announceForAccessibility(std::string announcement) noexc } } - if (!element) { - return; - } - auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element); if (!peer) { From 4241cc456073a0b25ed391340fd6b7bcf5fdf171 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Mon, 8 Mar 2021 13:25:16 -0800 Subject: [PATCH 07/10] Fix Requested Changes --- .../Modules/AccessibilityInfoModule.cpp | 29 +++++++++---------- vnext/Microsoft.ReactNative/XamlUIService.cpp | 10 +++---- vnext/Microsoft.ReactNative/XamlUIService.h | 4 +-- vnext/Microsoft.ReactNative/XamlUIService.idl | 8 +++-- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index 7c793884808..4987ddcf2f3 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -45,23 +45,22 @@ void AccessibilityInfo::announceForAccessibility(std::string announcement) noexc // So we need to find something to raise the notification event from. xaml::UIElement element{nullptr}; - if (react::uwp::Is19H1OrHigher()) { - // XamlRoot added in 19H1 - if (winrt::Microsoft::ReactNative::XamlUIService::GetXamlRoot(context.Properties().Handle())) { - if (auto xamlroot = - winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleXamlRoot(context.Properties().Handle())) { - element = xamlroot.Content(); - } else { - return; - } + if (react::uwp::IsXamlIsland()) { + if (auto xamlroot = + winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleRoot(context.Properties().Handle())) { + element = xamlroot.Content(); } - } - - if (!element) { - if (auto window = xaml::Window::Current()) { - element = window.Content(); - element.SetValue(xaml::Automation::AutomationProperties::LandmarkTypeProperty(), winrt::box_value(80002)); + if (!element) { + if (auto window = xaml::Window::Current()) { + if (element = window.Content()) { + element.SetValue(xaml::Automation::AutomationProperties::LandmarkTypeProperty(), winrt::box_value(80002)); + } else { + return; + } + } } + } else { + element = xaml::Controls::TextBlock(); } auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element); diff --git a/vnext/Microsoft.ReactNative/XamlUIService.cpp b/vnext/Microsoft.ReactNative/XamlUIService.cpp index f5696f37158..c5eec11db09 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.cpp +++ b/vnext/Microsoft.ReactNative/XamlUIService.cpp @@ -56,7 +56,7 @@ ReactPropertyId XamlRootProperty() noexcept { return propId; } -ReactPropertyId AccessibleXamlRootProperty() noexcept { +ReactPropertyId AccessibleRootProperty() noexcept { static ReactPropertyId propId{L"ReactNative.UIManager", L"AccessibleXamlRoot"}; return propId; } @@ -67,18 +67,18 @@ ReactPropertyId AccessibleXamlRootProperty() noexcept { winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(XamlRootProperty(), xamlRoot); } -/*static*/ void XamlUIService::SetAccessibleXamlRoot( +/*static*/ void XamlUIService::SetAccessibleRoot( IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept { - winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(AccessibleXamlRootProperty(), xamlRoot); + winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(AccessibleRootProperty(), xamlRoot); } /*static*/ xaml::XamlRoot XamlUIService::GetXamlRoot(IReactPropertyBag const &properties) noexcept { return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(XamlRootProperty()); } -/*static*/ xaml::XamlRoot XamlUIService::GetAccessibleXamlRoot(IReactPropertyBag const &properties) noexcept { - return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(AccessibleXamlRootProperty()); +/*static*/ xaml::XamlRoot XamlUIService::GetAccessibleRoot(IReactPropertyBag const &properties) noexcept { + return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(AccessibleRootProperty()); } ReactPropertyId XamlIslandProperty() noexcept { diff --git a/vnext/Microsoft.ReactNative/XamlUIService.h b/vnext/Microsoft.ReactNative/XamlUIService.h index 917f239c075..987ed5d018f 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.h +++ b/vnext/Microsoft.ReactNative/XamlUIService.h @@ -23,9 +23,9 @@ struct XamlUIService : XamlUIServiceT { JSValueArgWriter const &eventDataArgWriter) noexcept; static void SetXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; - static void SetAccessibleXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; + static void SetAccessibleRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; static xaml::XamlRoot GetXamlRoot(IReactPropertyBag const &properties) noexcept; - static xaml::XamlRoot GetAccessibleXamlRoot(IReactPropertyBag const &properties) noexcept; + static xaml::XamlRoot GetAccessibleRoot(IReactPropertyBag const &properties) noexcept; static void SetIslandWindowHandle(IReactPropertyBag const &properties, uint64_t hwnd) noexcept; static uint64_t GetIslandWindowHandle(IReactPropertyBag const &properties) noexcept; diff --git a/vnext/Microsoft.ReactNative/XamlUIService.idl b/vnext/Microsoft.ReactNative/XamlUIService.idl index 2cb2f7906ff..a8f2cc744a6 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.idl +++ b/vnext/Microsoft.ReactNative/XamlUIService.idl @@ -23,11 +23,15 @@ namespace Microsoft.ReactNative { void DispatchEvent(XAML_NAMESPACE.FrameworkElement view, String eventName, JSValueArgWriter eventDataArgWriter); // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands + DOC_STRING("Set XamlRoot for app. This must be manually provided to the ReactInstanceSettings when using XamlIslands.") static void SetXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands - static void SetAccessibleXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); + DOC_STRING("Set accessible XamlRoot for app. This XamlRoot should be able to create an automation peer. This must be manually provided to the ReactInstanceSettings when using XamlIslands to have access to accessibility methods.") + static void SetAccessibleRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); + DOC_STRING("Retrieve XamlRoot for app.") static XAML_NAMESPACE.XamlRoot GetXamlRoot(IReactPropertyBag properties); - static XAML_NAMESPACE.XamlRoot GetAccessibleXamlRoot(IReactPropertyBag properties); + DOC_STRING("Retrieve accessible XamlRoot for app.") + static XAML_NAMESPACE.XamlRoot GetAccessibleRoot(IReactPropertyBag properties); static UInt64 GetIslandWindowHandle(IReactPropertyBag properties); DOC_STRING("Sets the windowHandle HWND (as an uint64) to be the XAML Island window for the current React instance. Pass the value returned by IDesktopWindowXamlSourceNative get_WindowHandle.") From 0f0cf901ec8ee37eab4a3d61c4378532fb33f6f7 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Thu, 11 Mar 2021 16:03:49 -0800 Subject: [PATCH 08/10] Add Requested Changes --- .../Modules/AccessibilityInfoModule.cpp | 15 ++++----------- vnext/Microsoft.ReactNative/XamlUIService.cpp | 10 +++++----- vnext/Microsoft.ReactNative/XamlUIService.h | 4 ++-- vnext/Microsoft.ReactNative/XamlUIService.idl | 4 ++-- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp index 4987ddcf2f3..8ef28956eb9 100644 --- a/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp +++ b/vnext/Microsoft.ReactNative/Modules/AccessibilityInfoModule.cpp @@ -46,18 +46,11 @@ void AccessibilityInfo::announceForAccessibility(std::string announcement) noexc xaml::UIElement element{nullptr}; if (react::uwp::IsXamlIsland()) { - if (auto xamlroot = + if (auto accessibleRoot = winrt::Microsoft::ReactNative::XamlUIService::GetAccessibleRoot(context.Properties().Handle())) { - element = xamlroot.Content(); - } - if (!element) { - if (auto window = xaml::Window::Current()) { - if (element = window.Content()) { - element.SetValue(xaml::Automation::AutomationProperties::LandmarkTypeProperty(), winrt::box_value(80002)); - } else { - return; - } - } + element = accessibleRoot; + } else { + return; } } else { element = xaml::Controls::TextBlock(); diff --git a/vnext/Microsoft.ReactNative/XamlUIService.cpp b/vnext/Microsoft.ReactNative/XamlUIService.cpp index c5eec11db09..7b4e07f6b89 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.cpp +++ b/vnext/Microsoft.ReactNative/XamlUIService.cpp @@ -56,8 +56,8 @@ ReactPropertyId XamlRootProperty() noexcept { return propId; } -ReactPropertyId AccessibleRootProperty() noexcept { - static ReactPropertyId propId{L"ReactNative.UIManager", L"AccessibleXamlRoot"}; +ReactPropertyId AccessibleRootProperty() noexcept { + static ReactPropertyId propId{L"ReactNative.UIManager", L"AccessibleRoot"}; return propId; } @@ -69,15 +69,15 @@ ReactPropertyId AccessibleRootProperty() noexcept { /*static*/ void XamlUIService::SetAccessibleRoot( IReactPropertyBag const &properties, - xaml::XamlRoot const &xamlRoot) noexcept { - winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(AccessibleRootProperty(), xamlRoot); + xaml::FrameworkElement const &accessibleRoot) noexcept { + winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Set(AccessibleRootProperty(), accessibleRoot); } /*static*/ xaml::XamlRoot XamlUIService::GetXamlRoot(IReactPropertyBag const &properties) noexcept { return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(XamlRootProperty()); } -/*static*/ xaml::XamlRoot XamlUIService::GetAccessibleRoot(IReactPropertyBag const &properties) noexcept { +/*static*/ xaml::FrameworkElement XamlUIService::GetAccessibleRoot(IReactPropertyBag const &properties) noexcept { return winrt::Microsoft::ReactNative::ReactPropertyBag(properties).Get(AccessibleRootProperty()); } diff --git a/vnext/Microsoft.ReactNative/XamlUIService.h b/vnext/Microsoft.ReactNative/XamlUIService.h index 987ed5d018f..46b22c19ea3 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.h +++ b/vnext/Microsoft.ReactNative/XamlUIService.h @@ -23,9 +23,9 @@ struct XamlUIService : XamlUIServiceT { JSValueArgWriter const &eventDataArgWriter) noexcept; static void SetXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; - static void SetAccessibleRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; + static void SetAccessibleRoot(IReactPropertyBag const &properties, xaml::FrameworkElement const &accessibleRoot) noexcept; static xaml::XamlRoot GetXamlRoot(IReactPropertyBag const &properties) noexcept; - static xaml::XamlRoot GetAccessibleRoot(IReactPropertyBag const &properties) noexcept; + static xaml::FrameworkElement GetAccessibleRoot(IReactPropertyBag const &properties) noexcept; static void SetIslandWindowHandle(IReactPropertyBag const &properties, uint64_t hwnd) noexcept; static uint64_t GetIslandWindowHandle(IReactPropertyBag const &properties) noexcept; diff --git a/vnext/Microsoft.ReactNative/XamlUIService.idl b/vnext/Microsoft.ReactNative/XamlUIService.idl index a8f2cc744a6..d0d57d66ee5 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.idl +++ b/vnext/Microsoft.ReactNative/XamlUIService.idl @@ -27,11 +27,11 @@ namespace Microsoft.ReactNative { static void SetXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands DOC_STRING("Set accessible XamlRoot for app. This XamlRoot should be able to create an automation peer. This must be manually provided to the ReactInstanceSettings when using XamlIslands to have access to accessibility methods.") - static void SetAccessibleRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); + static void SetAccessibleRoot(IReactPropertyBag properties, XAML_NAMESPACE.FrameworkElement accessibleRoot); DOC_STRING("Retrieve XamlRoot for app.") static XAML_NAMESPACE.XamlRoot GetXamlRoot(IReactPropertyBag properties); DOC_STRING("Retrieve accessible XamlRoot for app.") - static XAML_NAMESPACE.XamlRoot GetAccessibleRoot(IReactPropertyBag properties); + static XAML_NAMESPACE.FrameworkElement GetAccessibleRoot(IReactPropertyBag properties); static UInt64 GetIslandWindowHandle(IReactPropertyBag properties); DOC_STRING("Sets the windowHandle HWND (as an uint64) to be the XAML Island window for the current React instance. Pass the value returned by IDesktopWindowXamlSourceNative get_WindowHandle.") From 612ba53bba4e00ce456173662718244f7a9c3be2 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:05:14 -0800 Subject: [PATCH 09/10] Add Requested Changes --- vnext/Microsoft.ReactNative/XamlUIService.idl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/vnext/Microsoft.ReactNative/XamlUIService.idl b/vnext/Microsoft.ReactNative/XamlUIService.idl index d0d57d66ee5..e69de886b47 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.idl +++ b/vnext/Microsoft.ReactNative/XamlUIService.idl @@ -26,11 +26,11 @@ namespace Microsoft.ReactNative { DOC_STRING("Set XamlRoot for app. This must be manually provided to the ReactInstanceSettings when using XamlIslands.") static void SetXamlRoot(IReactPropertyBag properties, XAML_NAMESPACE.XamlRoot xamlRoot); // This needs to be manually provided to the ReactInstanceSettings when using XamlIslands - DOC_STRING("Set accessible XamlRoot for app. This XamlRoot should be able to create an automation peer. This must be manually provided to the ReactInstanceSettings when using XamlIslands to have access to accessibility methods.") + DOC_STRING("Set accessible FrameworkElement for app. Make sure the element is able to create an automation peer. This must be manually provided to the ReactInstanceSettings when using XamlIslands to have access to accessibility methods.") static void SetAccessibleRoot(IReactPropertyBag properties, XAML_NAMESPACE.FrameworkElement accessibleRoot); DOC_STRING("Retrieve XamlRoot for app.") static XAML_NAMESPACE.XamlRoot GetXamlRoot(IReactPropertyBag properties); - DOC_STRING("Retrieve accessible XamlRoot for app.") + DOC_STRING("Retrieve accessible FrameworkElement for app.") static XAML_NAMESPACE.FrameworkElement GetAccessibleRoot(IReactPropertyBag properties); static UInt64 GetIslandWindowHandle(IReactPropertyBag properties); From af81234b573d023fc8626b74b69bb13a4f9f1f19 Mon Sep 17 00:00:00 2001 From: Chiara Mooney <34109996+chiaramooney@users.noreply.github.com> Date: Thu, 11 Mar 2021 17:42:50 -0800 Subject: [PATCH 10/10] Fix Formatting --- vnext/Microsoft.ReactNative/XamlUIService.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/vnext/Microsoft.ReactNative/XamlUIService.h b/vnext/Microsoft.ReactNative/XamlUIService.h index 46b22c19ea3..d161784ce39 100644 --- a/vnext/Microsoft.ReactNative/XamlUIService.h +++ b/vnext/Microsoft.ReactNative/XamlUIService.h @@ -23,7 +23,9 @@ struct XamlUIService : XamlUIServiceT { JSValueArgWriter const &eventDataArgWriter) noexcept; static void SetXamlRoot(IReactPropertyBag const &properties, xaml::XamlRoot const &xamlRoot) noexcept; - static void SetAccessibleRoot(IReactPropertyBag const &properties, xaml::FrameworkElement const &accessibleRoot) noexcept; + static void SetAccessibleRoot( + IReactPropertyBag const &properties, + xaml::FrameworkElement const &accessibleRoot) noexcept; static xaml::XamlRoot GetXamlRoot(IReactPropertyBag const &properties) noexcept; static xaml::FrameworkElement GetAccessibleRoot(IReactPropertyBag const &properties) noexcept;