Hold-to-talk dictation on sway and WoW chat
In World of Warcraft I chat while my hands are on the movement keys, but I felt like it sometimes interrupts the flow of what I’m doing too much. So I built hold-to-talk dictation: hold a key, speak, release, and the text lands in whatever has focus. It is one Python script, dictate, and a local speech server.
The key
My Voyager (a ZSA keyboard) sends F13 from a combo. That’s keycode XF86Tools in xkb, bound in sway:
bindsym XF86Tools exec ~/.local/bin/dictate start
bindsym --release XF86Tools exec ~/.local/bin/dictate stop
start runs parec into a wav. stop sends SIGINT to that earlier process, and posts the wav to the ASR server (whisper.cpp) so it gets transcribed. The server uses whisper-server’s /inference contract.
Dictating to World of Warcraft
I picked wtype, designed for Wayland, but I couldn’t get it to interface with WoW. So I switched to ydotool, which does work.
In WoW, typing without an input field could do all sorts of things in the game: if the input field is not open, every inputted character can hit a keybind. So when the focused window is wowb.exe, dictate puts the text on the clipboard, has ydotool press Enter, Ctrl+V, Enter, and restores the old clipboard.
Tweaking it for game-specific uses
A sentence that starts with a channel word (party, say, yell, etc.) becomes a chat command, e.g.:
- “party, hello” is
/p Hello - “guild anyone up?” is
/g Anyone up? - “emote dance” is
/dance - “slash reload” is
/reload
I added a mapping table which is a dict of the recurring mishearings, e.g.: killed, gilt and guilt all mean guild, incense means instance, remote and mode mean emote.