Triggers
Use app-owned X11 shortcuts or external Wayland trigger commands.
Push-to-talk needs explicit start and stop edges. QuillSpeak can own those edges on X11. On Wayland, an external hotkey tool calls the running app.
Trigger Model
A shortcut trigger starts recording for one shortcut id and stops that same shortcut. Hotkey backends and command-mode triggers do not use a blind toggle because push-to-talk needs separate key down and key up behavior.
| Session | Recommended trigger |
|---|---|
| Pure X11 | Use QuillSpeak keyboard shortcuts with hotkey_backend = "auto" or "x11". |
| Wayland | Use compositor keybindings or an external tool such as swhkd to call quillspeak trigger. |
| Mixed Wayland/X11 | Treated like Wayland for shortcut capture. Use external triggers or Linux signals. |
| No display backend | Keyboard capture is disabled. Tray actions and Linux signals may still be available. |
X11 Keyboard Shortcuts
On pure X11 sessions, QuillSpeak can capture global keyboard
shortcuts directly through passive X11 grabs. The default keyboard
shortcut is Ctrl+Alt+Space.
[general]
hotkey_backend = "auto"
[[shortcuts]]
id = "default"
trigger = { type = "keyboard", accelerator = "Ctrl+Alt+Space" }
Key down starts recording for that shortcut. Key up stops the same shortcut and sends the captured audio to transcription. If the selected accelerator cannot be parsed or conflicts with another enabled shortcut, the config is rejected.
X11 Availability
QuillSpeak considers keyboard capture available only when
DISPLAY is present and WAYLAND_DISPLAY
is absent. This avoids pretending that X11 grabs are reliable in
mixed Wayland sessions.
Wayland Trigger Commands
Wayland does not let a normal desktop app capture global keyboard shortcuts directly. QuillSpeak therefore exposes a command mode on the same binary. The command sends one line to the running app through its user socket.
quillspeak trigger Default start
quillspeak trigger Default stop
quillspeak trigger Default toggle
- Socket
$XDG_RUNTIME_DIR/quillspeak/command.sock- Shortcut selector
- Exact shortcut id first, then exact unique display name.
- Rejected selectors
- Missing, disabled, or ambiguous shortcut names.
- Rejected no-ops
- Start while busy, stop with no active recording, or toggle while processing.
Command failures exit with a non-zero status. This is useful for external hotkey tools because a failed key event does not silently pretend that recording state changed.
swhkd Example
swhkd is a practical Wayland-friendly hotkey daemon.
It can run a command on key press and a second command on key
release by using @ in the release binding.
Example ~/.config/swhkd/swhkdrc:
ctrl + space
/usr/bin/quillspeak trigger Default start
ctrl + @space
/usr/bin/quillspeak trigger Default stop
ctrl + shift + space
pkill -USR1 -x quillspeak
ctrl + shift + @space
pkill -USR1 -x quillspeak
The first pair uses command-mode start and stop edges for the
Default shortcut. The second pair demonstrates a
same-signal fallback profile where pressing and releasing the key
both send SIGUSR1.
sudo systemctl restart swhkd.service
systemctl --user restart swhks.service
Service names can vary by distribution. Restart only the services
your local swhkd package installed.
Linux Signals
Linux signal triggers are a lower-level fallback. Configure a
shortcut profile as linux_signal, then send signals
to the running quillspeak process.
pkill -USR1 -x quillspeak
pkill -USR2 -x quillspeak
| Signal | Accepted name |
|---|---|
| User-defined signal 1 | SIGUSR1 |
| User-defined signal 2 | SIGUSR2 |
| Alarm signal | SIGALRM |
| Window size change signal | SIGWINCH |
Aliases, numeric values, reserved process-control signals, and
custom names are not supported. SIGUSR1 and
SIGUSR2 are always registered as guard signals; if
they do not match an enabled shortcut, QuillSpeak logs the signal
at debug level and keeps running.
Same-Signal Toggle
If a shortcut uses the same start and stop signal, the first matching signal starts recording when idle. The next matching signal stops that same active shortcut. Signals for inactive shortcuts or processing state are ignored.
Manual Testing
Start the app in one terminal so logs stay visible:
QUILLSPEAK_DEV_LOG=1 quillspeak
Then trigger from another terminal:
quillspeak trigger Default start
quillspeak trigger Default stop
pkill -USR1 -x quillspeak
pkill -USR2 -x quillspeak
For a same-signal shortcut, send the same signal twice. The first signal should start recording. The second should stop the active recording without exiting the app.