How to Define Global Keyboard Shortcuts in OpenSuperWhisper
Yes, OpenSuperWhisper supports global keyboard shortcuts through the KeyboardShortcuts Swift package, allowing you to define custom hotkeys for starting and stopping transcription, single modifier keys, or even mouse buttons.
OpenSuperWhisper by Starmel provides a flexible system for defining global keyboard shortcuts that trigger voice recording and transcription. The application leverages the third-party KeyboardShortcuts library to register system-wide hotkeys that work even when the app is not in focus. Whether you need a traditional key combination, a single modifier key, or a mouse button trigger, the architecture in OpenSuperWhisper/ShortcutManager.swift makes it straightforward to customize your transcription workflow.
Understanding the Shortcut Architecture
The global keyboard shortcut system in OpenSuperWhisper consists of three interconnected components that handle declaration, registration, and user customization.
KeyboardShortcuts.Name Extension
The foundation of the shortcut system lies in the KeyboardShortcuts.Name extension declared in OpenSuperWhisper/ShortcutManager.swift. This extension defines the identifiers that the app recognizes, each with an optional default key combination.
extension KeyboardShortcuts.Name {
static let toggleRecord = Self("toggleRecord",
default: .init(.backtick, modifiers: .option))
static let escape = Self("escape", default: .init(.escape))
}
The default toggleRecord shortcut uses Option + Backtick (`), but you can define additional identifiers with custom defaults or leave them unbound for user configuration.
ShortcutManager Registration
The ShortcutManager class handles the actual registration of global hotkeys and forwards events to the UI layer. In the setupKeyboardShortcuts() method, the manager binds key-down and key-up events to specific actions using the KeyboardShortcuts API.
private func setupKeyboardShortcuts() {
KeyboardShortcuts.onKeyDown(for: .toggleRecord) { [weak self] in
self?.handleKeyDown()
}
KeyboardShortcuts.onKeyUp(for: .toggleRecord) { [weak self] in
self?.handleKeyUp()
}
// Escape shortcut dismisses the indicator window
KeyboardShortcuts.onKeyUp(for: .escape) { [weak self] in
Task { @MainActor in
if self?.activeVm != nil {
IndicatorWindowManager.shared.stopForce()
self?.activeVm = nil
}
}
}
KeyboardShortcuts.disable(.escape) // Hide from UI, internal use only
}
When the user presses the registered hotkey, handleKeyDown() starts the recording process, while handleKeyUp() stops it and initiates transcription.
Settings Persistence and UI
User preferences for shortcuts are stored in AppPreferences and managed through the SettingsViewModel in OpenSuperWhisper/Settings.swift. The view model exposes properties like modifierOnlyHotkey and mouseButtonHotkey, and posts .hotkeySettingsChanged notifications when values change.
The Settings UI allows users to select between three trigger modes:
- Key Combination – Traditional hotkey using modifiers and letter keys
- Single Modifier Key – Uses
ModifierKeyMonitor.swiftto detect standalone Command, Option, or Control presses - Mouse Button – Uses
MouseButtonMonitor.swiftto detect middle or side mouse button clicks
Step-by-Step Guide to Adding Custom Shortcuts
Follow these steps to implement a new global keyboard shortcut in OpenSuperWhisper:
-
Declare the shortcut identifier by extending
KeyboardShortcuts.NameinOpenSuperWhisper/ShortcutManager.swiftwith a unique name and optional default key combination. -
Register event handlers in
ShortcutManager.setupKeyboardShortcuts()usingKeyboardShortcuts.onKeyDownandKeyboardShortcuts.onKeyUpto bind your shortcut to existing logic likehandleKeyDown(). -
Add UI controls in
OpenSuperWhisper/Settings.swiftby creating a picker or segmented control that updates the corresponding view model property. -
Persist the selection by storing the value in
AppPreferencesand posting a.hotkeySettingsChangednotification soShortcutManagercan reconfigure the active monitors.
Practical Code Examples
Example 1: Declaring a New Shortcut
Add a custom "Start/Stop" shortcut named customToggle with a default of Control + F13:
// In OpenSuperWhisper/ShortcutManager.swift
extension KeyboardShortcuts.Name {
static let customToggle = Self("customToggle",
default: .init(.f13, modifiers: .control))
}
Example 2: Registering Callbacks
Reuse the existing recording logic by registering your new shortcut alongside the defaults:
// In ShortcutManager.setupKeyboardShortcuts()
private func setupKeyboardShortcuts() {
// Existing toggleRecord handlers...
KeyboardShortcuts.onKeyDown(for: .customToggle) { [weak self] in
self?.handleKeyDown()
}
KeyboardShortcuts.onKeyUp(for: .customToggle) { [weak self] in
self?.handleKeyUp()
}
}
Example 3: Adding UI Controls
Expose the new shortcut in the settings interface using a picker:
// In OpenSuperWhisper/Settings.swift
Form {
Picker("Recording Shortcut", selection: $viewModel.selectedShortcut) {
Text("Option + Backtick").tag(KeyboardShortcuts.Name.toggleRecord)
Text("Control + F13").tag(KeyboardShortcuts.Name.customToggle)
}
.pickerStyle(.menu)
}
Example 4: Persisting User Selection
Store the selected shortcut in AppPreferences and notify the system:
// In SettingsViewModel
@Published var selectedShortcut: KeyboardShortcuts.Name {
didSet {
AppPreferences.shared.selectedShortcut = selectedShortcut.rawValue
NotificationCenter.default.post(name: .hotkeySettingsChanged, object: nil)
}
}
The ShortcutManager automatically picks up this change and reconfigures the active shortcuts via setupRecordingTrigger().
Summary
- OpenSuperWhisper uses the KeyboardShortcuts Swift package to manage system-wide hotkeys for transcription control.
- Define new shortcuts by extending
KeyboardShortcuts.NameinOpenSuperWhisper/ShortcutManager.swiftand registering handlers insetupKeyboardShortcuts(). - The app supports three trigger modes: traditional key combinations, single modifier keys via
ModifierKeyMonitor.swift, and mouse buttons viaMouseButtonMonitor.swift. - Persist user preferences in
AppPreferencesand broadcast changes via.hotkeySettingsChangedto trigger runtime updates without app restarts. - Default shortcuts can be disabled or hidden from the UI using
KeyboardShortcuts.disable()while remaining active internally.
Frequently Asked Questions
What is the default global keyboard shortcut for OpenSuperWhisper?
The default global shortcut is Option + Backtick (`), defined in OpenSuperWhisper/ShortcutManager.swift as the toggleRecord identifier. This toggles recording on and off system-wide, even when the application is not focused.
Can I use a mouse button instead of a keyboard shortcut?
Yes. OpenSuperWhisper supports mouse button triggers through MouseButtonMonitor.swift. Users can select this mode in the Settings UI, which stores the preference in SettingsViewModel.mouseButtonHotkey and activates the monitor via ShortcutManager.setupRecordingTrigger().
Where are custom shortcut preferences stored?
Custom shortcut configurations are persisted in AppPreferences.swift using standard UserDefaults. The SettingsViewModel reads these values on initialization and writes changes back when the user selects a new trigger mode or key combination.
How do I disable the default Option+Backtick shortcut?
The default shortcut is automatically disabled when you select an alternative trigger mode (single modifier or mouse button) in the Settings UI. Programmatically, you can call KeyboardShortcuts.disable(.toggleRecord) in ShortcutManager, though this is typically handled automatically by setupRecordingTrigger() when switching modes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →