Skip to content

feat(wlmouse): expose the DPI stage table to the shared stage editor - #51

Closed
ydw1904 wants to merge 1 commit into
OpenMouse-Project:mainfrom
ydw1904:feat/wlmouse-dpi-stages
Closed

feat(wlmouse): expose the DPI stage table to the shared stage editor#51
ydw1904 wants to merge 1 commit into
OpenMouse-Project:mainfrom
ydw1904:feat/wlmouse-dpi-stages

Conversation

@ydw1904

@ydw1904 ydw1904 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

What

WLmouse mice hold six onboard DPI stages and send the whole table in one
packet, and the driver has always decoded it — but only the active stage
reached the app, so OpenMouse could edit one DPI value where the vendor
software edits six.

The control app already ships a generic stage editor for exactly this shape
(Keychron M6 and Teevolution use it), so this reports dpiStages,
activeDpiStage and the dpiStageEditor hint, and adds the three setters
that editor calls.

WLmouse DPI stage editor, six stages read off a Beast Max 1K

How

setDpiStageCount and setDpiStageValue reuse the write setDpi was already
making: count and stages travel together in one packet, so a single-value edit
is a full table write either way. That write and its read moved into
writeStages/readStages, which setDpi now uses too.

Editing one stage keeps a Y that already differs from X. The shared editor
shows a single value per stage, and it must not quietly flatten a separate-axis
setup.

The one guess

setActiveDpiStage writes profile-page command 0x02, which is not in any
capture
. It is the 0x82 read with the high bit cleared, which is how every
other command in this driver pairs up (0x80/0x00, 0x81/0x01,
0x84/0x04, 0x88/0x08, 0x89/0x09, 0x8a/0x0a). The write is
verified by reading the active stage back, and the mouse answers an unknown
command with unsupported, so a wrong byte surfaces as a plain error rather
than a silent no-op — but it would be good to have someone else confirm it on
hardware before trusting it.

Testing

  • npm run check clean, npm test 829 passing.
  • Three new tests in src/drivers/wlmouse/hid.test.ts cover the table round
    trip, the Y-preservation rule, and the rejection paths, against a fake device
    that now models a mutable stage table.
  • Read path confirmed on real hardware: a Beast Max 1K behind the shared 1K
    receiver (36a7:a882), reporting the same six stages its vendor software
    shows (screenshot above).

Per-stage DPI colours are the obvious follow-up. The command that carries them
is still unknown, so they are deliberately out of scope here.

🤖 Generated with Claude Code

The mouse has always sent its whole stage table in one packet and the
driver has always decoded it, but only the active stage reached the app,
so the panel could edit one DPI value where the vendor software edits
six. The control app already ships a generic stage editor for exactly
this shape (Keychron and Teevolution use it), so this reports
`dpiStages`, `activeDpiStage`, and the `dpiStageEditor` hint, and adds
the three setters that editor calls.

`setDpiStageCount` and `setDpiStageValue` reuse the write `setDpi` was
already making: the count and every stage travel together in one packet,
so a value edit is a full table write either way. Editing a stage keeps
a Y that already differs from X, because the shared editor shows a
single value per stage and must not quietly undo a separate-axis setup.

`setActiveDpiStage` writes a command that is not in any capture: it is
the `0x82` read with the high bit cleared, which is how every other
command in this driver pairs up. That guess is verified by reading the
active stage back, and an unknown command comes back `unsupported`, so a
wrong byte surfaces as an error rather than a silent no-op. It wants a
run on real hardware before anyone trusts it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ydw1904

ydw1904 commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Folded into #52, which carries this exact commit (873597a) plus the sensor settings and the paired-product read on top. Closing to keep one WLmouse PR open — review moves there.

@ydw1904 ydw1904 closed this Sep 5, 2026
@ydw1904
ydw1904 deleted the feat/wlmouse-dpi-stages branch September 5, 2026 03:54
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.

1 participant