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

46 lines
2.1 KiB
Markdown

# 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.