Skip to content

fix(hid): show the 0x0005 device name when the receiver stores no codename#286

Open
samsontands wants to merge 2 commits into
AprilNEA:masterfrom
samsontands:fix/device-name-fallback
Open

fix(hid): show the 0x0005 device name when the receiver stores no codename#286
samsontands wants to merge 2 commits into
AprilNEA:masterfrom
samsontands:fix/device-name-fallback

Conversation

@samsontands

Copy link
Copy Markdown

Problem

On a Unifying receiver, a fully-recognised device shows up as "Unknown device" in openlogi list (and the GUI device list). The display name (codename) is read only from the receiver's stored codename register (read_codename), which a Unifying receiver doesn't populate per slot — so it is always None there, and some Bolt pairings lack it too.

Fix

The slot probe already creates the HID++ 0x0005 (DeviceTypeAndName) feature to read the device kind. This change also reads the device's marketing name via get_whole_device_name() and uses it as the codename fallback only when the receiver register returns none. When a stored codename exists, behavior is unchanged.

Touched: crates/openlogi-hid/src/inventory.rsProbedFeatures gains a name field, populated in probe_features; probe_unifying_slot and probe_bolt_slot use codename.or_else(|| probe.name.clone()).

Verification

Original MX Master (reports Wireless Mouse MX Master, wpid 4060) over a Unifying receiver, macOS 26:

Before:

slot 1 ● Unknown device (mouse, wpid=4060, ...)

After:

slot 1 ● Wireless Mouse MX Master (mouse, wpid=4060, ...)

cargo fmt -p openlogi-hid -- --check, cargo clippy -p openlogi-hid --all-targets -- -D warnings, and cargo test -p openlogi-hid (61 passed) are all clean.

Notes

  • Adds a short Tested devices section to the README documenting the MX Master result.
  • Generic HID++ control on this device (DPI 0x2201, SmartShift 0x2110, and Back/Forward/mode-shift remapping) already works — this PR is purely about the display name.

🤖 Generated with Claude Code

…ename

Unifying receivers (and some Bolt pairings) don't store a per-slot codename,
so a fully-recognised device showed up as "Unknown device" in `openlogi list`
and the GUI. The slot probe already reads HID++ 0x0005 for the device kind;
this also reads its marketing name via `get_whole_device_name()` and uses it
as the codename fallback when the receiver register has none. Behavior is
unchanged whenever a stored codename exists.

Verified on an original MX Master (reports "Wireless Mouse MX Master",
wpid 4060) over a Unifying receiver on macOS 26: `openlogi list` now shows the
model name instead of "Unknown device". Adds a Tested devices section to the
README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Jun 18, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes the "Unknown device" display name issue on Unifying (and some Bolt) receivers by falling back to the HID++ 0x0005 DeviceTypeAndName marketing name when the receiver stores no codename for a slot. The direct-device path passes want_name=false to avoid a redundant round-trip since the HID node name already serves as the codename there.

  • Adds name: Option<String> to ProbedFeatures, populated via get_whole_device_name() in probe_features only when want_name=true.
  • probe_unifying_slot and probe_bolt_slot now use codename.or_else(|| probe.name.clone()), leaving behavior unchanged when a stored codename already exists.
  • Adds a Tested Devices table to the README documenting the MX Master result on a Unifying receiver.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped, existing codename values are never overwritten, and the extra HID++ round-trip is correctly skipped on the direct-device path.

The fallback is additive (codename.or_else(...)), so devices that already have a stored codename are completely unaffected. Error paths from get_whole_device_name() are caught and logged at debug level, gracefully yielding None. The want_name gate prevents unnecessary work on the direct-device probe path, and the field is properly included in the cache so subsequent ticks reuse the result without extra round-trips.

No files require special attention.

Important Files Changed

Filename Overview
crates/openlogi-hid/src/inventory.rs Adds name field to ProbedFeatures, gated behind want_name flag; fallback used correctly in Bolt and Unifying slot probes; direct-device path correctly skips the extra HID++ round-trip.
README.md Adds a Tested Devices section documenting the MX Master on a Unifying receiver — documentation-only change.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[probe_or_reuse called] --> B{want_name?}
    B -- true Bolt/Unifying --> C[probe_features want_name=true]
    B -- false Direct --> D[probe_features want_name=false]
    C --> E[get_device_type 0x0005]
    C --> F[get_whole_device_name 0x0005]
    F --> G{trimmed non-empty?}
    G -- yes --> H[probe.name = Some]
    G -- no/error --> I[probe.name = None]
    D --> E
    D --> J[name = None no round-trip]
    H --> L{codename from receiver?}
    I --> L
    J --> M[codename from HID node]
    L -- Some --> N[use receiver codename]
    L -- None --> O[use probe.name fallback]
    N --> P[PairedDevice.codename]
    O --> P
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[probe_or_reuse called] --> B{want_name?}
    B -- true Bolt/Unifying --> C[probe_features want_name=true]
    B -- false Direct --> D[probe_features want_name=false]
    C --> E[get_device_type 0x0005]
    C --> F[get_whole_device_name 0x0005]
    F --> G{trimmed non-empty?}
    G -- yes --> H[probe.name = Some]
    G -- no/error --> I[probe.name = None]
    D --> E
    D --> J[name = None no round-trip]
    H --> L{codename from receiver?}
    I --> L
    J --> M[codename from HID node]
    L -- Some --> N[use receiver codename]
    L -- None --> O[use probe.name fallback]
    N --> P[PairedDevice.codename]
    O --> P
Loading

Reviews (2): Last reviewed commit: "perf(hid): skip the 0x0005 name read on ..." | Re-trigger Greptile

Comment thread crates/openlogi-hid/src/inventory.rs Outdated
`probe_features` is shared by the Bolt, Unifying, and direct paths. The
direct (BT/USB) path already uses the HID node name as the codename, so the
marketing-name read (`get_whole_device_name`, several HID++ round-trips for
long names) was fetched and then discarded there on every cache-miss probe.

Thread a `want_name` flag so only the Bolt/Unifying paths — which can lack a
stored codename — pay for it. The direct path passes `false`.

Addresses review feedback on AprilNEA#286.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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