How the SuperKey Service in vorssaint-utils Uses Keyboard Event Taps and hidutil Mapping

The SuperKey service in vorssaint-utils combines real-time CGEvent taps with low-level hidutil key remapping to transform keys like Caps Lock into customizable modifiers that can trigger solo actions or add modifier flags to subsequent keystrokes.

The vorssaint-utils repository implements a sophisticated SuperKey feature through a two-part architecture: SuperKeyService manages the system-level event interception while SuperKeySupport handles the pure logic for state management and hidutil mapping. This design allows macOS users to repurpose underutilized keys into powerful modifier triggers that persist across system events and device changes.

Core Architecture: Service and Support Layers

The implementation splits responsibilities between two primary Swift files in Sources/Vorssaint/Services/SuperKey/:

  • SuperKeyService.swift – Creates and manages the background thread running the CGEvent tap, handles raw CGEvent objects, and coordinates the lifecycle of the hidutil mapping.
  • SuperKeySupport.swift – Contains the state machine logic, builds the JSON mapping tables for hidutil, parses mapping reports, and classifies events into abstract types (trigger, source key, or other).

Creating the CGEvent Tap

When enabled via syncWithPreferences, the service launches a dedicated background thread named "Vorssaint Super Key" to avoid blocking the main thread. The runEventTap method installs two separate taps using CGEvent.tapCreate:

let tap = CGEvent.tapCreate(
    tap: .cgSessionEventTap,
    place: .headInsertEventTap,
    options: .defaultTap,
    eventsOfInterest: mask,
    callback: { _, type, event, userInfo in 
        guard let userInfo else { return Unmanaged.passUnretained(event) }
        let service = Unmanaged<SuperKeyService>.fromOpaque(userInfo)
            .takeUnretainedValue()
        return service.handle(type: type, event: event)
    },
    userInfo: Unmanaged.passUnretained(self).toOpaque())

The .cgSessionEventTap placement ensures the tap receives keyboard events at the session level, while .headInsertEventTap places it at the front of the event stream. Both keyboard and mouse events are captured—mouse taps use .cghidEventTap so that modifier holds apply to drag operations. The callback forwards every event to SuperKeyService.handle for processing.

Event Classification and State Machine Decisions

Inside handle, raw events are normalized through SuperKeySupport.classify, which converts CGEventType and keycodes into a domain-specific Event enum:

let event0 = SuperKeySupport.classify(type: type, source: source, event: event)

Classification rules include:

  • .triggerDown / .triggerUp – Detected when the keycode matches the configured trigger (remapped to F18 by hidutil).
  • .sourceKey – Flag-change events for the physical source key (e.g., Caps Lock) before remapping takes effect.
  • .otherKey – All remaining keyboard keys and mouse button presses.

The classified event feeds into a thread-safe state machine protected by stateLock:

let decision = stateLock.withLock { state.decide(event0) }

The SuperKeySupport.State.decide method returns a Decision enum with the following outcomes:

  • .swallow – Drops the event entirely, preventing the system from seeing the source key press.
  • .addModifiers – Injects user-configured modifier flags into the event before passing it along.
  • .soloTap or .soloHold – Triggers the configured solo action when the SuperKey is released without combination keystrokes.
  • .interceptAndRemap – Holds the event temporarily when the raw source key appears before the hidutil mapping is active.

Modifier Injection Logic

When the state machine returns .addModifiers, the service fetches the configured mask from eventModifiers.cgFlags and unions it with the existing event flags:

event.flags = event.flags.union(modifierFlags)
return Unmanaged.passUnretained(event)

This union operation ensures that holding the SuperKey adds custom modifiers—such as Control, Option, or Command—to every subsequent keystroke without interfering with the base key functionality.

Managing the hidutil Mapping

The service uses macOS's /usr/bin/hidutil utility to remap the physical source key (e.g., Caps Lock at 0x700000039) to a harmless placeholder (F18 at 0x70000006D). This remapping allows the system to treat the SuperKey as a normal key that can be held down without triggering system behaviors like Caps Lock toggling.

Building and Applying the Mapping

The SuperKeySupport.mappings function generates a JSON structure:

{"UserKeyMapping":[{"HIDKeyboardModifierMappingSrc":0x700000039,"HIDKeyboardModifierMappingDst":0x70000006D}]}

The applyMapping method executes this via Shell.run:

let write = Shell.run(
    hidutilPath,
    ["property", "--matching", keyboardMatch,
     "--set", SuperKeySupport.mappingArgument(wanted)])

After writing, the service verifies the mapping by reading it back with --get and parsing the output through SuperKeySupport.parseMappings to ensure mappingReportConfirms matches the expected configuration.

Mapping Lifecycle and Repair

A SuperKeyMappingGuard maintains a persistent marker in DefaultsKey.superKeyMappingApplied to ensure the mapping is cleared on application quit or crash. The repairMappingIfStale method periodically checks mapping consistency—triggered on keyboard plug-in events or system wake notifications—removing any tables that belong to other applications to prevent conflicts.

Handling Edge Cases

The service implements several defensive mechanisms to maintain reliability:

  • Accessibility Permission Checks – syncWithPreferences validates AXIsProcessTrusted() before starting the tap and clears any leftover hidutil mappings if permissions are revoked.
  • Tap Recovery – The handle method reacts to .tapDisabledByTimeout or .tapDisabledByUserInput by immediately re-enabling taps via CGEvent.tapEnable if the application remains active.
  • Lost Key-Up Detection – A heldKeyWatchdog monitors for stuck keys. If a key-up event is missed (common during rapid typing or sleep states), the watchdog queries the physical key state using CGEventSource.keyState(.hidSystemState, key:) and calls forgetHeldKey to reset the state machine.
  • Dynamic Device Support – When new keyboards are connected, the next source key press triggers repairMappingIfStale, rebuilding the mapping for the newly attached HID device.

Solo Actions

When the state machine determines the user tapped or held the SuperKey in isolation (.soloTap or .soloHold), performSoloAction executes one of the following on the main thread:

  • Escape – Posts a synthetic Escape keystroke using CGEvent.post.
  • CapsLock – Toggles the system Caps Lock state via IOHIDSetModifierLockState.
  • InputSource – Cycles to the next enabled input source using TISSelectInputSource.

Summary

  • SuperKeyService in Sources/Vorssaint/Services/SuperKey/SuperKeyService.swift creates a background thread to run CGEvent taps that intercept all keyboard and mouse events at the session level.
  • SuperKeySupport in Sources/Vorssaint/Services/SuperKey/SuperKeySupport.swift provides the classification logic, hidutil JSON generation, and state machine that decides whether to swallow, modify, or redirect events.
  • The service uses /usr/bin/hidutil with --set and --get operations to remap source keys to F18, enabling the key to function as a holdable modifier rather than a toggle.
  • Modifier injection occurs in real-time by unioning eventModifiers.cgFlags with the event's existing flags before returning the modified event to the system.
  • Robust edge-case handling includes accessibility permission validation, tap recovery, physical key state watchdogs, and automatic mapping repair on device changes or system wake.

Frequently Asked Questions

How does the SuperKey service prevent the original Caps Lock behavior from activating?

The service uses /usr/bin/hidutil to remap the physical Caps Lock key to the F18 keycode at the HID driver level. This remapping occurs before macOS processes the key as a modifier toggle. Additionally, the CGEvent tap swallows the initial key-down event using the .swallow decision until the mapping is confirmed active, ensuring the system never sees a raw Caps Lock press.

What happens if I disconnect and reconnect my keyboard while the SuperKey is active?

The service detects device changes through the event stream and triggers repairMappingIfStale. This method queries the current hidutil mapping via --get, compares it against the expected configuration, and re-applies the remapping if inconsistencies are found. This ensures the SuperKey continues functioning across keyboard hot-swaps.

Why does the SuperKey service require Accessibility permissions?

Accessibility permissions grant the application the kAXTrustedCheckOptionPrompt entitlement required to create CGEvent taps with .cgSessionEventTap. Without this trust status, CGEvent.tapCreate returns nil and the service cannot intercept or modify keyboard events. The syncWithPreferences method explicitly checks AXIsProcessTrusted() and refuses to start the tap until the user grants permission in System Settings.

Can the SuperKey add multiple modifiers simultaneously?

Yes. The eventModifiers configuration stores a bitmask of desired modifiers (Command, Option, Control, Shift). When the state machine returns .addModifiers, the service performs a union operation between the existing event flags and the configured modifier mask using event.flags.union(modifierFlags). This allows the SuperKey to act as a hyper key, adding any combination of modifiers to subsequent keystrokes.

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 →