Skip to content

Accessibility on Windows

yaakovschectman edited this page Mar 14, 2023 · 3 revisions

Microsoft Active Accessibility

Microsoft Active Accessibility (MSAA) is an older interface used for accessibility. It can interact with screen readers such as Windows Narrator or NVDA, and has a more limited set of available functionality compared to newer interfaces.
The base of MSAA is the IAccessible interface, which all a11y-providing classes extend. MSAA methods are prefixed with acc_. In the Flutter engine, AXPlatformNodeWin extends IAccessible. Any IAccessible objects used are COM interfaces, and should be initialized and reference counted accordingly.
When a program such a screen reader queries an application for an a11y object, it sends a WM_GETOBJECT window message, to which the window will respond with the result of passing the IAccessible of its root to the function LresultFromObject.

UI Automation

UI Automation is one framework for Windows that is used for accessibility, for example, by screen readers such as Windows Narrator or NVDA. The interface class IRawElementProviderFragment must be implemented by any object representing a UIA fragment, i.e. an accessibility item that exists on the screen, such as a text label, a pane, a button, etc.. For the Flutter engine, the class AXPlatformNodeWin extends IRawElementProviderFragment in order to serve this purpose. Abstract methods in IRawElementProviderFragment provide functionality including retrieving the bounds of the fragment on screen, testing if an on-screen point is within the fragment, and retrieving properties of the fragment such as name and role. Each of the methods of IRawElementProviderFragment implemented by AXPlatformNodeWin are listed in ax_platform_node_win.h. Additionally, IRawElementProviderFragment contains a method that returns the fragment root of the fragment.
The fragment root represents the root of a fragment tree, and extends the class IRawElementProviderFragmentRoot. Generally, and in the case of Flutter, these correspond 1-1 to a window. We extend this class in AXFragmentRootPlatformNodeWin in ax_fragment_root_win.cc. This class contains methods to retrieve the fragment at a given point, and the current focus of the tree.
The Window class’s OnGetObject handles WM_GETOBJECT window messages, which a screen reader will dispatch to access the UIA fragment tree. When the lparam parameter of the message is equal to the constant UiaRootObjectId, the request is asking for the UIA root, and a reference is created out of the window’s fragment root with UiaReturnRawElementProvider, which is then returned to the message sender.
Patterns are optional interfaces which UIA elements can provide for additional functionality. For example, providing the ITextProvider allows a fragment to be treated as formatted text, and IToggleProvider indicates that a fragment can be toggled (e.g. a checkbox) and provides its current toggle state (i.e. on, off, mixed). The UIA method GetPatternProvider is used to return an instance of a requested interface type, or none if it is not provided. Provided patterns may or may not be the same as the fragment itself. For example, in AXPlatformNodeWin, when IToggleProvider is requested, a casted pointer to the node is returned, as AXPlatformNodeWin extends IToggleProvider. By contrast, when an ITextProvider is requested, a separate object is returned, rather than AXPlatformNodeWin being a subclass of ITextProvider. In this case, this is necessary, as other inherited methods of AXPlatformNodeWin share a name but different signature to those in ITextProvider, so it cannot extend both.

Whether or not the engine makes use of UI Automation is controlled in the Window class, in Window::OnGetObject. When a UIA message is received, a UIA response is only issued if the engine was built with the FLUTTER_ENGINE_USE_UIA macro defined.

Flutter Wiki

Process

Framework repo

The Flutter CLI Tool

Engine repo

Packages repo

Engineering Productivity

User documentation

Clone this wiki locally