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

gfx/accessible_info.h

What a component IS, as opposed to what it looks like.

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

Design notes

The gap

The component tree is a purely visual object. A knob is a rectangle that draws an arc and responds to drags; nothing in it says "this is a control called Gain, currently at -6.0 dB, whose value you may change". So a producer using a screen reader gets silence, and a plugin generated by this SDK is unusable without sight.

The keyboard half of this landed first -- every control is reachable by Tab and operable by arrow keys, which was itself a total barrier -- but a control you can operate and cannot hear is still not usable.

What this file is, and what it is not

The vocabulary only: a role, a name, a value and a range. Split from accessibility.h so Component can declare accessibleInfo() without including the traversal that walks Components -- the circular include that otherwise forces the whole thing into component.h.

This file on its own is not a screen reader integration -- it is what a bridge READS. gfx/uia_win32.h is the Windows bridge and is verified against a real UI Automation client. gfx/accessibility_mac.h is the macOS bridge, onto NSAccessibility, and as of 2026-10-14 it has been COMPILED against a shim of Apple's declarations and never run: no Mac is in this loop. So on Windows a reader is known to hear a plugin built with this; on macOS it should, and tests/mac_input_selftest.cpp is what a Mac developer runs to find out.

(This paragraph said "nothing here reaches UI Automation" until the Windows bridge landed one commit later, and "macOS has none yet" until the Mac one did. A header comment that describes a limitation is a claim with an expiry date, and this one is dated deliberately.)

Operating a control, not only reading it

A reader also ACTS: VoiceOver's "increment" on a slider, "press" on a button, typing a value straight into a field. Those go to the component itself (Component::performAccessibleAction, setAccessibleValue, setAccessibleText), which answers through the same code its keys and clicks use -- a slider stepped by a reader brackets the edit exactly as an arrow key does, so the host records one gesture either way. What a control will do is part of its description (actions, valueSettable) so a bridge can list it without asking the live tree from another thread.

Why roles are a small closed set

Every platform has its own vocabulary and they do not agree. A closed enum that each bridge maps into its own platform's names is the only arrangement where adding a second platform cannot change what the first one says.

Types 1

Everything a screen reader would want about one component.

Built on demand rather than kept as state: the value of a knob is already in the knob, and a second copy updated by a callback is a second copy that can be stale at exactly the moment somebody asks.

Functions 2

Enums 3

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