AprilNEA / AprilNEA/OpenLogi

[Feature]: Decode OnboardProfiles (0x8100) event 1 - live DPI stage changes from the mouse

Open
#1,194 0 comments 0 reactions 0 assignees View on GitHub
area: hidpp platform: all type: feature
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 the [Roadmap](https://github.com/AprilNEA/OpenLogi#roadmap), and this isn't already tracked.

### Problem / motivation

G-series mice change their DPI stage on the hardware itself (the DPI button cycles the onboard profile's DPI slots). Nothing in OpenLogi can see that happen: `0x8100` is name-only on master, and the in-flight onboard-profiles work (#459 read/mode slice, #1002 read + write groundwork, #1146 G502 branch) decodes no events, so even once those land the GUI's DPI display goes stale the moment the user presses the DPI button. Polling `0x2201` only returns the resulting value, not which profile slot is active, and burns traffic on battery mice.

Measured on real hardware (G305, WPID 0x4074, profile_format_id 3, Lightspeed receiver 046d:c53f; raw frame traces available on request): the device broadcasts the change.

### Proposed solution

Decode `0x8100` event 1 in the onboard-profiles feature (the `EventSource` pattern from `wireless_device_status.rs` fits):

1. **Event 1 is "current DPI index changed".** Frame shape `[0x11, device_index, feature_index, 0x10, new_index, 0x00 ...]` - function nibble 1, `params[0]` = new 0-based index into the profile's DPI slot table. Observed `02`, `00`, `01` across three DPI-button presses. Mapping the index into the decoded profile's DPI slots gives a live "current DPI" readout with zero polling.

2. **Document the event that never comes:** `setCurrentProfile` (function 3) completes with no broadcast - confirmed in two capture sessions on different days. Code that waits for a profile-activated event after switching profiles will hang; reading `getCurrentProfile` back is the reliable confirmation. Worth a doc comment in the feature so nobody rediscovers this the hard way.

Both facts are G305-measured; the `--sector`/diag tooling from #1002 should make it easy to check whether the G502 family behaves the same.

### Alternatives considered

- Polling 0x2201 after the fact: returns the DPI value but not the active slot, races the press, and costs battery on wireless mice.
- G HUB shows the live stage; that is the bar to match.

### Related area(s)

- [x] GUI
- [ ] CLI
- [ ] Button actions / remapping
- [x] DPI
- [ ] SmartShift
- [ ] Per-application profiles
- [ ] Configuration (TOML)
- [ ] Auto-update
- [x] Other

### Additional context

Deliberately filed as its own issue rather than a review comment on #1002/#459 so it stays actionable regardless of how those PRs slice up the 0x8100 work. Related: #1193 (another implemented-but-unwired event, 0x8090 broadcast) - same EventSource wiring pattern would serve both.

Contributor guide

No contributing guide indexed for this repository

Research direction

Inspect the onboard-profiles feature and compare its event handling with wireless_device_status.rs and its EventSource pattern. Use the --sector/diag tooling and G305 traces to verify 0x8100 event 1 and its DPI-slot index mapping. Done means the GUI updates the live DPI stage without polling, and the feature documents that setCurrentProfile has no broadcast and must be confirmed by getCurrentProfile.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
backend-api-design, desktop
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.