[Bug]: MX Master 2S thumb wheel rebinds never arm — no 0x2150 feature, and the 0x1b04 CID 0x00d7 fallback hijacks pointer movement
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 675
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 172
Description
### Pre-flight checklist
- [x] I searched [existing issues](https://github.com/AprilNEA/OpenLogi/issues?q=is%3Aissue) and this is not a duplicate.
- [x] I am on the latest release (v0.8.0) or a recent `master` build. The bug also reproduces on v0.7.10.
- [x] I quit Logi Options+ before running OpenLogi (uninstalled; OpenLogi is the only Logitech driver on this machine).
### Which part of OpenLogi?
Agent (HID++ capture session / gesture watcher)
### Device
MX Master 2S (046d:b019), tested over **both** Bluetooth BLE direct and Unifying receiver (`receiver:aa1d9dbd:slot:1`) — same behavior on both.
macOS 26.5.2 · OpenLogi v0.8.0 (auto-updated 2026-08-26 from v0.7.10, which reproduces identically)
### Summary
Thumb-wheel rotation rebinds (any action — VolumeUp/Down, horizontal scroll, etc.) never take effect on the MX Master 2S. Every other control works: side buttons, gesture button, DPI button (ToggleSmartShift). Every capture session logs:
```
control capture active index=N gesture_sources=1 dpi_buttons=1 buttons=0 thumbwheel=false
```
Reproduction matrix: v0.7.10 and v0.8.0 × BLE and Unifying × cold start / full restart / GUI preset hot-reload / minimal clean config — **all** end with `thumbwheel=false`. On 8/25 (still 0.7.10), all 18 capture-session records of the day are `thumbwheel=false` with zero config parse errors.
### What I ruled out
1. **Config loading is fine.** `config.toml` parses cleanly (verified with an external TOML parser), no `could not load config.toml` in agent logs, runtime device key matches the migrated schema-v6 key (`unit:9e43a1eb`). Strongest evidence: the DPI button executes my configured non-default action `ToggleSmartShift` (`SmartShift toggle → flipping wheel mode`) — so config → plan → dispatch works; only the thumb-wheel arm path doesn't fire.
2. **The plan layer is fine.** With a debug build instrumented at `thumbwheel_armed`, every session logs:
```
thumbwheel arm decision key=unit:9e43a1eb sensitivity=70 bindings_nondefault=true default_sensitivity=14 armed=true
```
So `spec.capture_thumbwheel = true` reaches the session layer correctly.
3. **HID++ read/write is healthy.** `diag dpi / smartshift / controls / features` all round-trip OK on both transports.
### Root cause (probe-level)
`arm_controls_into` arms the thumb wheel only when `root.get_feature(thumbwheel::FEATURE_ID /* 0x2150 */)` returns `Some`:
```
DEBUG openlogi_device::session::gesture: thumb wheel feature absent — skipping diversion feature=0x2150
```
A direct probe of the device shows:
- `get_feature(0x2150)` behaves inconsistently — sometimes returns `Some(index=0)` (false positive), sometimes `Ok(None)`; a full `diag features` enumeration does **not** list 0x2150. Conclusion: **the MX Master 2S firmware has no HID++ 0x2150 Thumbwheel feature** (that's Master 3/4 generation); its thumb wheel is exposed as a virtual control on 0x1b04 instead.
- `getCtrlIdInfo` for CID 0x00d7 returns:
```
cid=0x00d7 flags=DIVERTABLE | VIRTUAL_CONTROL | RAW_XY | FORCE_RAW_XY (raw_wheel=false)
```
### Fallback experiment (failed — do not repeat)
I tried arming CID 0x00d7 like a gesture source (`setCidReporting{diverted=true, raw_xy=true, force_raw_xy=true}`):
- The diversion write succeeds and `rawXYEvent`s (dx≠0) arrive while rolling.
- **But it hijacks the whole pointer pipeline**: all pointer deltas get consumed as the control's raw-XY reports — the cursor freezes and mouse movement becomes volume presses.
Conclusion: on 2S firmware, diverting the virtual thumb-wheel control does not yield a rotation-only channel; it diverts pointer motion itself. I restored the control's reporting afterwards; no lingering effects.
### Expected
Either (a) thumb-wheel rebinds work on the 2S via some other mechanism I couldn't find, or (b) if there is genuinely no usable channel, the GUI should hide/disable thumb-wheel presets for devices without the capability instead of offering bindings that can never fire.
Happy to run probes against my device if that helps — I have a debug build set up already.
### Attachments
- Agent state logs covering both versions: `~/.local/state/openlogi/agent.2026-08-25.log` (v0.7.10), `agent.2026-08-26.log` (v0.8.0)
- Possibly related: #887 (sensitivity ignored), #365 (single step only) — same area, more severe manifestation
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in openlogi_device::session::gesture at arm_controls_into and inspect the 0x2150 feature check alongside the 0x00d7 CID behavior. Reproduce the feature enumeration and getCtrlIdInfo probes on the MX Master 2S without diverting pointer movement; done means finding a safe thumb-wheel channel or ensuring unsupported devices do not offer thumb-wheel presets.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100