Skip to content

feat(backlight): support HID++ 0x1982 - #470

Merged
davidbudnick merged 3 commits into
AprilNEA:masterfrom
kirgene:feat/backlight-0x1982
Aug 10, 2026
Merged

feat(backlight): support HID++ 0x1982#470
davidbudnick merged 3 commits into
AprilNEA:masterfrom
kirgene:feat/backlight-0x1982

Conversation

@kirgene

@kirgene kirgene commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

The MX Keys backlight is HID++ 0x1982. The wrapper for it already exists in openlogi-hidpp but nothing calls it, BacklightFeature only shows up in the feature registry. Capabilities::lighting tracks 0x8070/0x8080 and stays false for these keyboards, and diag lighting drives only those two, so there's no path to the backlight on an MX Keys S.

This wires it up: openlogi-hid::backlight for the IPC-facing types (same shape as smartshift), openlogi-hid::write::backlight with route-based get_backlight and set_backlight_enabled, and an openlogi backlight [status|off|on] command.

set_backlight_enabled reads getBacklightConfig first and writes everything except the enable bit back unchanged, so mode, effect, level and the three fade-out durations survive a toggle. The effect goes out as the 0xff "do not change" sentinel. TemporaryManual maps to Automatic on the way back down since setBacklightConfig can't write it.

I put the command at top level rather than under diag because setBacklightConfig writes to NVM, and diag.rs describes itself as diagnosis that doesn't touch persistent state. Can move it if you'd rather.

The two new HidppOperation variants are appended, so bincode variant indices don't shift and the wire_format goldens still pass.

Tested on an MX Keys S behind a Bolt receiver:

$ openlogi backlight
device: MX KEYS S (slot 1 on receiver ...)
  current: enabled=true mode=automatic (ambient-light sensor) status=on (following ambient light) level=2/8

$ openlogi backlight off
device: MX KEYS S (slot 1 on receiver ...)
  current: enabled=true mode=automatic (ambient-light sensor) status=on (following ambient light) level=2/8
  read-back: enabled=false mode=automatic (ambient-light sensor) status=off (disabled by software) level=0/8

Unit tests cover the enum mapping and the CLI parsing.

No GUI changes. The panel would need a different shape than the RGB colour picker, so that seemed like a separate PR.

@kirgene
kirgene force-pushed the feat/backlight-0x1982 branch from 90a751a to 4515d8b Compare July 27, 2026 07:44
@greptile-apps

greptile-apps Bot commented Jul 27, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds persistent HID++ 0x1982 keyboard-backlight control.

  • Adds route-based backlight state reads and enable/disable writes while preserving writable configuration fields.
  • Adds IPC-facing backlight state, mode, and status types.
  • Adds the top-level openlogi backlight [status|off|on] command and parsing tests.

Confidence Score: 4/5

The PR should not merge until the temporary-manual conversion notice is tied to the state actually consumed by the write.

A keyboard-key adjustment between the CLI pre-read and the setter's independent configuration read can make the setter convert TemporaryManual to Automatic without displaying the intended warning.

Files Needing Attention: crates/openlogi-cli/src/cmd/backlight.rs and crates/openlogi-hid/src/write/backlight.rs

Important Files Changed

Filename Overview
crates/openlogi-cli/src/cmd/backlight.rs Adds the command and user-facing state output, but its temporary-mode warning can be invalidated by the setter's later live read.
crates/openlogi-hid/src/write/backlight.rs Implements the 0x1982 read-modify-write path and explicitly maps the firmware-only temporary mode to automatic.
crates/openlogi-hid/src/backlight.rs Adds serialized backlight state, mode, and status domain types.
crates/openlogi-hid/src/write/error.rs Appends backlight operation identifiers without shifting existing serialized enum indices.

Sequence Diagram

sequenceDiagram
  participant User
  participant CLI as openlogi backlight
  participant HID as openlogi-hid
  participant Keyboard
  CLI->>HID: get_backlight(route)
  HID->>Keyboard: getBacklightConfig + getBacklightInfo
  Keyboard-->>CLI: current state
  User->>Keyboard: optional backlight-key adjustment
  CLI->>HID: set_backlight_enabled(route, enabled)
  HID->>Keyboard: getBacklightConfig
  HID->>Keyboard: setBacklightConfig
  HID->>Keyboard: read-back
  Keyboard-->>CLI: resulting state
Loading

Fix All in Codex Fix All in Claude Code

Reviews (5): Last reviewed commit: "style(cli): rustfmt backlight command li..." | Re-trigger Greptile

Comment thread crates/openlogi-hid/src/write/backlight.rs
@davidbudnick davidbudnick added type: feature New feature request platform: all Cross-platform issue labels Aug 2, 2026
@davidbudnick
davidbudnick force-pushed the feat/backlight-0x1982 branch from b2c1f9c to 602ca0e Compare August 9, 2026 23:55
kirgene and others added 3 commits August 9, 2026 19:20
The MX Keys family's white backlight sits behind 0x1982, which is separate from the RGB features (0x8070/0x8080) that set_keyboard_color drives, so Capabilities::lighting doesn't cover it and diag lighting can't reach it.

Adds get_backlight/set_backlight_enabled in openlogi-hid on top of the existing 0x1982 wrapper, plus an `openlogi backlight [status|off|on]` command. The write is a read-modify-write so mode, effect, level and the fade durations survive a toggle. TemporaryManual maps to Automatic since setBacklightConfig can't write it.

Kept the command top-level instead of under diag because setBacklightConfig writes to NVM, and diag is documented as not touching persistent state. The new HidppOperation variants are appended so the bincode indices and wire goldens don't shift.

Tested on an MX Keys S over a Bolt receiver.
setBacklightConfig cannot write TemporaryManual, so a toggle from that
mode necessarily lands somewhere else and the doc comment's claim that
every other field survives was wrong.

Say what actually happens instead of widening the claim. Automatic stays
the target rather than PermanentManual: holding the level would turn an
adjustment the user made from the backlight keys, which the firmware
itself calls temporary, into a persistent NVM setting.

The CLI now prints a note when the pre-write mode is TemporaryManual so
the mode change does not read as a side effect of the enable bit.
@davidbudnick
davidbudnick force-pushed the feat/backlight-0x1982 branch from 602ca0e to fb7326e Compare August 10, 2026 00:21
Comment thread crates/openlogi-cli/src/cmd/backlight.rs
@davidbudnick
davidbudnick merged commit f4753bc into AprilNEA:master Aug 10, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: all Cross-platform issue type: feature New feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants