# How to Handle Shortcut Conflicts in OpenSuperWhisper: Priority System and Resolution

> OpenSuperWhisper handles shortcut conflicts via a priority system. Learn how mouse hotkeys override modifier-only keys and regular shortcuts for seamless operation.

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

---

**OpenSuperWhisper resolves shortcut conflicts through a strict priority hierarchy where mouse-button hotkeys take precedence over modifier-only keys, which in turn override regular keyboard shortcuts, enforced by mutual exclusion in [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift).**

OpenSuperWhisper, the open-source macOS dictation tool by Starmel, allows users to trigger recordings through three distinct input mechanisms. When multiple hotkey types are configured, the application must prevent simultaneous activation to avoid duplicate recordings or conflicting states. The conflict resolution system is centralized in [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift), which implements a priority-based mutex ensuring only one recording trigger remains active at any time.

## Understanding the Three Hotkey Modes

OpenSuperWhisper supports three activation methods, each managed by separate monitoring components. The application handles shortcut conflicts by strictly prioritizing these modes to prevent overlapping triggers.

### Regular Keyboard Shortcuts

The default activation method uses the `KeyboardShortcuts` library with the identifier `KeyboardShortcuts.Name.toggleRecord`. Typically bound to **⌥ + \\**, this mode relies on standard key press and release combinations. When either a modifier-only or mouse-button hotkey is active, this regular shortcut is automatically disabled to prevent conflicts.

### Modifier-Only Hotkeys

Users can configure **modifier-only hotkeys** (such as Left ⌘ or Right ⌥) through the custom `ModifierKeyMonitor` class. These triggers activate when a specific modifier key is pressed and released without accompanying character keys. This mode takes precedence over regular keyboard shortcuts but yields to mouse-button hotkeys when both are configured.

### Mouse-Button Hotkeys

**Mouse-button hotkeys** provide the highest priority activation method, monitored by `MouseButtonMonitor`. When configured (for example, Right-click or Middle-click), this mode automatically disables both the regular keyboard shortcut and any modifier-only hotkeys. This ensures that deliberate mouse-based triggering isn't interrupted by accidental keyboard modifier presses.

## Conflict Resolution Logic in ShortcutManager.swift

The core conflict resolution implementation resides in [`OpenSuperWhisper/ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/OpenSuperWhisper/ShortcutManager.swift). The manager evaluates user preferences and enforces mutual exclusion whenever hotkey settings change.

### Preference Lookup and Monitoring

The manager first reads the current configuration from `AppPreferences` to determine which modes should be active. According to lines 75-77 of [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift), the initialization checks both modifier and mouse button settings:

```swift
let modifierKey = ModifierKey(rawValue: AppPreferences.shared.modifierOnlyHotkey) ?? .none
let mouseButton = MouseButton(rawValue: AppPreferences.shared.mouseButtonHotkey) ?? .none

```

The `setupRecordingTrigger()` method (lines 84-119) then evaluates these values to determine which monitoring system to activate.

### Mutual Exclusion Enforcement

Before enabling any hotkey mode, the manager explicitly stops all other monitors to guarantee single-mode operation. As implemented in lines 78-83, the system tears down existing monitors before initializing new ones:

```swift
ModifierKeyMonitor.shared.stop()
MouseButtonMonitor.shared.stop()

```

This teardown prevents race conditions where a modifier key release might trigger a recording while a mouse button hotkey is being configured.

### Priority Order Handling

The decision hierarchy in `setupRecordingTrigger()` follows strict precedence rules:

1. **Mouse-button hotkey** – If `mouseButton != .none`, the manager installs the mouse monitor, disables the regular shortcut, and logs the configuration change.
2. **Modifier-only hotkey** – If no mouse button is selected but a modifier key is configured, the manager starts `ModifierKeyMonitor` and disables the regular shortcut.
3. **Regular shortcut** – Only when both specialized modes are set to "none" does the `KeyboardShortcuts` library handle the default toggle.

Both `handleKeyDown()` and `handleKeyUp()` methods maintain consistent recording logic regardless of which trigger system is active, ensuring uniform behavior across all input modes.

### Dynamic Reconfiguration

The system supports live switching without application restarts. When users modify hotkey preferences in the Settings UI, `ShortcutManager` observes the `.hotkeySettingsChanged` notification (registered in lines 30-35) and re-runs `setupRecordingTrigger()` to re-evaluate the priority hierarchy immediately.

## Configuring Hotkeys Without Conflicts

You can programmatically configure hotkey preferences while respecting the conflict resolution system. Changes automatically trigger the priority evaluation in `ShortcutManager`.

### Enabling Mouse-Button Hotkeys

To set a mouse button as the primary trigger (which automatically disables other modes):

```swift
// In Settings.swift – when the user selects a mouse button
AppPreferences.shared.mouseButtonHotkey = MouseButton.right.rawValue   // “right” is defined in MouseButton enum
// ShortcutManager will automatically re‑configure on the next notification

```

### Setting Modifier-Only Keys

To configure a modifier-only hotkey (which disables the regular shortcut but defers to mouse buttons):

```swift
// In Settings.swift – user selects Left ⌘ as the hot‑key
AppPreferences.shared.modifierOnlyHotkey = ModifierKey.leftCommand.rawValue
// ShortcutManager disables the regular shortcut and starts ModifierKeyMonitor

```

### Resetting to Default Shortcuts

To restore the standard keyboard shortcut and disable specialized modes:

```swift
AppPreferences.shared.mouseButtonHotkey = "none"
AppPreferences.shared.modifierOnlyHotkey = "none"
// ShortcutManager falls back to KeyboardShortcuts.toggleRecord

```

### Observing Configuration Changes

Internally, components listen for preference changes to update UI state accordingly:

```swift
NotificationCenter.default.addObserver(
    self,
    selector: #selector(hotkeySettingsChanged),
    name: .hotkeySettingsChanged,
    object: nil)

```

This observer pattern ensures that [`ContentView.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ContentView.swift) and other UI components reflect the current active trigger mode without requiring manual refresh.

## Summary

- **Priority hierarchy**: Mouse-button hotkeys take precedence over modifier-only keys, which override regular keyboard shortcuts.
- **Mutual exclusion**: [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift) stops all monitors before activating a new mode to prevent double-triggering.
- **Dynamic updates**: The system re-evaluates conflicts immediately when preferences change via `.hotkeySettingsChanged` notifications.
- **Consistent handling**: `handleKeyDown()` and `handleKeyUp()` provide uniform recording logic regardless of the active input method.
- **Configuration storage**: [`AppPreferences.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/AppPreferences.swift) persists settings for `modifierOnlyHotkey` and `mouseButtonHotkey`, which `ShortcutManager` reads to resolve conflicts.

## Frequently Asked Questions

### What happens if I configure both a mouse button and a modifier key shortcut?

The mouse-button hotkey takes absolute precedence. When `AppPreferences.shared.mouseButtonHotkey` is set to any value other than "none", `ShortcutManager` automatically disables both the regular keyboard shortcut and the modifier-only monitor. This prevents conflicts where pressing a mouse button might coincide with modifier key presses.

### Why does my regular keyboard shortcut stop working when I enable a modifier-only hotkey?

This is the intended behavior according to the conflict resolution logic in [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift). When a modifier-only hotkey is active, the system disables the standard `KeyboardShortcuts.toggleRecord` to prevent both triggers from firing simultaneously. The modifier-only key becomes the exclusive recording trigger until you either disable it or configure a mouse-button hotkey (which would then take precedence).

### How do I switch back to the default keyboard shortcut after using specialized hotkeys?

Set both preference values to "none" to restore the default behavior:

```swift
AppPreferences.shared.mouseButtonHotkey = "none"
AppPreferences.shared.modifierOnlyHotkey = "none"

```

Once both are reset to "none", `ShortcutManager` re-enables the regular `KeyboardShortcuts` library handler for toggle recording.

### Can I use multiple hotkeys simultaneously in OpenSuperWhisper?

No, the architecture specifically prevents simultaneous activation. The `setupRecordingTrigger()` method in [`ShortcutManager.swift`](https://github.com/Starmel/OpenSuperWhisper/blob/main/ShortcutManager.swift) enforces mutual exclusion by stopping all monitors before starting a new one. This design prevents race conditions and ensures that a single physical action cannot trigger multiple recording sessions.