Files
cthulhu/docs/wine-accessibility.md

3.1 KiB

Wine Accessibility

Cthulhu's Wine integration has three components:

  1. WineAccessibility, a built-in plugin which discovers same-user Wine and Proton prefixes.
  2. cthulhu-wine-access.exe, a Wine-hosted helper built with Winegcc.
  3. The org.stormux.Cthulhu1.Service D-Bus interface used by the helper and Prism.

The manager starts one helper per prefix, uses WINEPREFIX or STEAM_COMPAT_DATA_PATH/pfx, and passes the prefix's own loader through WINELOADER. Discovery requires an actual Wine loader process, so exported prefix variables and idle wineserver processes do not keep helpers alive. A helper is stopped after its prefix has been idle for ten seconds. Repeated early exits use exponential restart backoff. If an actual NVDA window already exists in the prefix, the helper yields the controller endpoint to it while continuing to provide standard-dialog reading.

Controller Compatibility

The helper registers the current NvdaCtlr.<session>.<desktop> local RPC endpoint, the legacy NvdaCtlr endpoint used by older official controller clients, and the Controller 1, 2, and 3 interface UUIDs. It also creates the wxWindowClassNR / NVDA window used by official Tolk releases for detection. The compatibility window is explicitly hidden, nonactivating, and excluded from ordinary window switching. Therefore applications can keep the original nvdaControllerClient32.dll, nvdaControllerClient64.dll, and Tolk.dll; no DLL override is required.

Plain speech queues like NVDA Controller output; Tolk's interrupt flag uses the separate cancel call before speaking. Braille, cancel, and process ID calls are also implemented. Speaking-state queries return ERROR_CALL_NOT_IMPLEMENTED, because Cthulhu's current speech backend does not expose an accurate answer. SSML is validated by Cthulhu and currently fails with ERROR_NOT_SUPPORTED. This is intentional: accepting SSML while dropping mark callbacks or reporting completion too early would violate the Controller 2 contract.

The current Meson target builds the 64-bit helper. A 32-bit helper requires a 32-bit Winegcc and 32-bit GLib/GIO development environment and should be shipped by multilib packaging.

Standard Dialog Reading

The first reader stage listens for MSAA focus, name, value, state, and selection events. When Wine's MSAA proxy has no useful data for a standard control, the helper falls back to the control's Win32 class and message protocol. Combo boxes, list boxes, edits, buttons, sliders, and static controls can therefore expose useful names, roles, values, and states without replacing the MSAA path for controls which already read correctly.

This class-based fallback is adapted from the LGPL wine-a11y reader published by Mudb0y.

The reader does not expose custom-drawn, DirectX, or game-specific interfaces. UI Automation coverage and an AT-SPI object broker remain separate later stages.

Prism

Prism has a distinct Cthulhu backend ID. Native applications call Cthulhu's D-Bus service directly. Wine builds use Prism's Winelib D-Bus bridge. This backend supports speech, braille, combined output, and cancellation without claiming to be Orca.