This document outlines the technical implementation and lessons learned while building the global shortcut system for Voxa, specifically focusing on the native macOS CGEventTap used to handle specialized hardware keys and bypass system limitations.
Voxa requires high-performance, low-latency global shortcut handling. Initially, we relied on high-level Rust crates and the Tauri global_shortcut plugin. However, we encountered three major issues:
- System Conflicts: Hardware keys (like the MacBook "Dictation" or "Microphone" keys) often trigger built-in macOS services (e.g., system dictation), causing double-transcription or UI overlaps.
- Key Swallowing (Collisions): Registering "bare" keys (like
SpaceorBackspace) without modifiers through high-level APIs often "swallows" the key globally, breaking normal typing in all applications. - API Ambiguity: High-level Carbon/Cocoa traits in Rust (like
TCFTypevsForeignType) can lead to compilation paradoxes when mixing different crates (core-foundation,core-graphics,cocoa).
We implemented a Hybrid Shortcut System:
- Tauri Global Shortcut Plugin: Used for standard user-configurable shortcuts that must have modifiers (Cmd, Alt, Shift).
- Native
CGEventTap(Pure FFI): Used for "reserved" shortcuts (Paste,Cancel,Hands-Free) and hardware keys. - Shortcut Synchronization: A globally shared
OnceLock<ShortcutConfig>inlib.rsensures that both the native tap and the backend logic stay in sync.
To intercept specialized hardware keys (e.g., the MacBook Pro Touch Bar Mic key or the F5 Dictation key), the CGEventTap must be created with the NSSystemDefined event mask:
// Mask for NSSystemDefined (14) to capture hardware special keys
let event_mask = (1 << 14) | (1 << 10) | (1 << 11); // NSSystemDefined + KeyDown + KeyUpWithout this mask, keycodes like 176 and 179 will be ignored by the tap, and the system will proceed to trigger its default behavior.
To prevent macOS from activating its built-in dictation engine when using the hardware key for Voxa, we must:
- Capture both
KeyDownandKeyUpfor the specific keycode. - Return
None(null) from theCGEventTapProxycallback.
This effectively "consumes" the event before it reaches the system-level HID manager.
When high-level crate traits conflict, the most robust solution is raw FFI. In src-tauri/src/lib.rs, we defined raw extern "C" bindings for:
CGEventTapCreateCFMachPortCreateRunLoopSourceCFRunLoopAddSource
This bypasses the TCFType dependency issues and provides a stable, persistent event tap that survives application lifecycle changes.
To avoid breaking the Escape key's normal functionality (e.g., closing dialogs in other apps), the native tap implements Context-Aware Guards:
if keycode == ESCAPE {
// Only swallow Escape if we are actually recording
if is_recording { return None; }
}To prevent "accidental" global keyboard locks, we implemented a database migration that:
- Scans for shortcuts missing modifiers (bare keys).
- Resets them to safe defaults.
- Ensures
shortcut_hands_freeis always mapped to"F5"(which represents the unified hardware key in our logic).
- Hardware Key Expansion: When adding support for new specialized keys (e.g., the "Globe" key or Media keys), consult the
macos_keycode_to_nametable and ensure theNSSystemDefinedmask remains active. - Permission Handling: Always verify
AXIsProcessTrusted()before initializing the tap. macOS will silently ignore tap creation if Accessibility permissions are missing.
Senior Architect Note: Concepts > Code. Understanding the low-level HID event flow is more important than knowing specific crate APIs. Always aim for a design that respects the user's system state.