How OpenSuperWhisper Implements Global Keyboard Shortcuts Using Modifier-Only Keys

OpenSuperWhisper uses a low-level CGEvent tap to monitor system-wide modifier key state changes, allowing users to trigger dictation with standalone modifier keys like Left Command or Right Option without combining them with other keys.

OpenSuperWhisper is an open-source macOS dictation application that enables hands-free voice input through global hotkeys. Unlike traditional keyboard shortcuts that require key combinations, the app supports global keyboard shortcuts using modifier-only keys—such as pressing Left Command or Right Option alone—to start and stop recording sessions. This implementation relies on Core Graphics event taps to capture system-wide modifier state changes, providing a seamless experience across all applications.

Architecture of the Modifier-Only Hotkey System

The implementation consists of three tightly-coupled components working together to intercept and process modifier key events at the system level.

ModifierKey Enum Definition

Located in OpenSuperWhisper/ModifierKeyMonitor.swift, the ModifierKey enum defines every supported modifier key. It maps each key to its raw key-code, the corresponding NSEvent flag, and a human-readable name. This abstraction allows the system to identify specific physical keys independently of their symbolic meanings.

ModifierKeyMonitor Event Tap

The ModifierKeyMonitor class creates a low-level CG event tap that listens for flagsChanged events from the system. When the selected modifier's flag changes, it fires onKeyDown and onKeyUp callbacks. The monitor runs at the session level (.cgSessionEventTap), ensuring it captures events globally regardless of which application is front-most, provided the user has granted Accessibility permissions.

ShortcutManager Orchestration

The ShortcutManager class in OpenSuperWhisper/ShortcutManager.swift decides which trigger mode to use. When a user selects a modifier-only hotkey in the preferences stored in OpenSuperWhisper/Settings.swift, the manager disables the standard KeyboardShortcuts registration and wires the monitor's callbacks to its own recording logic.

Implementation Flow in ShortcutManager

The setup process begins in ShortcutManager.setupRecordingTrigger(), which coordinates between user preferences and the low-level monitor.

When a modifier-only key is selected, the flow works as follows:

  1. The system reads the selected modifier from AppPreferences.shared.modifierOnlyHotkey
  2. Standard keyboard shortcuts are disabled via KeyboardShortcuts.disable(.toggleRecord) to prevent duplicate handling
  3. The monitor's callbacks are wired to handleKeyDown() and handleKeyUp() methods
  4. The monitor starts listening for the specific modifier key code
let modifierKey = ModifierKey(rawValue: AppPreferences.shared.modifierOnlyHotkey) ?? .none
if modifierKey != .none {
    // Disable the regular shortcut that KeyboardShortcuts registers
    KeyboardShortcuts.disable(.toggleRecord)

    // Forward low‑level modifier events to the recording logic
    ModifierKeyMonitor.shared.onKeyDown = { [weak self] in self?.handleKeyDown() }
    ModifierKeyMonitor.shared.onKeyUp   = { [weak self] in self?.handleKeyUp()   }

    // Begin listening for flagsChanged events for the selected key
    ModifierKeyMonitor.shared.start(modifierKey: modifierKey)
}

Low-Level Event Handling

The ModifierKeyMonitor processes raw Core Graphics events to detect modifier state changes.

Capturing Flags Changed Events

The handleFlagsChanged(event:) method in ModifierKeyMonitor.swift inspects each incoming CGEvent to determine if the selected modifier is pressed or released:

private func handleFlagsChanged(event: CGEvent) {
    let keyCode = UInt16(event.getIntegerValueField(.keyboardEventKeycode))
    guard keyCode == selectedModifierKey.keyCode else { return }

    let isPressed = event.flags.contains(selectedModifierKey.cgEventFlag)
    if isPressed && !isModifierPressed {
        isModifierPressed = true
        DispatchQueue.main.async { self.onKeyDown?() }
    } else if !isPressed && isModifierPressed {
        isModifierPressed = false
        DispatchQueue.main.async { self.onKeyUp?() }
    }
}

This approach distinguishes between different physical keys (e.g., Left vs. Right Command) by checking the specific key code rather than just the generic modifier mask.

Recording Logic Integration

When the monitor detects a modifier press, the ShortcutManager executes handleKeyDown() to initiate dictation.

Starting a Dictation Session

The handleKeyDown() method prepares the recording interface through IndicatorWindowManager and optionally supports "hold-to-record" mode:

private func handleKeyDown() {
    holdWorkItem?.cancel()
    holdMode = false

    Task { @MainActor in
        // Start a new dictation session
        let vm = IndicatorWindowManager.shared.prepare()
        vm.startRecording()
        self.activeVm = vm
    }

    // Optional “hold‑to‑record” arm
    if AppPreferences.shared.holdToRecord && activeVm == nil {
        let work = DispatchWorkItem { self.holdMode = true }
        holdWorkItem = work
        DispatchQueue.main.asyncAfter(deadline: .now() + holdThreshold, execute: work)
    }
}

The method cancels any pending hold work items, initializes the IndicatorWindowManager from OpenSuperWhisper/IndicatorWindowManager.swift, and begins recording immediately or after a threshold in hold mode.

Summary

  • OpenSuperWhisper implements global keyboard shortcuts using modifier-only keys through a Core Graphics event tap that monitors system-wide flagsChanged events.
  • The ModifierKeyMonitor class in ModifierKeyMonitor.swift handles low-level event capture, distinguishing between specific physical modifier keys using raw key codes.
  • ShortcutManager in ShortcutManager.swift coordinates between user preferences and the monitor, disabling standard shortcuts when modifier-only mode is active to prevent conflicts.
  • The event tap runs at the session level (.cgSessionEventTap), requiring Accessibility permissions but providing truly global hotkey functionality across all macOS applications.
  • Recording logic integrates with IndicatorWindowManager to provide visual feedback when dictation starts via modifier key presses.

Frequently Asked Questions

Why does OpenSuperWhisper require Accessibility permissions for modifier-only shortcuts?

macOS restricts low-level event monitoring to applications with Accessibility permissions. Because the ModifierKeyMonitor creates a .cgSessionEventTap to listen for flagsChanged events system-wide, the app must be granted Accessibility access in System Settings to intercept modifier key states regardless of which application is currently active.

How does the app distinguish between Left and Right modifier keys?

The implementation uses raw key codes defined in the ModifierKey enum rather than generic modifier masks. Each physical key (Left Command, Right Command, Left Option, Right Option) has a unique key code. The handleFlagsChanged(event:) method compares the event's key code against the selected modifier's key code, ensuring specific physical keys trigger the action.

What happens if both a regular shortcut and a modifier-only hotkey are configured?

The ShortcutManager prevents conflicts by disabling the standard KeyboardShortcuts registration when a modifier-only hotkey is active. In setupRecordingTrigger(), the code calls KeyboardShortcuts.disable(.toggleRecord) before starting the ModifierKeyMonitor, ensuring only one trigger mechanism handles the input at a time.

Can the modifier-only hotkey work while other applications are fullscreen?

Yes. Because the ModifierKeyMonitor uses a session-level event tap (.cgSessionEventTap), it receives events at the system level rather than the application level. This allows the modifier-only global keyboard shortcut to function even when the user is working in fullscreen applications or apps that normally intercept standard hotkeys.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →