All tests run on an 8-year-old MacBook Air.
A global shortcut fires even when your app isn't focused. For a menubar app, this is essential — Cmd+Shift+H should open the panel regardless of what the user is doing.
Tauri v2 has a global shortcut plugin. It works, but there are a few things worth knowing before you reach for it.
Basic setup
# Cargo.toml
[dependencies]
tauri-plugin-global-shortcut = "2"
use tauri_plugin_global_shortcut::{GlobalShortcutExt, Shortcut};
fn main() {
tauri::Builder::default()
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
.setup(|app| {
let shortcut: Shortcut = "CmdOrCtrl+Shift+H".parse()?;
app.global_shortcut().on_shortcut(shortcut, |app, _shortcut, _event| {
if let Some(window) = app.get_webview_window("main") {
if window.is_visible().unwrap_or(false) {
window.hide().unwrap();
} else {
window.show().unwrap();
window.set_focus().unwrap();
}
}
})?;
Ok(())
})
.run(tauri::generate_context!())
.unwrap();
}
The conflict problem
Global shortcuts are system-wide. If another app has already registered Cmd+Shift+H, your registration silently fails — no error, no fallback.
Always handle registration failure gracefully:
match app.global_shortcut().register(shortcut) {
Ok(_) => println!("shortcut registered"),
Err(e) => {
// Notify user the shortcut is taken
eprintln!("shortcut registration failed: {}", e);
// Fall back to a less likely-to-conflict alternative
}
}
Let users configure their own shortcut. Don't hardcode one and assume it's available.
Unregistering on quit
Global shortcuts persist until explicitly unregistered or the process exits. Tauri handles cleanup on normal exit, but register an explicit cleanup for safety:
app.on_window_event(|window, event| {
if let tauri::WindowEvent::Destroyed = event {
window.app_handle()
.global_shortcut()
.unregister_all()
.ok();
}
});
The wrong way: JavaScript keyboard listeners
window.addEventListener('keydown', ...) in your frontend only fires when your window is focused. For a menubar app that hides itself, this is useless for the primary use case.
Always use the native global shortcut plugin for shortcuts that need to work system-wide. Use JS keyboard listeners only for shortcuts that operate within your focused window.
One more thing: accessibility permissions
On macOS, apps that register global shortcuts may trigger an accessibility permission prompt. Tauri's plugin handles this, but users on locked-down machines (corporate MDM) may not be able to grant it.
Design your app to work without the shortcut — it's a convenience, not a requirement.
Hiyoko PDF Vault → https://hiyokoko.gumroad.com/l/HiyokoPDFVault
X → @hiyoyok
Top comments (0)