macoc/docs/superpowers/specs/2026-10-25-capswitch-design.md

1.8 KiB

Capswitch Design

Capswitch is a small native macOS menu-bar application for a user who wants physical Caps Lock to cycle keyboard layouts without the stock input-source shortcut HUD or animation.

Intent

On a plain Caps gesture, suppress the system Caps Lock event and switch to the next enabled keyboard input source on Caps release. Reserve Caps+Option for the real Caps Lock behavior.

Goals

  • Global Caps interception through Accessibility-authorized CGEventTap.
  • Plain Caps switches once on release.
  • Caps+Option toggles real Caps Lock in either key order.
  • Input sources are selected directly through Carbon TIS APIs.
  • Menu-bar indicator shows the current input source and permission state.
  • Build and bundle from Taskfile/CLI on macOS without an Xcode project.

Non-goals

  • Replacing or modifying macOS input-source configuration.
  • Supporting App Store sandbox or notarized distribution in the MVP.
  • Implementing a full preferences window.
  • Supporting arbitrary remapping beyond Caps and Caps+Option.

Interaction Contract

The event tap suppresses Caps down/up events. It records whether Option was already down or became active while Caps is held. On Caps release, no Option seen selects the next source; any Option seen schedules a synthetic clean Caps down/up. If Option remains held, the synthetic Caps event is posted when Option is released.

Platform Contract

  • Swift 5-compatible source targeting macOS 14.0+.
  • AppKit status item, CoreGraphics event tap, ApplicationServices Accessibility check, Carbon TIS input source APIs.
  • Stable bundle identifier `dev.local.Capswitch`.
  • `LSUIElement=true` so the app has no Dock icon.

Verification

Linux may run only platform-independent/static checks because the remote host has no Swift/macOS SDK. The authoritative build and XCTest run are on macOS 14.8.9 with Command Line Tools installed.