Files
chanora/crates
EdisonJwa 383b707e7c feat(audio,macos): live CGEventTap PTT capture (SDD-085)
Replace the macOS PTT backend's worker-thread stub (which had just
slept) with a full CGEventTap implementation:

  * extern "C" bindings to CGEventTapCreate, CGEventGetIntegerValueField,
    CGEventTapEnable, CFMachPortCreateRunLoopSource, CFRunLoopGetCurrent,
    CFRunLoopAddSource/RemoveSource, CFRunLoopRun/Stop, CFRelease, plus
    the kCFRunLoopCommonModes static.
  * tap_callback: C-ABI extern fn that reads bound keycode /
    mouse-button from atomics, matches the incoming event, and toggles
    the AudioTransmitGate. Returns the event unchanged (listen-only
    tap, no event modification). Privacy-safe: never logs raw key
    codes or button numbers (DEC-027).
  * Event mask covers kCGEventKeyDown, kCGEventKeyUp,
    kCGEventOtherMouseDown, kCGEventOtherMouseUp; also handles the
    kCGEventTapDisabledBy{Timeout,UserInput} notifications by logging
    a degraded-mode warning.
  * Worker thread captures the CFRunLoopRef via a Send-marked
    RunLoopHandle newtype so stop() can call CFRunLoopStop from the
    audio engine thread.
  * Box<TapState> is leaked into the worker via a Send-marked
    TapStatePtr newtype; reclaimed on worker exit so the gate's Arc
    refcount stays correct.
  * Flutter logical-key labels are mapped to Carbon virtual keycodes
    via label_to_macos_keycode (covers letters, digits, function keys,
    navigation, common punctuation). Mouse-side-button labels resolve
    via label_to_macos_mouse_button (3 = Mouse4, 4 = Mouse5).
  * refresh_bound_atomics() rebuilds bound_keycode + bound_mouse_button
    on start() and rebind() so the tap callback sees the new binding
    without re-arming the tap.

Tests: chanora_audio 34 / 0 / 0 on macOS (was 28 before this commit).
Added: keymap_letters, keymap_function_keys, keymap_navigation,
keymap_unknown_returns_none, mouse_button_map, runloop_handle_is_send.

Verified the live IOHIDCheckAccess returns Undetermined (Unknown=2) on
a fresh M1 box where Input Monitoring has never been requested; the
1.5 s permission-watcher re-publishes the descriptor on user grant
or revoke without restart.

DEC-025: macOS desktop officially in scope. SAD-073: two-level PTT
ladder. SRS-198: honest capability advertising. DEC-027: privacy.
2026-05-16 13:50:28 +08:00
..