Skip to content

ControllerKeys 2.0.0

Choose a tag to compare

@NSEvent NSEvent released this 13 Jun 20:28
· 88 commits to main since this release

Added

  • Shared macro library across TriggerKit apps: Macros are no longer trapped inside a single ControllerKeys profile. Bindings can now pull from a shared, per-user macro library (~/Library/Application Support/TriggerKit/macros.json) that the same library editor in the Macros tab edits in place, and any binding surface — buttons, chords, sequences, gestures, layers, the command wheel — can reference a shared macro through a new Shared Library section in every macro picker. Edits to a library macro propagate live to every profile that references it; exported and community profiles stay portable because each referenced program is snapshotted into the profile, and an intentionally-emptied live macro does nothing rather than resurrecting its snapshot. This is the first feature that lets a macro you build in one TriggerKit app show up in another, and it leads the 2.0 bump.

  • Small 8BitDo controller support (Zero 2, Micro, Lite 2, Lite SE): These tiny pads impersonate first-party controllers over Bluetooth — the Zero 2 and Micro clone a Pro Controller or DualShock 4 with no analog stick, funneling their physical D-pad through a phantom left-stick axis that macOS mis-calibrates (right often registered as left). ControllerKeys now reads the raw HID reports directly to recover the D-pad correctly on every reconnect, synthesizes the Micro's Home button (which macOS otherwise swallows), and ships product-accurate Buttons-tab previews traced from the official renders for all four pads. A behavioral stickless-clone detector — a real analog stick always sweeps through intermediate magnitudes, while a clone snaps center-to-full — distinguishes the impostors from genuine hardware, so real controllers are never affected. A new D-Pad stick mode lets any stickless pad act as a proper D-pad, and because the d-pad feeds the stick axis its mode dropdown also offers Mouse and Scroll — so the pad can drive the cursor or wheel directly. Stickless previews drop the controls these pads don't have (no analog sticks, and no triggers on the Zero 2), relabel the shoulders to match the hardware (L/R, plus L2/R2 on the Micro), and render the 8BitDo home button with its own logo.

  • Redesigned controller previews with photo-traced silhouettes: The Buttons-tab controller graphic and the stream overlay were rebuilt from generic blob bodies into product-accurate previews for every supported controller — Xbox, Elite Series 2, DualSense, DualSense Edge, DualShock 4, Switch Pro, Steam Controller, the four small 8BitDo pads, and the Siri Remote. Bodies are traced from product photos at their true aspect ratios with per-model materials (carbon black, PlayStation white with light bars, the DS4 light bar, charcoal Pro), controls sit at their real hardware locations, and back paddles render with connector-line anchors — four metallic blades on the Elite, two on the DualSense Edge, four rear grips on the Steam Controller. Face buttons now follow each family's printed letters in their physical diamond, the stream overlay follows the connected controller type instead of being hardcoded to Xbox/PlayStation, and the whole set is backed by a documented photo-trace-to-Swift process so new controllers land at the same quality.

  • Pannable, location-anchored zoom on the buttons canvas: The mapping canvas used to only zoom around its center. Now you can drag anywhere on empty canvas or a card background to pan, pinch-zoom is anchored at your fingers so the content under them stays put while the scale changes, and two-finger scroll pans directly. Button taps and drag-to-swap still win on the controls themselves. Double-click empty canvas or press Cmd+0 to re-center and reset the scale, and the pan offset is clamped so the canvas can't be flung out of view.

  • Pairing instructions when no controller is connected: With no controller connected, the Buttons tab now shows a pairing-hint card above the canvas instead of silently rendering a default layout. With no specific model picked, it's a "No controller connected" chooser with a chip for every controller family that auto-connects the moment a controller enters pairing mode; pick a chip and it jumps straight to that model's steps. For a specific preview, the card shows step-by-step Bluetooth pairing for that exact controller, a wired/USB note, model tips, native-support caveats, and "Open Bluetooth Settings" / "Full Guide" buttons. Localized into German, Japanese, and both Chinese variants.

  • Controller layout preview picker: A new layout menu above the input log lets you manually choose which controller layout the Buttons tab previews — handy for authoring a profile against a controller you don't have in hand. Layouts that match a currently-connected controller are marked, your pinned choice now persists across relaunches, and a small inline note warns when the layout you're previewing doesn't match anything connected.

  • Descriptor-aware SDL fallback and Controller Support Dump: The generic-HID fallback now validates each SDL controller-database row against the live macOS HID element layout — non-macOS rows are only borrowed when every element they reference actually exists, duplicate database rows per controller are scored independently with later rows winning ties (matching SDL override order), and borrowed-mapping provenance like "SDL Windows fallback" is surfaced in the toolbar and menu bar. A new Controller Support Dump (Help menu, plus the no-controller toolbar/menu-bar entry points) exports an AI-prompt markdown alongside a raw HID layout JSON — with no serial numbers or location IDs — to make bringing up an unrecognized controller a copy-paste away.

Changed

  • Macro execution now runs through the TriggerKit runtime: Macros are converted to TriggerKit automation programs at execution time and run through the shared runtime instead of the app's own executor. Behavior is held identical — concurrent macros, continue-on-step-failure, the https-only link allowlist, and shell/webhook/OBS handling all carry over and are pinned by behavior tests — but macros now run off the main actor (a regression had inadvertently serialized them onto the UI run loop), held key/mouse/modifier presses replay their releases in reverse on any abnormal exit so a cancelled mid-sequence macro can't leave something stuck down, and emoji/flags/ZWJ sequences type correctly. The controller hot paths (button-to-key, joystick-to-mouse) are untouched.

  • Battery indicator hidden when no battery is reported: Many controllers expose no battery level to macOS — notably the small 8BitDo pads in D-input mode, which are Bluetooth-Classic HID gamepads with no battery service of any kind. The preview now renders nothing in that slot instead of a permanent "?" gauge that read as broken. Controllers that do report battery are unaffected.

  • Marketing and documentation refresh: All screenshots and demo GIFs were regenerated through a new reproducible capture pipeline, the German and Japanese READMEs were added (bringing the README to a four-language switcher), and website links now point at the live marketing page. None of this changes app behavior.

  • Test coverage and internal cleanup: The shared-macro wiring, stickless-clone detector, macro executor contract, and the v1.9.3 audit fixes all gained regression tests, and several large source files were split into focused component files with no behavior change.

Fixed

  • Apple TV Remote battery never showed: The Siri Remote serves a standard battery service, but its Bluetooth name is a bare serial number, so the name-matching battery monitor never identified it. The monitor now accepts a connected serial-named peripheral while an Apple TV Remote is the active controller (resetting on disconnect so nothing else is misidentified), and the remote's mini preview and the menu-bar badge now show its battery level like every other controller.

  • Swipe-typing debug log growing unbounded: Release builds were writing a ~/swipe_debug.log file in the user's home directory that grew without limit. That logging is now gated behind DEBUG builds, and a few force-unwraps in the swipe-typing and indicator paths were replaced with safe lookups.


Download on Gumroad