mirror of
https://github.com/l0ng-ai/tty7.git
synced 2026-09-21 16:02:20 +00:00
fix(terminal): report the terminal as the focused element
A terminal draws its own glyphs, so nothing outside the window can read what is on screen. That much is a terminal being a terminal. What is not is that the window reports no focused element at all. gpui sets accessibility focus in exactly one place: a `div` that tracks a focus handle and has an a11y node of its own. The terminal surface tracks the focus handle and never asks for a role, so it has no node, so `set_focus` is never reached — and a client asking the window what has focus is handed the window. Measured on Windows 11 26200 with a UI Automation probe: the window answers with `WindowPattern` and nothing else, publishes zero descendants, and `FocusedElement` is the top-level window, supporting neither `ValuePattern` nor `TextPattern`. A screen reader has nothing to say about a tty7 window for the same reason. It reaches past screen readers. A dictation tool pastes its transcript and then asks the focused element what it now says, to check the text arrived. Against tty7 it gets no element to ask, concludes the paste failed, and hands the transcript back for the user to paste by hand — while the bytes it sent are already in the pty and the text is on screen. That is what led here. The fix is the surface asking for a role: it gets a node, and focus lands on it. `MultilineTextInput` rather than `Terminal` because `Terminal` maps to a document that reports itself as not editable, and "is this something text can be put into" is the question these clients are actually asking. The node carries no text of its own yet — reading the grid out is a separate change with a cost per frame, and this one has none: gpui builds the a11y tree only once something attaches to it, so a window nobody is inspecting still builds nothing. The path this fixes is platform-independent; it was verified on Windows, where the dictation tool that surfaced it runs.
This commit is contained in:
@@ -6820,6 +6820,11 @@ impl Render for TerminalView {
|
||||
|
||||
div()
|
||||
.id("terminal-surface")
|
||||
// The surface, not the grid inside it, is what carries the role:
|
||||
// a11y focus is only ever reported for a `div` that tracks a focus
|
||||
// handle *and* has a node of its own, so a terminal with no role
|
||||
// here is a window whose focused element is the window.
|
||||
.role(gpui::Role::MultilineTextInput)
|
||||
.track_focus(&self.focus_handle)
|
||||
.key_context(self.key_context())
|
||||
.size_full()
|
||||
|
||||
Reference in New Issue
Block a user