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 rawCGEventobjects, and coordinates the lifecycle of thehidutilmapping.SuperKeySupport.swift– Contains the state machine logic, builds the JSON mapping tables forhidutil, 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 byhidutil)..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..soloTapor.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 thehidutilmapping 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 –
syncWithPreferencesvalidatesAXIsProcessTrusted()before starting the tap and clears any leftoverhidutilmappings if permissions are revoked. - Tap Recovery – The
handlemethod reacts to.tapDisabledByTimeoutor.tapDisabledByUserInputby immediately re-enabling taps viaCGEvent.tapEnableif the application remains active. - Lost Key-Up Detection – A
heldKeyWatchdogmonitors for stuck keys. If a key-up event is missed (common during rapid typing or sleep states), the watchdog queries the physical key state usingCGEventSource.keyState(.hidSystemState, key:)and callsforgetHeldKeyto 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.swiftcreates 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.swiftprovides the classification logic,hidutilJSON generation, and state machine that decides whether to swallow, modify, or redirect events. - The service uses
/usr/bin/hidutilwith--setand--getoperations 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.cgFlagswith 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →