Skip to content

Detect macOS system-wide hotkey conflicts (Carbon CopySymbolicHotKeys) #122

Description

@samkeen

Optional, and only worth doing after #121 (customizable shortcuts) — until a user can pick their own chord, there's nothing to warn them about.

What's possible. CopySymbolicHotKeys() (HIToolbox) returns the system's symbolic-hotkey table: kHISymbolicHotKeyCode, kHISymbolicHotKeyModifiers, kHISymbolicHotKeyEnabled — Spotlight, Mission Control, screenshots, input-source switching and the rest. Public header, Carbon-era; verify the deprecation annotation against the current SDK before committing to it.

What it costs. An objc2/CoreFoundation dependency in b2-desktop, unsafe FFI (repo policy: a // SAFETY: per block stating the invariant that makes it sound — model.rs's weights mmap is the worked example), and virtual-keycode → character translation via UCKeyTranslate + TISCopyCurrentKeyboardLayoutInputSource, because the API speaks keycodes and the registry speaks characters. Non-trivial FFI for what is ultimately an advisory string.

The hacky alternative, explicitly rejected. Shelling out to defaults read com.apple.symbolichotkeys and parsing AppleSymbolicHotKeys — a dict keyed by undocumented magic integers whose meanings you'd hard-code. It works, plenty of apps do it, and it's exactly the kind of thing this repo would call a hack.

What is not possible in any supported way. Third-party global hotkeys — Raycast's ⌘Space, Alfred's ⌥Space, Rectangle's ⌃⌥arrows. Nothing enumerates another process's RegisterEventHotKey or CGEventTap claims. Any curated "commonly taken" list is a guess with a shelf life, and would go stale silently.

Why Low. The empirical probe in #121 already covers most of the practical value for free, and stays true across OS updates and third-party installs in a way a static table can't. This buys pre-emptive warnings (naming the conflict before the user presses it) for a meaningful chunk of unsafe FFI — a real gain, but a small one on top.

Left over from the keyboard-registry work in #118 — Layer 4 of the collision-detection plan, deferred there on this reasoning.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions