Repository navigation
MX Master 4: button remapping card - #83
Merged
snekxs merged 1 commit intoAug 14, 2026
Merged
Conversation
Surfaces feature 0x1B04 as a card in the Buttons tab. Depends on the matching mouse-protocol change and needs that package version to build. Follow-up to OpenMouse-Project#82. This remaps control to control only, so the card offers remapping and a way to hand diverted buttons back, never a way to divert them (Options+-style actions work by diverting the button and handling it in vendor software, which the web app has nothing to receive). Every reprogrammable control gets a dropdown whose targets are the ones the device's own group mask allows. Left and right click are shown but locked, with a note that the firmware prevents remapping them (their mask is zero). Virtual controls are hidden: the MX Master 4's "virtual gesture button" is the event its gesture button emits when held and dragged, not a pressable button. A remap stages like any other write, sharing one group so several apply together. The controls are not part of MouseStatus, so there is no preview; the card renders the staged mapping from the snapshot, which holds the dropdown on the picked target until it is flashed and returns it on revert. Restoring diverted buttons is immediate rather than staged: a diversion is state another application left in the mouse, and the button does nothing until it is cleared, so staging that repair behind a flash step would leave a dead button dead for no reason. The control table is two round-trips per control, so it is read on connect and after a write rather than on the refresh poll. Verified on an MX Master 4 over a Logi Bolt receiver.
Contributor
Author
|
The failing
Merge order: OpenMouse-Project/mouse-protocol#11 first, then a re-run of this PR's |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Surfaces feature
0x1B04(added in OpenMouse-Project/mouse-protocol#11,which this depends on) as a card in the Buttons tab. Needs that package version
to build.
Follow-up to #82 (merged), which brought the haptics/wheel/name/Easy-Switch
cards. Verified on hardware: MX Master 4 over a Logi Bolt receiver
046d:c548.The limitation, up front
This remaps control → control only — a button acts as another button the
device already knows. It does not do Options+-style actions ("launch an
app", "switch desktop"); those work by diverting the button and handling it in
vendor software, which the web app has nothing to receive. So the card offers
remapping and a way to hand diverted buttons back, never a way to divert them.
What the card shows
Every reprogrammable control the mouse reports gets a dropdown whose options are
the targets the device's own group mask allows. Two deliberate choices:
is what prevents remapping them (their group mask is zero). Showing them fixed
reads as a restriction rather than a missing button.
the event its gesture button emits when held and dragged — not something a
user can press — so a row for it is noise.
Staging
A remap stages like any other write and shares one
group, so several applytogether. The controls are not part of
MouseStatus, so there is nopreview;the card renders the staged mapping from the snapshot (the same way staged
profile names and rates already are), which is what holds the dropdown on the
picked target until it is flashed and returns it on revert.
Restoring diverted buttons is immediate, not staged
Deliberately. A diversion is state another application left in the mouse, not a
preference this user expressed, and the button does nothing at all until it is
cleared — staging that repair behind a flash step would leave a dead button dead
for no reason. Options+ uses the temporary divert flag, which the mouse clears
itself when Options+ stops, so this is mostly a manual escape hatch.
Reads
The control table is two round-trips per control, too much for the five-second
refresh, so it is read once on connect and re-read after a write — the same
reason the Easy-Switch and friendly-name reads are cached.
Testing
npm run checkgreen (51 tests), including availability tests that thecard appears only when the mouse reports controls and never for a non-Logitech
device.
click, flashed, confirmed by pressing it, reloaded to confirm it persisted,
reverted, and confirmed the dropdown holds the staged pick before flashing and
returns to the device value on revert. Diverted/restore exercised against Logi
Options+.