# How to Define Global Keyboard Shortcuts in OpenSuperWhisper

> Define global keyboard shortcuts for OpenSuperWhisper using the KeyboardShortcuts Swift package. Customize hotkeys for transcription, modifiers, or mouse buttons easily.

- Repository: [Starmel/OpenSuperWhisper](https://github.com/Starmel/OpenSuperWhisper)
- Tags: how-to-guide
- Published: 2026-07-05

---

**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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/OpenSuperWhisper/ShortcutManager.swift). This extension defines the identifiers that the app recognizes, each with an optional default key combination.

```swift
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.

```swift
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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/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:

1. **Key Combination** – Traditional hotkey using modifiers and letter keys
2. **Single Modifier Key** – Uses [`ModifierKeyMonitor.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ModifierKeyMonitor.swift) to detect standalone Command, Option, or Control presses
3. **Mouse Button** – Uses [`MouseButtonMonitor.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/MouseButtonMonitor.swift) to 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:

1. **Declare the shortcut identifier** by extending `KeyboardShortcuts.Name` in [`OpenSuperWhisper/ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/OpenSuperWhisper/ShortcutManager.swift) with a unique name and optional default key combination.

2. **Register event handlers** in `ShortcutManager.setupKeyboardShortcuts()` using `KeyboardShortcuts.onKeyDown` and `KeyboardShortcuts.onKeyUp` to bind your shortcut to existing logic like `handleKeyDown()`.

3. **Add UI controls** in [`OpenSuperWhisper/Settings.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/OpenSuperWhisper/Settings.swift) by creating a picker or segmented control that updates the corresponding view model property.

4. **Persist the selection** by storing the value in `AppPreferences` and posting a `.hotkeySettingsChanged` notification so `ShortcutManager` can 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:

```swift
// 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:

```swift
// 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:

```swift
// 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:

```swift
// 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.Name` in [`OpenSuperWhisper/ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/OpenSuperWhisper/ShortcutManager.swift) and registering handlers in `setupKeyboardShortcuts()`.
- The app supports three trigger modes: traditional key combinations, single modifier keys via [`ModifierKeyMonitor.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ModifierKeyMonitor.swift), and mouse buttons via [`MouseButtonMonitor.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/MouseButtonMonitor.swift).
- Persist user preferences in `AppPreferences` and broadcast changes via `.hotkeySettingsChanged` to 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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/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`](https://github.com/Starmel/OpenSuperWhisper/blob/main/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.