Skip to content

Feat/macos accessibility support#267

Open
xell wants to merge 2 commits into
ZenNotes:mainfrom
xell:feat/macos-accessibility-support
Open

Feat/macos accessibility support#267
xell wants to merge 2 commits into
ZenNotes:mainfrom
xell:feat/macos-accessibility-support

Conversation

@xell

@xell xell commented Jun 25, 2026

Copy link
Copy Markdown

Expose the editor to macOS accessibility clients

Problem

On macOS, accessibility tools that read the system accessibility (AX) tree could not see the editor's text. Chromium builds its renderer accessibility tree lazily, only after an assistive client performs the macOS activation handshake. Tools that read the tree without performing that handshake were left blind: they could see the app window but not the CodeMirror content, so they appeared to attach, yet did nothing. The Grammarly desktop app is the clearest example (its bubble showed, but it never flagged anything), but this affects the whole class of AX-based text tools.

A second, related issue: a document whose first line was a heading disabled checking for the entire field because the heading fold arrow is at opacity: 0 but is an accessibility-visible role="button" placed at the very start of the line. Clients that inspect a field's leading content treated the whole field as a non prose control.

Changes

  • Enable the renderer accessibility tree on macOS (app.setAccessibilitySupportEnabled(true) in whenReady). This exposes editor content to AX clients that do not trigger Chromium's lazy activation on their own.
  • Mark the heading fold arrow aria-hidden  so it no longer sits in the accessibility tree as a leading interactive element. Folding is unchanged and still available by mouse, keyboard, and Vim.
  • Mark the live preview list bullet aria-hidden  so the decorative glyph does not pollute the field's text value.
  • Add an aria-label to the editor surface so clients announce it as a named text field.

No rendering or editing behavior changes. Typecheck and the full test suite pass.

Tradeoffs to flag

  • Enabling accessibility unconditionally has a small, always-present memory and CPU cost (Chromium keeps the tree live and updates it as you type), paid by every macOS user. The alternative is to gate it behind a setting; happy to do that if preferred. Scoped to macOS for now; the same API would likely help Windows (UI Automation) too.
  • Hiding the fold arrow from the accessibility tree means a screen reader can no longer discover that one affordance, though folding remains reachable by keyboard and Vim.

Not addressed (out of scope)

  • Tools that skip the first word after a list marker: reproduce in unrelated editors, so it is the tool's behavior, not ours.
  • Live preview tables: editable cells are nested in a contenteditable="false" widget, so AX clients disengage inside them. Workaround: the existing "Render tables in live preview" setting.

xell and others added 2 commits June 25, 2026 23:27
On macOS, Chromium builds its renderer accessibility tree lazily, only once
an assistive client performs the activation handshake. Tools that read the
tree without performing that handshake (e.g. the Grammarly desktop app and
similar proofreaders) were left blind: they found the app window but never
the CodeMirror content, so they appeared to attach yet did nothing.

- main: call app.setAccessibilitySupportEnabled(true) in whenReady (darwin),
  exposing editor content to that class of accessibility clients.
- heading fold arrow: aria-hidden. It is an opacity:0 but AX-visible
  role="button" at the start of every heading line; as a field's leading
  element it made some clients treat the whole field as a non-prose control
  and disengage (e.g. any document starting with a heading). Folding is
  unchanged and still available by mouse, keyboard, and vim.
- editor surface: aria-label so clients announce it as a named text field.

No rendering or editing behavior changes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lity tree

The rendered list bullet is decorative, so mark it aria-hidden to keep it out
of the field's text value for clients that read it (screen readers,
proofreaders). The underlying `- ` source text is unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xell
xell requested a review from adibhanna as a code owner June 25, 2026 11:40
@xell
xell marked this pull request as draft June 26, 2026 04:46
@xell
xell marked this pull request as ready for review June 26, 2026 05:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant