VoiceOver: QuickNav does not engage after interacting with the terminal; content goes stale; review cursor jumps to top on new output
- iTerm2 version: 3.7.0beta5 (all three problems also reproduced on current master built from source)
- OS version: macOS 26.5.2
- Plist: will attach.
- Debug log: the reproduction is deterministic with the steps below; happy to capture a debug log on request.
- Screen capture: the symptoms are in VoiceOver speech and navigation rather than on screen, so the steps below are the clearest reproduction. Can record one on request.
- Performance/CPU/hang: no
- Crash: no
- Excessive memory: no
Detailed steps to reproduce the problem:
- Enable VoiceOver (Cmd+F5) and QuickNav (press the Left and Right arrows together).
- In an iTerm2 session, run
seq 1 40. - VO-interact with the terminal text area and press Up/Down.
- While still interacting, press Cmd+K to clear, run
ls, and navigate again. - Navigate up to an earlier output line, then run any command that produces output.
What happened:
- Step 3: Up/Down goes to the shell (command history) instead of moving the VoiceOver cursor. It only starts working after toggling QuickNav off and on (Left+Right twice).
- Step 4: VoiceOver keeps reading the pre-clear content; the new output is unreachable until I stop interacting and re-interact.
- Step 5: The VoiceOver review cursor jumps to the top of the terminal, losing my reading position.
What should have happened (this is how Terminal.app behaves):
- Step 3: The VoiceOver cursor moves line by line immediately; no QuickNav toggle needed.
- Step 4: VoiceOver reads the current content as soon as it changes.
- Step 5: The cursor stays on the line I was reading, and the new output is reachable by navigating down.
Cause (from investigation)
- The terminal text area advertises an AXDocument attribute and a settable AXValue (settable only because of a no-op setter kept for Full Keyboard Access, Issue 10023). That makes VoiceOver treat it as more than a plain text area, which wedges QuickNav on interaction (step 3). Terminal.app advertises neither.
- The announce-new-output path suppresses value-changed notifications during an output burst and posts layout-changed with NSAccessibilityUIElementsKey once output settles. That notification directs VoiceOver to move its cursor to the element, relocating the review cursor to the top (step 5), and since no content notification is re-posted at settle, VoiceOver’s cached model goes stale during interaction (step 4).
I have a fix for all three and will open a pull request referencing this issue.