Skip to content

Releases: NSEvent/xbox-controller-mapper

ControllerKeys 2.4.0

26 Jun 06:05

Choose a tag to compare

Added

  • Independent left/right stick tuning: Each analog stick now has its own sensitivity, acceleration, and deadzone, so you can keep one stick slow for pixel-precise aiming and the other fast to fling the cursor across a wide monitor—even with both sticks set to mouse mode. Previously the two sticks shared a single sensitivity, so tuning one changed the other. Set them independently in Settings → Joysticks.

  • Per-layer joystick overrides: Any layer can now override a stick's mode and tuning while it's held, and anything you don't set falls through to your base settings—the same transparency model layers already use for button mappings. Hold a layer trigger to make the left stick fast and release for fine control, without touching the other stick. Configure them in the new Per-Layer Overrides section of the Joysticks tab.

Fixed

  • Joystick deadzone and invert controls follow the selected mode: The Deadzone slider and Invert Y toggle edited the scroll-mode field on the right stick and the mouse-mode field on the left regardless of which mode was actually selected, so they had no effect once a stick was switched away from its default mode. They now bind to the field the chosen mode actually uses.

Download on Gumroad

ControllerKeys 2.3.0

25 Jun 19:43

Choose a tag to compare

Added

  • ⌘K command palette: A Spotlight-style jump bar — press ⌘K or the new toolbar button — to go straight to any section, controller button, or bound shortcut without walking the nested tab bar. Sections are searchable by what they do (typing "javascript" finds Scripts, "latency" finds Input), with arrow-key, Return, and Escape navigation.

Fixed

  • Touchpad cursor lag and path replay: Using the DualSense touchpad as a mouse could feel laggy and re-trace the path you just swiped under high-rate input — most noticeable through a Bluetooth-to-USB controller adapter, but reproducible wired too. Touchpad samples are now coalesced into a single net movement per drain, so a burst can no longer back up the input queue and replay the motion.

  • Expanded automation URL-scheme blocklist: TriggerKit automation URL handling now also rejects shortcuts, terminal, ssh, telnet, vnc, ftp, smb, and afp schemes, closing local-execution and sandbox-escape vectors that the earlier file and system-scheme block didn't cover.

  • OBS WebSocket password no longer falls back to plaintext: When Keychain storage failed, the OBS password used by automation commands was previously written to disk in plaintext as a fallback. It now fails securely and discards the password instead of persisting it unencrypted.

  • Accessibility labels for tooltip-only buttons: Controls that previously exposed only a hover tooltip — the ⌘K command palette, Settings, Profiles, trial status, and several mapping panels — now carry VoiceOver accessibility labels.


Download on Gumroad

ControllerKeys 2.2.1

19 Jun 08:45

Choose a tag to compare

Fixed

  • 8BitDo Lite 2 Android-mode support: Android mode now identifies as the Lite 2 instead of a generic controller, uses the corrected mini-map layout, keeps left-stick motion from falsely lighting D-pad actions, and reads the 8BitDo/Home logo button through raw HID when Input Monitoring is granted.

  • Launch crash when Bluetooth is off: ControllerKeys no longer crashes at startup when Bluetooth is unavailable or powered off; battery monitoring now clears state safely when CoreBluetooth is not ready.

  • Unsafe automation URL schemes blocked: TriggerKit URL handling now rejects non-web and system URL schemes so imported automations cannot launch arbitrary local handlers.

Changed

  • Real controller names: Controller surfaces now prefer product-specific names over generic GameController labels when a real product name is available.

  • Controller pairing guide links updated: In-app pairing guide URLs now point at the ControllerKeys documentation pages, including the newly added controller guides.

  • Release test stability: App-hosted XCTest now starts in a test-only scene so controller mapping and remote-mouse side effects stay out of the suite.


Download on Gumroad

ControllerKeys 2.2.0

17 Jun 20:05

Choose a tag to compare

Added

  • Guided first-run permissions setup: First launch now walks you through the macOS permissions ControllerKeys needs — Accessibility, Input Monitoring, and Bluetooth — one at a time, each with a plain-language explanation and a live status pill that flips to "Granted" the moment you toggle the switch, instead of firing every system prompt at once on launch. Accessibility (the fussy one) gets a drag-and-drop app-icon well so you can drop ControllerKeys straight into the Settings list without hunting through a file chooser, plus a Reveal-in-Finder fallback and troubleshooting help for stale permission state. Granting a permission instantly restarts the features that depend on it — no relaunch needed — and you can re-run the whole flow any time from Settings → General → Permissions. A banner appears if a permission is later revoked.

  • Anonymous, opt-out usage analytics: Now that ControllerKeys is distributed free through GitHub and Homebrew, the app sends a small anonymous ping — app version, macOS version, and Mac type — so I can see how many people use it and which versions to keep supporting. There's no account, no name, and no controller input or profile data involved, and your IP address is never stored. You can turn it off any time in Settings → General → "Share Anonymous Usage Data"; the privacy policy lists exactly what's sent.

Changed

  • Local Network permission is no longer requested at launch: The cross-Mac Remote Mouse relay now asks for Local Network access only when you actually set it up (or if you've already paired two Macs) — so if you never use that feature, you're never prompted for it.

  • More VoiceOver labels in the automation editors: Icon-only buttons in the macro library, automation program editor, and modifier-set editor now carry accessibility labels for screen-reader users.


Download on Gumroad

ControllerKeys 2.1.1

16 Jun 20:46

Choose a tag to compare

Fixed

  • Window no longer breaks when no controller is connected: With nothing paired, the "No controller connected" pairing card could push the Buttons tab past the window height — the layout overflowed and shoved the toolbar and tab bar off the top edge while the controller diagram collapsed. The Buttons tab now scrolls when its contents don't fit and the diagram keeps a usable minimum size, so the toolbar and tabs always stay in place.

  • Blocked unsafe URL schemes: Website and quick-link actions now open only http/https URLs, so a crafted or imported profile can't use them to launch arbitrary system handlers (e.g. file:// or system-preference panes).

Changed

  • Layer toolbar adapts to narrow windows: The Base / layer / Add Layer / Swap / Cursor Hints / Stream pills are now a fixed height — labels no longer wrap to a second line and grow tall — and they collapse to icon-only buttons when the row gets too narrow. Layers keep their colored activator badge so they stay distinguishable, and tooltips name every icon.

  • Tooltips and VoiceOver labels for icon-only buttons: Icon-only controls across the Buttons tab, community profiles, and the sequence editor now carry hover tooltips and accessibility labels.

  • Hardened automation handling: Macros and automation programs are validated and migrated more strictly, with cleanup policies kept in sync between the editor and the runtime — reducing the chance of a malformed automation misbehaving.


Download on Gumroad

ControllerKeys 2.1.0

16 Jun 05:18

Choose a tag to compare

Added

  • 14-day free trial with license unlock: ControllerKeys now opens as a 14-day free trial with full functionality — no account needed. A first-launch welcome explains the trial and lets anyone who already purchased on Gumroad paste their license key to activate immediately. When the trial ends, controller mapping pauses (the rest of the app stays usable) until a license is entered; activation verifies against Gumroad and then keeps working offline, and the trial clock is stored in the login keychain so it survives reinstalls. License status, activation, and a buy link live in Settings → General.

  • Automatic updates: ControllerKeys can now update itself — it checks for new versions in the background and installs them with your approval, with a "Check Now" control in Settings → General. Updates are cryptographically signed (EdDSA) and notarized, so only genuine builds are ever installed.

  • Show/hide the profile sidebar with ⌘B: The profile sidebar is now shown by default and toggles with ⌘B (the shortcut hint appears next to the menu item). Hiding it persists until you show it again.

Changed

  • Apple-style Settings: Settings was rebuilt from one long scrolling form into a System Settings-style sheet — a sidebar of categories (General, Appearance, Layout, Controllers, Remote Mouse, About) with the selected category's controls shown on the right.

  • Reworked toolbar and mapping toggle: The connection status (status light and controller name) moved to the right side of the toolbar, next to a redesigned mapping toggle — a high-contrast filled pill ("Mapping On" / "Trial ended") that replaces the previous low-contrast accent-on-gray text.

  • More room for the controller map: Tightened the toolbar, tab bar, and Buttons-tab header so the controller diagram sits higher and renders larger. The Timeline strip is now optional — hide it from the Buttons tab and restore it from Settings → Layout.

Fixed

  • Stream and Cursor Hints toggles: These buttons now reliably reflect their on/off state. Previously the highlight could stick after toggling because the underlying preference wasn't observed by the view.

Download on Gumroad

ControllerKeys 2.0.1

14 Jun 08:44

Choose a tag to compare

Added

  • Profile switch action: System-command mappings can now switch directly to another ControllerKeys profile. The action is available across the mapping editor surfaces and is treated as an internal profile action instead of a shell/webhook command.

  • Controller Connection Guides window: Pairing help now has a dedicated guide window with controller-specific minimaps, reachable from the no-controller pairing hint and the menu bar.

Changed

  • 8BitDo documentation and marketing assets: The README set and screenshot pipeline now include the 8BitDo Zero 2 and Micro, with the 8BitDo section rewritten to focus on why the tiny-controller support matters in practice.

  • Icon-only control accessibility: Added missing accessibility labels and tooltips to several toolbar, layer, sidebar, and stream-overlay controls.

Fixed

  • Configure-button sheet scrolling: Scrolling inside a Buttons-tab configuration sheet no longer leaks through to the underlying buttons canvas. Canvas two-finger panning now only handles scroll events from the actual canvas window and ignores attached sheet windows.

  • Universal Control secret storage hardening: The relay no longer falls back to storing shared secrets in UserDefaults when Keychain persistence fails.


Download on Gumroad

ControllerKeys 2.0.0

13 Jun 20:28

Choose a tag to compare

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

ControllerKeys 1.9.3

10 Jun 03:36

Choose a tag to compare

Added

  • Magicsee R1 controller mapping: Generic HID fallback now recognizes the Magicsee R1 on macOS and maps its face buttons, triggers, sticks, Back, and Start controls through the SDL controller database.

Fixed

  • Raw HID controller reliability: ControllerKeys now filters generic HID input to controller collections when available, ignores stale fallback timers after disconnect, handles device-open failures without phantom controllers, resets stale controller-type flags between detections, and normalizes CRC-bearing SDL GUIDs so more database mappings resolve correctly.

  • Universal Control relay and input-state hardening: Relay sends now recover from terminal connection failures, bound replay protection per peer, avoid redundant 120 Hz UI-state echoes, and keep hot-path handoff settings cached. Joystick ticks no longer hold mapping locks across network sends, haptics, or re-entrant button handling.

  • Text input and persistence edge cases: Text typing now preserves full UTF-16 sequences such as emoji, pasteboard writes happen synchronously to avoid stale clipboard races, and queued profile/config saves flush during app termination.

Changed

  • Test and CI coverage: Added a GitHub Actions macOS test workflow, split the large test file into focused suites, added Magicsee R1 regression coverage, and made benchmark tests opt-in.

Download on Gumroad

ControllerKeys 1.9.2

09 Jun 00:12

Choose a tag to compare

Fixed

  • Off-brand controller detection: ControllerKeys now falls back to raw HID for controller-shaped devices that are missing from macOS GameController, including generic Bluetooth Low Energy gamepads and devices with known SDL vendor/product mappings. This lets many inexpensive third-party controllers appear as mappable controllers instead of showing "No controller."

  • Generic HID mapping coverage: Fallback controllers now handle common D-pad hat encodings, version-zero and all-platform SDL controller database matches, trigger axis polarity, and axis-backed button polarity so more nonstandard controllers map their sticks, triggers, buttons, and D-pad correctly.

  • Generic HID false-positive guards: The fallback path avoids inferring mouse-style HID devices as controllers, ignores non-HID controller database GUID rows when building vendor/product matches, and prefers macOS mappings when duplicate SDL GUIDs exist.


Download on Gumroad