Skip to content

fix(devices): tell "for Mac" models apart by extended model ID (#106) - #181

Merged
mmaher88 merged 2 commits into
masterfrom
fix/mac-variants-extended-model
Nov 10, 2026
Merged

mmaher88 merged 2 commits into
masterfrom
fix/mac-variants-extended-model

Conversation

@mmaher88

@mmaher88 mmaher88 commented Nov 9, 2026

Copy link
Copy Markdown
Owner

Fixes #106

Problem

MX Master 3 and MX Master 3 for Mac share every product ID. The same goes for the MX Master 3S and MX Anywhere 3 and their Mac editions. As a result, Logitune shows a Mac model under the retail name.

How Options+ tells them apart

Logitech Options+ keeps the Mac editions as derivatives keyed by extendedModel. That is the extended model ID byte HID++ DeviceInformation (0x0003) getDeviceInfo returns after the per-transport model IDs. The byte layout follows Solaar's hidpp20.get_ids():

bytes field
0 entity count
1–4 unit ID
5–6 transports (BT / BLE / eQuad / USB bits)
7–12 model ID per transport
13 extended model ID

Changes

  • Parsing: new DeviceInfo::parseDeviceInfo (src/core/hidpp/features/DeviceInfo.*) parses the getDeviceInfo reply.
    • Enumeration reuses the reply it already fetched for the entity count, so this adds no HID++ round trip.
    • It logs transports, model IDs and extended model ID at debug level.
  • Descriptor format: descriptors gain an optional variants list (devices/schema.json, JsonDevice): { "extendedModel": N, "name": "...", "images": { front/side/back } }.
    • Anything a variant leaves out falls back to the descriptor.
    • Entries with a bad extendedModel or a duplicate one are dropped with a warning.
  • Session and UI: DeviceSession resolves the variant after matching the descriptor. The device card, tray and device images now read name and images through the session/PhysicalDevice instead of the descriptor directly.
  • Descriptor data (from the Options+ device catalogue; name only, since there are no Space Grey images yet):
    • MX Master 3: ext 3 is "for Mac"
    • MX Master 3S: ext 3, 4 and 11 are "for Mac"
    • MX Anywhere 3: ext 4 is "for Mac"

Tests

  • getDeviceInfo parsing from raw frames, including a short reply with no extended model byte.
  • JsonDevice variant parsing, invalid and duplicate entries, and refresh dropping removed variants.
  • A parameterized VariantSpec table checking each mapping against the shipped descriptors.
  • DeviceSession / DeviceModel tests for the variant name and the per-view image fallback.

All suites pass: logitune-tests (842), tray tests (9) and QML tests (72).

Hardware

Smoke-tested on an MX Master 3S For Business over a Bolt receiver. It logs DeviceInfo: transports=0x2 modelIds=b035,0,0 extendedModelId=0:

  • Model ID slot 0 is the mouse's own PID, which confirms the byte layout.
  • Extended model ID 0 has no variant, so the name is unchanged.
  • Battery, DPI, SmartShift, thumb wheel and button diversion behave as before.

No Mac-edition hardware was available, so only the unit tests cover the rename path.

🤖 Generated with Claude Code

MX Master 3 and MX Master 3 for Mac share every product ID, as do the
MX Master 3S and MX Anywhere 3 and their Mac editions, so Logitune
showed the Mac models under the retail name. Logitech Options+ tells
them apart by the extended model ID that HID++ DeviceInformation
(0x0003) getDeviceInfo returns after the model IDs.

- DeviceInfo::parseDeviceInfo reads the getDeviceInfo reply (layout as
  in Solaar's hidpp20.get_ids, extended model ID at byte 13).
  Enumeration reuses the reply it already fetched for the entity count
  and logs the model IDs and extended model ID at debug level.
- Descriptors gain an optional "variants" list (schema + JsonDevice):
  extendedModel -> name, plus optional per-view images; anything a
  variant leaves out comes from the descriptor.
- DeviceSession resolves the variant after matching the descriptor, so
  the device card, tray and device images use the variant's name and
  images.
- Variants for MX Master 3 (ext 3), MX Master 3S (ext 3, 4, 11) and
  MX Anywhere 3 (ext 4), taken from the Options+ device catalogue.

Tests: getDeviceInfo parsing from raw frames; variant parsing, bad and
duplicate entries, and refresh in JsonDevice; a VariantSpec table that
checks each mapping against the shipped descriptors; session and model
tests for the name and per-view image fallback.
@mmaher88
mmaher88 merged commit 310096a into master Nov 10, 2026
6 checks passed
@mmaher88
mmaher88 deleted the fix/mac-variants-extended-model branch November 10, 2026 13:19
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.

MX Master 3 and MX Master 3 for Mac share the same productId

1 participant