AprilNEA / AprilNEA/OpenLogi

[Bug]: Solaar and OpenLogi silently fight over the thumb wheel — 0x2150 polarity is one device-global write

Open
#1,273 0 comments 0 reactions 0 assignees View on GitHub
platform: linux type: bug
Dominant language
Rust
Stars
21k
Forks
675
Avg merge
2d 5h
Merged PRs (30d)
172

Description

### Pre-flight checklist

- [x] I searched existing issues and this is not a duplicate.
- [x] I am on the latest release (0.8.3).
- [x] Logi Options+ is not installed (Linux). Note that this report is exactly that
class of conflict, for a different application.

### Which part of OpenLogi?

Both

### OpenLogi version

0.8.3

### Operating system

Linux

### OS version & architecture

Debian GNU/Linux 13 (trixie), x86_64, GNOME on X11

### Device model

MX Master 3S

### How is the device connected?

Logi Bolt receiver

### Affected area(s)

- [x] Button remapping
- [x] Settings / configuration (TOML)
- [x] Other — HID++ feature ownership vs. another HID++ manager

### What happened?

With **Solaar 1.1.14** running (the default on most Linux distros, autostarted from
`/etc/xdg/autostart/solaar.desktop`), OpenLogi and Solaar both divert the thumb wheel over
HID++ `0x2150`, and they silently corrupt each other. Two distinct symptoms, both of which
look like OpenLogi bugs from the user's side:

**1. The wheel direction inverts.** `setThumbwheelReporting` (function 2) carries reporting
mode *and* the invert bit in a single device-global write, so the last writer wins for both
consumers. Solaar stores `thumb-scroll-invert: false` and writes it on connect; OpenLogi
0.8.3 normalises polarity at arm time from `0x2150 default_dir`
(`ArmedThumbwheel::direction()` in `crates/openlogi-device/src/session/gesture.rs`, added in
45fbb0cc). Whichever armed last sets the sign that *both* tools then decode. Solaar's rules
test the raw sign (`thumb_wheel_up` / `thumb_wheel_down` in `logitech_receiver/diversion.py`),
so after OpenLogi arms, they fire on the opposite physical direction.

**2. Changing the binding in the OpenLogi GUI does nothing.** Solaar keeps receiving the
`0x2150` notifications that OpenLogi's own diversion generates, and keeps running its rules
against them. So a user who has any Solaar thumb-wheel rule gets a second, invisible actor
emitting keys, and switching the OpenLogi thumb-wheel preset appears to have no effect — the
keystrokes are coming from Solaar.

This took a while to diagnose because nothing surfaces it. The existing conflict detection
(`EventTapInfo::known_input_conflict`, `crates/openlogi-hook/src/lib.rs`) cannot help on two
counts: its curated list is macOS-oriented (Logi Options+, SteerMouse, BetterMouse, ...) and
has no Linux entries, and it is built on `Hook::list_event_taps`, which is documented to
"return an empty vector on non-macOS targets" (`lib.rs:509`). It also detects *OS event taps*,
a different layer entirely from HID++ feature diversion, so even on macOS it would not catch
a second HID++ manager.

### Steps to reproduce

1. On Linux with Solaar installed and running, add a Solaar rule on the thumb wheel, e.g.
`Test: [thumb_wheel_up, 10]` → `KeyPress: [XF86_AudioRaiseVolume, click]` and the mirror
for `thumb_wheel_down`. Confirm it works.
2. Install OpenLogi 0.8.3 and bind the thumb wheel to Volume Down / Up, which makes OpenLogi
divert the wheel.
3. Roll the wheel — the volume moves the wrong way.
4. Switch the thumb-wheel preset to the reversed pair in the OpenLogi GUI — the behaviour
does not change.

### Suggested direction

Detection rather than arbitration seems right, since neither tool can safely take the wheel
from the other:

- Extend conflict detection to HID++-level competitors, and make it work on Linux. Solaar is
the obvious first entry (`solaar` process, or `~/.config/solaar/config.yaml` carrying
`thumb-scroll-mode: true` for a device OpenLogi also manages).
- Surface it where the user is: a warning on the thumb-wheel panel, not only in Diagnostics.
- Possibly re-assert polarity if `0x2150` reporting is observed changing underneath an armed
session, which would at least make the direction stable.

### `openlogi list` output

```text
Logi Bolt Receiver (AA30CBD029D4775E, vid=046d pid=c548)
└─ slot 2 ● MX Master 3S (mouse, wpid=b034, battery=70% full (discharging))
model_ids=[b034,0000,0000] ext=01 serial=... unit_id=... transports=btle
```

### Notes

Diagnosed by code reading plus the running config of both tools; the polarity mechanism in
symptom 1 is inferred, since `openlogi diag` does not expose `0x2150` `default_dir` and I did
not read it off the device. Symptom 2 and the detection gap are directly verified. Disabling
Solaar resolved both.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by tracing EventTapInfo::known_input_conflict and Hook::list_event_taps in crates/openlogi-hook/src/lib.rs, then inspect the thumb-wheel path in crates/openlogi-device/src/session/gesture.rs. Done means Linux HID++ conflict detection recognizes Solaar and the warning appears on the thumb-wheel panel without attempting arbitration; reproduce with the listed Solaar rules.

Written by the indexing model from the issue text.

Assessment

Tech stack
linux, rust
Domain
desktop, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.