macoc/docs/superpowers/specs/2026-10-25-in-process-hid-remap.md

2.1 KiB

In-Process Native HID Remapping

User contract

The app installs physical Caps->F19 mappings and requests any required input privileges under Capswitch's own identity. Never request that the user grant Input Monitoring or Accessibility to a system binary or helper. Do not launch /usr/bin/hidutil or other executables.

Apple-supported mechanism

Technical Note TN2450 documents:

  • IOHIDEventSystemClientCreateSimpleClient
  • IOHIDEventSystemClientCopyServices
  • IOHIDServiceClientConformsTo(kHIDPage_GenericDesktop, kHIDUsage_GD_Keyboard)
  • IOHIDServiceClientCopyProperty/SetProperty with UserKeyMapping.

The IOKit adapter is compiled inside the existing CapswitchHID SwiftPM C target, linked to IOKit in the Capswitch executable.

Safety and lifecycle

  • Set up active Quartz event tap before changing HID keyboard mappings.
  • Enumerate connected keyboard services, read each current UserKeyMapping, and fail closed if malformed or conflicting with Caps/F19.
  • Preserve other mappings while appending Caps->F19 only when absent.
  • Verify the result per service, do not trust a successful setter alone.
  • Persist owned service registry IDs under Capswitch's own preferences so a crash/restart can restore exactly Capswitch-owned rules.
  • On Pause/Quit, remove only the exact pair for those owned services.
  • A disconnected service's mapping is discarded by macOS.
  • On wake/reconnect, re-enumerate and reconcile.
  • No privileged helpers, keyboard drivers, or external subprocesses.
  • Both Accessibility and Input Monitoring requests target Capswitch; the OS remains responsible for user consent.

Acceptance tests

  • Build without Xcode IDE using Taskfile and Command Line Tools on macOS 14.8.9.
  • First launch creates permission prompts where appropriate.
  • Native --doctor reports keyboard services and applied pair counts.
  • Short Caps taps between typed letters register as F19 down/up and switch exactly once on release.
  • Option+Caps toggles real Caps Lock including actual typing state.
  • Pause/Quit preserves foreign HID remappings.
  • Keyboard reconnect / sleep recovery works.