-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Initial AccessibilityInfo implementation #5849
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
I think there might be some issues openaround api completion for AccessibilityInfo. Feel free to have this PR close them if you're wanting to track specific implementation issues. |
| onSuccess(false); | ||
| } | ||
|
|
||
| void AccessibilityInfo::setAccessibilityFocus(double reactTag) noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't remember if we generate warnings for unused params or not, but consider commenting out the name.
vnext/src/RNTester/js/examples/Accessibility/AccessibilityInfoExample.js
Show resolved
Hide resolved
|
|
||
| void AccessibilityInfo::isTouchExplorationEnabled( | ||
| std::function<void(React::JSValue const &)> const &onSuccess) noexcept { | ||
| onSuccess(false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
false [](start = 12, length = 5)
Re: - isTouchExplorationEnabled always returns false. As far as I know windows does not expose a hook to know if someone is running narrator or similar tools. Open question, should we default to true instead of false?
Idk what "touch exploration" means & how it's used, but as far as telling whether an a11y tool is running goes: There's UiaClientsAreListening (https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcoreapi/nf-uiautomationcoreapi-uiaclientsarelistening). This is about events which is a subset of UIA functionality, but I'd assume that any "real" a11y tool would do that. If you should decide to use UiaClientsAreListening, do a sanity check on its returns; I vaguely recall that on earlier Win10 versions this returned true even if there was no real a11y tool running.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that API safe for UWP usage?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also IRawElementProviderAdviseEvents (https://docs.microsoft.com/en-us/windows/win32/api/uiautomationcore/nn-uiautomationcore-irawelementprovideradviseevents). This is something that needs to be implemented in the UI framework, and we'd have to connect to that - probably too complicated for what we want to achieve here.
In reply to: 478625704 [](ancestors = 478625704)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so (we're using it in WinRT platform adaptors in FastAcc). Forrest would know for sure.
In reply to: 478626922 [](ancestors = 478626922)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per otools/bin/mox/mosdk-shaped-fullanno.xml, it looks like UiaClientsAreListening is allowed.
In reply to: 478626922 [](ancestors = 478626922)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It still seems to return true even if nothing is running. Not sure how useful that hook up is then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in-box XAML uses UiaClientsAreListening for this purpose, and I am pretty sure this is working reliably there (ie it returns true only when an AT like Narrator is running).
In reply to: 478640914 [](ancestors = 478640914,478626922)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kmelmon it returns true if there is a UIA client that is subscribed to events - but UIA clients don't have to do that, instead they can just poll properties every N seconds. Narrator does subscribe to UIA events, so if the intent is to only get this working with narrator and maybe not support other UIA clients then that API is fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's been a long time since I looked at this API, but IIRC it could return false positives. For example, I think it returns true on touch devices even if there no ATs listening.
| onSuccess(false); | ||
| } | ||
|
|
||
| void AccessibilityInfo::setAccessibilityFocus(double /*reactTag*/) noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AccessibilityInfo::setAccessibilityFocus [](start = 5, length = 40)
We can use AutomationPeer::SetFocusCore() to implement this. See:
https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.automation.peers.automationpeer.setfocuscore?view=winrt-19041
Also see XAML code that implements it here:
%SDXROOT%\onecoreuap\windows\dxaml\xcp\dxaml\lib\winrtgeneratedclasses\AutomationPeer.g.cpp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That moves actual focus to that element. This API is just trying to move the narrator focus. -- So, when running narrator, it would move the blue rectangle without moving keyboard focus.
(Otherwise, this API is pointless, since there is a similar API that sets normal focus)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops I didn't realize it's just supposed to move narrator focus. I'm asking around, meanwhile I see some hits in Windows that suggest raising the AutomationFocusChanged event might work (eg %SDXROOT%\xbox\shellapps\Shared\Xbox.Foundation.UI\Narrator\NarratorReader.cpp line 125)
// Raise the focus changed automation event, to ensure that this element receives narrator focus so that it reads the element and textToRead together.
auto automationPeer = FrameworkElementAutomationPeer::FromElement(focusedElement);
if (automationPeer != nullptr)
{
automationPeer.RaiseAutomationEvent(AutomationEvents::AutomationFocusChanged);
}
In reply to: 481482991 [](ancestors = 481482991)
| return; | ||
| } | ||
|
|
||
| auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
auto peer = xaml::Automation::Peers::FrameworkElementAutomationPeer::FromElement(element); [](start = 4, length = 90)
Is this still returning null in all cases? If so feel free to file an issue and assign to me, I can look into it.
|
Hello @acoates-ms! Because this pull request has the p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (
|
| m_context = reactContext; | ||
| } | ||
|
|
||
| void AccessibilityInfo::isReduceMotionEnabled(std::function<void(React::JSValue const &)> const &onSuccess) noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[](start = 88, length = 1)
(nit) can this be && to avoid std::function copy here and while passing into further lambdas?
| } | ||
|
|
||
| void AccessibilityInfo::isReduceMotionEnabled(std::function<void(React::JSValue const &)> const &onSuccess) noexcept { | ||
| auto jsDispatcher = m_context.JSDispatcher(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jsDispatcher [](start = 7, length = 12)
std::move?
| // no-op - This appears to be unused in RN | ||
| } | ||
|
|
||
| void AccessibilityInfo::announceForAccessibility(std::string announcement) noexcept { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
string [](start = 54, length = 6)
Similar comment, can this be either && or const& to avoid accidental copying?
NikoAri
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
![]()
Summary: Cherry picks: microsoft#5849 microsoft#7220 microsoft#7290 Test Plan: See D29689294 Test Plan Reviewers: ericroz Reviewed By: ericroz Subscribers: eliwhite Differential Revision: https://phabricator.intern.facebook.com/D30940769 Tasks: T85606613 Signature: 30940769:1631724353:41db1d978132f06502803cfb4df0323f6da84732
There are several things wrong with this implementation.
isTouchExplorationEnabledalways returns false. As far as I know windows does not expose a hook to know if someone is running narrator or similar tools.Open question, should we default to true instead of false?UsingUiaClientsAreListeningfor now)setAccessibilityFocusis unimplemented. - Turns out this method on this native module isn't called by RN. The AccessibilityInfo.setAccessibilityFocus method calls directly into UIManager.sendAccessibilityEvent (which we also need to implement) (Implement UIManager.sendAccessibilityEvent #5907)announceForAccessibilityTries to find an element to raise the event from. All the elements I tried do not seem to return anything in the call FrameworkElementAutomationPeer::FromElement, so the method ends up being a no-op. Someone with more XAML expertise should see if they can come up with something better. -- We might want to look into adding an argument to the core function to allow users to specify which element should do the announce, since in desktop environments that might make more difference. (AccessibilityInfo::announceForAccessibility fails to announce #5908)I expect to open an issue to track all the unresolved issues above when this goes in. But having this implementation does provide a good impl for
isReduceMotionEnabled, and fixes the Redbox on the existingAccessibilityExampletest page.Microsoft Reviewers: Open in CodeFlow