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

> Discover how vorssaint-utils' SuperKey service uses keyboard event taps and hidutil mapping to remap Caps Lock into a powerful modifier for custom actions and key combinations.

- Repository: [vorssaint/vorssaint-utils](https://github.com/vorssaint/vorssaint-utils)
- Tags: internals
- Published: 2026-09-11

---

**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`](https://github.com/vorssaint/vorssaint-utils/blob/main/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`](https://github.com/vorssaint/vorssaint-utils/blob/main/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`:

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

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

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

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

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

```

The `applyMapping` method executes this via `Shell.run`:

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