Skip to content

syn speak

Velle Sinclair edited this page Aug 31, 2026 · 3 revisions

Speech and dictation

The desktop, out loud — syn-speak. Everything on this desktop says what it has to say in pixels; this is the other channel. It announces the window that has focus as focus moves, reads the text you have highlighted, and speaks any line handed to it.

Shipped by the synui package as /usr/bin/syn-speak.

It is an announcer, not a full screen reader — and it says so itself. A real screen reader walks the accessibility tree and reads every widget under the cursor, which needs AT-SPI support in each toolkit and is a project of its own. What this does is the half that is both useful today and honest: what has focus, and what it is asked for. Orca remains the answer for the full tree, and this does not pretend otherwise.

Nothing speaks until asked. It is off on a fresh install, and the switch is per user. A desktop that started talking after an update would be the worst possible version of this feature.

The three keys

Key What it does
Super+Shift+U Screen reader on/off — announce the focused window as focus moves, and press again to stop
Super+U Read whatever is highlighted right now, once
Super+Shift+V Dictate — listen once, and type what you said where the cursor is (vibe)

They are keys, and not only a menu item, for the obvious reason: a screen reader you can only start from a terminal is not one — the person who needs it is the person who cannot read the terminal to start it.

One chord toggles, rather than a pair. A reader talking over you has to be stoppable with the key you just pressed, not with a different one you have to remember while it is talking.

Super+Shift+V is V for voice; Super+V is the clipboard.

From a window

Two panels offer the same switch, because SynapseOS can be installed with KDE or GNOME instead of synui and the setting still has to be reachable:

  • synui's control panelSuper+CSoundSpeech. Two rows: Screen reader and Answer to its name (that second one is vibe's wake word, and it holds a microphone open — the bar shows a microphone icon while it does).
  • syn-settings ▸ Speech — the same two switches, plus the speech rate, the volume, the wake words, which engines this box actually has, and the two units behind the switches: syn-speak.service (the announcer) and vibe-wake.service (the listener). That last pair is the row to read when a switch says On and nothing happens — a switch and the thing it switches are two separate facts, and this is where the second one is visible.

Neither reimplements anything. They read the state files and run the commands below, so there is one answer to "is the reader on" and not three.

From the command line

syn-speak on           # announce the focused window from now on
syn-speak off          # stop, and stop talking now
syn-speak toggle       # whichever of those applies

syn-speak window       # say the focused window once
syn-speak selection    # say the highlighted text once
syn-speak say "ready"  # say a line
syn-speak stop         # silence what is being said

syn-speak voice NAME   # syn-speak voices lists them
syn-speak rate 80..450 # words per minute (default 175)
syn-speak volume 0..100
syn-speak status       # what it would do, and what this box can do

syn-speak status is the one to reach for first — it reports the switch, the voice, the rate, the volume, which engine would actually speak, and the window it would announce right now:

on       yes
voice    en
rate     175
volume   100
engine   vibe
window   Inbox, thunderbird

engine is vibe, or the synthesiser name (espeak-ng), or none.

One voice on the machine

syn-speak does not own a speech engine. Where vibe is installed it speaks through vibe voice say — which is chibi's piper — so the screen reader and the assistant sound like the same desktop, and there is one place where "which engine does this box have" is worked out.

espeak-ng is what is left when vibe is absent, not a second opinion. It is an optdepends of synui; on an install that took no AI stack it is the only voice there is, so:

synpkg install espeak-ng

Without either, the switch turns on and the machine stays silent. syn-speak status reports engine none, and syn-speak say says which synthesiser it looked for, on stderr, and exits 3.

One utterance at a time. A new line stops the one in progress. Two announcements overlapping is not twice the information, it is none — and it is what makes the announcer usable at speed: moving quickly between windows leaves you hearing the one you landed on, not a queue of the ones you passed.

The announcer

syn-speak on does two things: it writes on=yes, and it enables syn-speak.service, a user unit that runs syn-speak watch — the loop that polls the focused window and speaks it when it changes. WantedBy=default.target, so the choice survives a login.

systemctl --user status syn-speak.service     # is the reader actually running

A poll, deliberately. synui has no "focus changed" event a client can subscribe to, and adding one to the compositor for a feature that ships off would be a protocol for nothing. Half a second is under the threshold at which a window switch feels unannounced, and one synctl call at that rate costs nothing measurable.

The loop announces on change. A window is spoken once when you land on it, not once per poll.

If the switch says On and nothing is announced, check systemctl --user status syn-speak.service first — or syn-settings ▸ Speech, which shows the same thing as a row. Between synui 527 and 563 that unit was not in the package at all: syn-speak on tried to enable it, the failure was swallowed on purpose (so that a machine without systemd is not a broken install), and all three surfaces reported On with nothing behind them. Fixed in synui 0.1.0-564.

Settings, and where they live

~/.config/synui/speak.state, key=value, the same shape every other synui state file uses — so it greps, and it can be fixed with an editor.

Key Default What it is
on no is the announcer switched on
voice en an espeak-ng voice name — syn-speak voices lists them
rate 175 words per minute, 80–450
volume 100 0–100
interval 0.5 seconds between focus checks; no command sets it, edit the file

voice falls back to lang if it is not set, so an existing lang= line keeps working.

What it needs

a voice vibe (piper), or espeak-ng
the focused window synctl, from the synui package
the selection wl-clipboardwl-paste --primary first, since on Wayland that is what "the text I just highlighted" means; the clipboard is what was deliberately copied
python3, to read synctl's JSON

Every one of them is checked by name rather than by running it and looking at the exit status: "not installed" and "ran and failed" want opposite answers.

Notes for a multi-monitor or nested desktop

The announcer asks synctl which window has focus, and synctl finds the compositor through WAYLAND_DISPLAY. A user unit does not have one — nothing in this session runs systemctl --user import-environment — so syn-speak resolves the name synui publishes at $XDG_RUNTIME_DIR/synui-display, the same file synui-foot.service and synui-media-inhibit read.

An explicit WAYLAND_DISPLAY always wins and is never overridden. That published file names the live desktop, so a nested or headless synui — a test rig, a screenshot rig — must not have its announcer read the real session's windows out loud.

See also

  • Keybindings — the three keys, in the System table
  • Settings — the Speech pane
  • Vibe — the assistant: vibe voice, dictation, and the wake word
  • Chibi — where piper and faster-whisper come from

Clone this wiki locally