Search guides and the APICtrl K
  1. API reference
  2. Native GUI

gfx/accessibility_mac.h

The macOS end of accessibility: handing our component tree to NSAccessibility.

#include <sonore/gfx/accessibility_mac.h>
On this page

Design notes

Written, compiled, never run

Said first, as window_cocoa.h says it: as of 2026-10-14 no machine in this project has executed a line of this file. It has been COMPILED, on Windows, against the Objective-C runtime shim in tests/au_shim (tests/ mac_syntax_mac_input.cpp), which proves every name exists and every call has the right shape -- and not that VoiceOver hears anything. The Windows bridge (uia_win32.h) is verified by being the screen reader; this one is verified by nobody until a Mac developer runs tests/mac_input_selftest.cpp, which asks AppKit -- through the same attribute API the accessibility server uses -- what this file exposes, and prints it.

The shape

Same as UIA's, on the same platform-neutral model (accessibility.h):

the editor's NSView   -- an AXGroup named after the editor, whose
                         accessibilityChildren are the top-level elements
                         (window_cocoa.h registers those view methods)
one element each      -- an NSAccessibilityElement SUBCLASS, created at
                         runtime with objc_allocateClassPair like the
                         view itself, one instance per accessible
                         component

The roles, subroles and how each reads its value come from accessibleRoleMapping -- the same table UIA reads -- so a combo box cannot be one thing to NVDA and another to VoiceOver by accident.

Why elements are KEPT, where UIA makes them per call

A UIA client identifies an element by its runtime id, so the Windows bridge can hand out a new COM object on every navigation. VoiceOver identifies an element by the OBJECT: it compares pointers to see whether the focus moved, and a notification is about the object it is posted for. So each element lives as long as its component does -- matched across rebuilds by detail::matchAccessibleNodes -- and is told it is destroyed (NSAccessibilityUIElementDestroyedNotification) when the component goes.

Threads

None to worry about, unlike UIA: AppKit services accessibility requests on the main thread, which is the thread the editor runs on. Every read comes from a snapshot retaken on the editor's clock, and every ACTION retakes it first, so the component pointer it acts on was found in the live tree a moment ago rather than remembered from a frame that may have closed a panel.

Types 5

NSPoint, NSSize and NSRect, laid out as CoreGraphics lays them out.

No comment on this one in the header yet; the source says the rest.

No comment on this one in the header yet; the source says the rest.

The two AppKit functions the bridge calls, which are C functions rather than messages and so are resolved with dlsym -- the same rule window_cocoa.h follows for CoreGraphics, so no project has to name a framework.

The bridge: the snapshot, the elements, and the announcements.

Owned by NativeWindowCocoa, created with its view and detached before the view goes. Detaching leaves every element answering as an empty element, which is the right answer for one VoiceOver still holds after the editor closed.

Functions 41

↑↓ to move↵ to openEvery public name in the headers, and every guide