Skip to content

feat(flterm): expose accessible terminal semantics - #102

Open
adonm wants to merge 1 commit into
elias8:mainfrom
adonm:upstream/101-accessibility
Open

feat(flterm): expose accessible terminal semantics#102
adonm wants to merge 1 commit into
elias8:mainfrom
adonm:upstream/101-accessibility

Conversation

@adonm

@adonm adonm commented Jul 15, 2026

Copy link
Copy Markdown

Summary

Adds a screen-reader semantics node to TerminalView:

  • semanticsLabel / semanticsHint params with sensible defaults ('Terminal' / 'Activate to focus terminal input'). Set semanticsLabel: null to delegate the accessible surface to an embedding application.
  • The semantics node exposes the visible, non-concealed terminal viewport as plain text (wide cells widened, SGR 8 invisible cells omitted, wrapped rows joined), captured from the render pipeline after each paint and coalesced through a bounded 100 ms refresh interval — so output updates never announce as a live region.
  • The snapshot follows the visible scrollback viewport (primary screen only), and switching controllers clears the cached value.
  • Focus/tap actions route to terminal input focus.

Implementation

  • FrameBuilder.semanticsText() walks the existing RowIterator/CellIterator state and emits plain text; RenderPipeline/renderer forward a monotonically increasing semanticsGeneration and an onSemanticsText callback fired from paint after frame sync.
  • _TerminalViewState schedules generation bumps on terminal output and primary-screen scroll, and rebuilds the semantics node through a ValueNotifier without recreating the terminal subtree.

Tests

  • Frame builder: semantics iteration preserves subsequent terminal updates.
  • View: visible non-concealed text + hint/actions; label delegation via null; scrollback viewport tracking; controller swap clears cached semantics.

This was carried downstream in the Zuko remote-shell client and is ported here from that implementation onto the refactored frame-source pipeline.

@adonm
adonm force-pushed the upstream/101-accessibility branch from ed9a137 to 2b8ca42 Compare August 15, 2026 22:36
@adonm adonm changed the title feat(flterm): expose terminal accessibility semantics feat(flterm): expose accessible terminal semantics Aug 15, 2026
TerminalView now renders a semantics node with the visible, non-concealed
terminal viewport as its value, along with the configured label, hint, and
focus actions. The render pipeline captures the accessible snapshot after
each paint, coalesced through a bounded refresh interval, and follows the
visible scrollback viewport. Set semanticsLabel to null to delegate the
accessible surface to an embedding application.

Ported from the downstream GTK4-era implementation onto the refactored
frame-source render pipeline.
@adonm
adonm force-pushed the upstream/101-accessibility branch from 2b8ca42 to ef585ed Compare August 15, 2026 22:49
@adonm

adonm commented Aug 15, 2026

Copy link
Copy Markdown
Author

Local validation on the pinned Flutter beta: flutter analyze clean, and the full rendering/view/controller test suites pass — 540 tests, including the four new semantics tests (visible non-concealed text, label delegation, scrollback viewport tracking, controller swap clearing).

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