Control Screen Reader from Applications
Problem
Many terminal applications, particularly those that redraw parts of the screen have many issues when being used with a screen reader as everything will be read by the screen reader, including "decorative" and redrawn content.
Proposal
This proposal intends to solve this problem by allowing applications to stop and start announcing to the screen reader, as well as providing "screen reader hints" that will be announced but not printed (similar to alt
text in HTML). Such a mechanism if adopted could potentially enable applications that make heavy use of the alt buffer to become accessible to visually impaired users. This feature would be enabled by default but should have no impact on users not using a screen reader.
OSC Ps ; Pt ST
-
Ps = 2 0 0
-> Stop announcing incoming data to screen reader,Pt
is an optional string that will be announced immediately. The screen reader will resume announcing incoming data if any key is pressed. -
Ps = 2 0 1
-> Resume announcing incoming data to screen reader,Pt
is an optional string that will be announced immediately. -
Ps = 2 0 2
-> AnnouncePt
immediately to the screen reader.
Note that the reason any key press will force the screen reader to announce again is to prevent situations where applications are terminated while the screen reader is not announcing or where applications are misbehaving.
The OSC sequence described was just the first I saw that I could use in a proof of concept, that's up for discussion.
Examples
The below examples show the xterm.js and the box that shows what is read by VoiceOver (macOS screen reader).
Print "hello world", announce "hello screen reader":
echo -e "hello\x1b]200;\x1b\\ viewport\x1b]201; screen reader\x1b\\"
Print a progress bar that updates in-place, announce "0%, 50%, Done":
echo -ne "\x1b]200;0%\x1b\\[ ] 0%" && sleep 1 && \
echo -ne "\x1b[1G[=== ] 25%" && sleep 1 && \
echo -ne "\x1b[1G[====== ] 50%\x1b]202;50%\x1b\\" && sleep 1 && \
echo -ne "\x1b[1G[========= ] 75%" && sleep 1 && \
echo -ne "\x1b[1G[============] Done\x1b]201;Done\x1b\\"
Implementation
I put together a proof of concept on Tyriar/xterm.js#screen_reader_hint.