Skip to content

Add Logitech HID++ (HIDPP 2.0) support via hidapi#1710

Open
PradyumnaKrishna wants to merge 1 commit into
noah-nuebling:masterfrom
PradyumnaKrishna:hidpp-listener
Open

Add Logitech HID++ (HIDPP 2.0) support via hidapi#1710
PradyumnaKrishna wants to merge 1 commit into
noah-nuebling:masterfrom
PradyumnaKrishna:hidpp-listener

Conversation

@PradyumnaKrishna

@PradyumnaKrishna PradyumnaKrishna commented Jan 14, 2026

Copy link
Copy Markdown

Fixes #1277 — the original issue I opened about a year ago.

Description

After a year, I’m back — and I finally got my Logitech Signature M650 to expose button 4 and 5 correctly. The HID++ code here was built with heavy AI help (I’m not a C/C++ expert), but it works and I wanted to upstream it. Feel free to ask for changes you want to make, or if you like you can take it from here.

This change introduces first‑class Logitech HID++ support in the helper so devices that expose buttons only through HID++ can be handled without the vendor driver. This PR doesn't interfere with any code other than HIDPP for logitech devices.

Design Decision

Logitech HID++ exposes multiple button‑capture features. We chose REPROG_CONTROLS_V4 because it is available on our working test device (M650) and Solaar already supports/uses it. That suggests it is a practical, widely‑enough feature to target first, and it likely explains why certain Logitech buttons were previously not visible to MMF. We therefore divert controls via REPROG_CONTROLS_V4 and restore diversion on shutdown.

What’s implemented

  • Adds a dedicated HIDPPListener and wires it into DeviceManager for attach/remove.
  • Enumerates Logitech HID interfaces through hidapi.
  • Discovers HID++ 2.0 features via FEATURE_SET and only enables REPROG_CONTROLS_V4 when advertised.
  • When diversion is active, Back/Forward CIDs are translated into CG button down/up events and we synthesize drag events while a diverted button is held.
  • Best‑effort: if HID++ probing fails we fall back to normal IOHID input.

Licensing / attribution

hidapi is pulled in as a submodule and remains under its upstream licensing. hidapi is tri‑licensed (BSD‑style/original/GPL) per its LICENSE*.txt files; this PR does not alter those terms and only links against it from our helper.

Thanks to @pwr-Solaar/Solaar — their codebase and docs were a primary reference for HID++ protocol handling and discovery patterns.

Impact

Logitech mice that require HID++ now work without vendor software, while existing non‑Logitech behavior remains unchanged.

PS (testing with logitech devices):

  • Signature M650 — supports REPROG_CONTROLS_V4 → works (buttons 4/5 captured via HID++).
  • G304 Wireless — does not support REPROG_CONTROLS_V4, but buttons 4/5 already work → app falls back cleanly and behaves as before.

This change introduces first‑class Logitech HID++ support in the helper so
devices that expose buttons only through HID++ can be handled without the
vendor driver.

Logitech HID++ exposes multiple button‑capture features. We chose
REPROG_CONTROLS_V4 because it is available on our working test device (M650)
and Solaar already supports/uses it. That suggests it is a practical,
widely‑enough feature to target first, and it likely explains why certain
Logitech buttons were previously not visible to MMF. We therefore divert
controls via REPROG_CONTROLS_V4 and restore diversion on shutdown.

The implementation adds a dedicated HIDPPListener and wires it into
DeviceManager for attach/remove. We enumerate Logitech HID interfaces through
hidapi, discover HID++ 2.0 features via FEATURE_SET, and only enable
REPROG_CONTROLS_V4 when it is actually advertised. When diversion is active,
Back/Forward CIDs are translated into CG button down/up events and we
synthesize drag events while a diverted button is held.

hidapi is pulled in as a submodule and remains under its upstream licensing.
hidapi is tri‑licensed (BSD‑style/original/GPL) per its LICENSE*.txt files;
this commit does not alter those terms and only links against it from our
helper. Thanks to @pwr‑Solaar/Solaar — we used their codebase and docs as a
primary reference for HID++ protocol handling and discovery patterns.

Impact: Logitech mice that require HID++ now work without vendor software,
while existing non‑Logitech behavior remains unchanged.

Signed-off-by: Pradyumna Krishna <git@onpy.in>
@PradyumnaKrishna

Copy link
Copy Markdown
Author

@noah-nuebling Please take a look when you have a moment.

@pkrh39

pkrh39 commented Feb 10, 2026

Copy link
Copy Markdown

Can confirm this works on M650L sequoia 15.7.3, but the side buttons stop working after waking device up from sleep. I wanted to post logs here though I have no idea how to get logs after a sleep cycle..

@PradyumnaKrishna

Copy link
Copy Markdown
Author

Yes @pkrh39, I’m seeing this too, but I don’t think it’s related to the sleep events. I’m not sure how to reproduce it yet, but I’ll dig into it.

@miguelAngelo1999

Copy link
Copy Markdown

Hey @PradyumnaKrishna — great work tackling this! I hit the same problem and went down a similar path. I ended up with a different implementation that might be worth looking at before this merges: #1904

The main differences in my approach (`LogitechCIDActivator`):

No external dependency — uses `IOHIDLib` directly instead of hidapi, so no submodule or C++ required. Pure Obj-C.

All divertable CIDs, not just Back/Forward — the code enumerates `GetCidInfo` and diverts every button with the divert flag set, so thumb buttons, tilt wheel, precision mode, and side buttons all work without hardcoding CID values.

Unifying/Bolt receiver support — probes slots 1–6 on the receiver so wireless mice via USB dongle work, not just Bluetooth.

Sleep/wake handled — subscribes to `NSWorkspaceDidWakeNotification` + `NSWorkspaceScreensDidWakeNotification` and re-diverts on wake (HID++ diversion is per-connection and resets on sleep). Also has a 25s keep-alive timer for firmware resets during normal use. One gotcha I hit: `IORegisterForSystemPower` with an invalid `io_connect_t` corrupts the run loop on startup — avoid it entirely.

Not saying this to block your PR — just thought the overlap was worth flagging so Noah can pick the best approach or combine the two.

@PradyumnaKrishna

Copy link
Copy Markdown
Author

Saw your work around @miguelAngelo1999. If your work solves the major problem around logitech devices and does work with logitech devices like M650 and other I don't have any problem. I was doing my best to understand the problem and fix it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Logitech mouse support through hidpp2.0 [enhancement]

3 participants