Global key listener
A native Rust process captures keystrokes system-wide, matches them against registered shortcuts, and can block matched keys from reaching other apps.
Language
Rust · rdev grab
Transport
JSON lines over stdio
Heartbeat
Every 10 seconds
Why a native process
Electron's globalShortcutcan't express hold-to-talk or reliably block a key from the focused app. VoiceFlow instead spawns a small Rust binary that uses rdev's grab API to intercept the macOS event stream, giving it press/release granularity and the ability to swallow matched keys.
App Nap prevention
The stdio protocol
The main process's shortcut-manager talks to the binary with newline-delimited JSON. It writes a register_hotkeys command listing the key combinations to watch; the binary streams back key events and periodic heartbeats.
{ "command": "register_hotkeys",
"hotkeys": [ { "keys": ["ShiftLeft", "Space"] },
{ "keys": ["BackQuote"] } ] }{ "type": "keydown", "key": "Space", "timestamp": "..." }
{ "type": "keyup", "key": "Space", "timestamp": "..." }
{ "type": "heartbeat_ping", "id": "7", "timestamp": "..." }Matching & blocking
The binary tracks the set of currently-pressed keys. On each press it checks whether the pressed set exactly equals any registered combo; if so, it returns None from the grab callback, which blocks the key from reaching other apps. The main process independently tracks pressed tokens to decide when to start and stop recording.
- Shortcuts are expanded into raw key variants so left/right modifiers both match.
- A special case blocks the Fn key (reported as Unknown(179)) when an Fn shortcut is registered.
- Matching requires an exact set — extra held keys mean no match, keeping toggle and hold from overlapping.
Resilience
A key listener that dies or gets stuck would silently break every shortcut, so the manager supervises it aggressively.
Heartbeat watchdog
The binary emits a heartbeat every 10 s. If none arrives within 15 s, the manager restarts the process.
Stuck-key recovery
Keys held longer than 5 s are cleared (unless part of an active hold recording), so a missed key-up event can't jam a shortcut.
Auto-restart
If the process exits unexpectedly, it's respawned after ~1 s and the shortcuts are re-registered.
Editing pause
While you record a new shortcut in Settings, the listener is disabled so your keypresses don't trigger recording.
Where the binary lives
In development the manager runs the Cargo build output for your architecture (e.g. aarch64-apple-darwin). In a packaged build it's bundled as an extra resource under resources/binaries. See Build & releasefor how it's compiled and packaged.