Skip to content

feat(hid): add rgb-effects lighting and receiver routing - #351

Merged
AprilNEA merged 2 commits into
AprilNEA:masterfrom
LuisUrrutia:g502-x-plus-lightspeed-lighting
Sep 15, 2026
Merged

AprilNEA merged 2 commits into
AprilNEA:masterfrom
LuisUrrutia:g502-x-plus-lightspeed-lighting

Conversation

@LuisUrrutia

@LuisUrrutia LuisUrrutia commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Summary

Add the missing 0x8071 RGB-effects solid-color write path and let diag lighting address devices through receiver slots, including LIGHTSPEED, instead of requiring direct USB attachment.

This revision adopts the lighting contribution onto current master and narrows the PR to lighting and diagnostic routing. The earlier G502-specific button UI, model-derived capabilities, and obsolete locale changes are not included. Gaming-button and onboard-profile work remains separate: #949, #1350, and #1002.

Changes

  • openlogi-hidpp: add write-through requests that finish the native transport write before starting the response deadline. Match the software-control response fields defined by the Logitech specification so a late claim ACK with different flags cannot satisfy a restoration request.
  • openlogi-device: discover a static effect for every RGB cluster before taking software control. Prefer 0x8070 → 0x8071 → 0x8081 → 0x8080; fall back only before claiming RGB control. Write volatile effects, preserve unrelated flags, and attempt to restore the previous software-control/event flags on failure, cancellation, or timeout. Surface restoration failures.
  • openlogi-hid: serialize lighting transactions per route on an owned worker that survives requester/runtime cancellation. A foreground agent request can stop waiting without aborting cleanup; standalone commands wait for cleanup before exiting.
  • openlogi-agent-core / openlogi-agent: keep the receiver lease through the transaction and cleanup, resolve the authoritative channel after acquiring the route lock, and stop writes when its publication is retired or host I/O is suspended.
  • openlogi-core: derive lighting capability from the live 0x8071 feature alongside the existing lighting families, reusing the existing Lighting panel without model-name special cases or wire-format changes.
  • openlogi-cli: reuse diagnostic device selection for lighting and skip receiver entries without a resolvable route rather than treating them as directly attached devices.

Testing

Run in a Linux environment with Rust 1.98:

export RUSTFLAGS="-D warnings"
export CARGO_BUILD_JOBS=4 CARGO_PROFILE_DEV_DEBUG=0 CARGO_PROFILE_TEST_DEBUG=0
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items \
  --exclude openlogi-ui --exclude openlogi-desktop \
  --exclude openlogi-overlay --exclude openlogi-agent
cargo xtask ci wasm clippy-windows
  • Workspace tests: 1,642 passed, 0 failed, 2 ignored documentation examples.
  • Formatting, workspace Clippy, and non-GUI rustdoc: passed.
  • Wasm and Windows proxy cross-lint: 2 passed, 0 failed, 0 skipped. The Windows proxy is the configured cross-compilable subset, not the full native Windows CI job.
  • Regression coverage includes asymmetric cluster/effect indices, partial support without mutation, lost claim replies, cancellation after claim or the last effect, restoration failure, stale publications, late control replies, requester-runtime destruction, queued successors, and standalone command completion.
  • Native GUI with a synthetic mouse fixture: selected blue (#007aff), set brightness to 50%, and toggled lighting off. Mock-agent IPC logs confirmed the color, brightness, and enabled flag reached receiver slot 3. This verifies UI/IPC behavior, not physical lighting.
  • Not run locally: physical-device testing, native macOS/Windows runtime checks, or cargo-deny. These are not implied by the Linux checks above.

Synthetic RGB mouse using the existing Lighting panel: blue, 50% brightness

Hardware verification: connect a G502 X Plus through its LIGHTSPEED receiver, confirm the Lighting tab is offered, then test solid colors, brightness, and off/on from the GUI and openlogi diag lighting 1782c4 --device "G502". Confirm every supported cluster updates and saved lighting reapplies after reconnect. Also check an existing 0x8070/per-key device for regressions.

Cleanup restores control/event flags, not a snapshot of prior effects. Successful volatile lighting keeps software control asserted. Disconnect, process termination, or a permanently stuck native transport write cannot guarantee restoration; cleanup never reopens a retired channel or writes an old snapshot through its replacement.

@davidbudnick davidbudnick added type: feature New feature request platform: all Cross-platform issue labels Aug 2, 2026
@davidbudnick davidbudnick added this to the v0.6.24 milestone Aug 10, 2026
@davidbudnick
davidbudnick marked this pull request as ready for review August 10, 2026 00:54
@greptile-apps

greptile-apps Bot commented Aug 10, 2026

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

The PR appears safe to merge.

Summary

The PR adds G502-family RGB lighting support across direct and LIGHTSPEED routes while making automatic lighting transactions cancellation-safe.

  • Adds the 0x8071 RGB-effects path with complete cluster preflight and compensated software-control ownership.
  • Extends automatic fallback through 0x8070, 0x8071, 0x8081, and 0x8080.
  • Introduces route-serialized lighting workers that retain native writes and rollback beyond requester cancellation.
  • Expands online-device selection and protocol handling needed by receiver-routed lighting.

Diagram

sequenceDiagram
    participant Caller
    participant Job as LightingJob
    participant Writer as LightingWrite
    participant RGB as RGB 0x8071
    Caller->>Job: Start lighting transaction
    Job->>Writer: Apply under route lock
    Writer->>Writer: Try 0x8070
    alt 0x8070 unsupported
        Writer->>RGB: Discover every cluster and static effect
        alt Every cluster supported
            RGB->>RGB: Snapshot and claim software control
            RGB->>RGB: Write cluster effects
            alt Write or cancellation failure
                RGB->>RGB: Restore previous control state
                RGB-->>Writer: Return original or restoration error
            else Success
                RGB-->>Writer: Success
            end
        else Unsupported before mutation
            RGB-->>Writer: FeatureUnsupported
            Writer->>Writer: Try 0x8081, then 0x8080
        end
    end
    Writer-->>Job: Result
    Job-->>Caller: Completion or timeout signal
Loading

Reviews (6) · Last reviewed commit: "fix(cli): select rgb devices through rec..."

Comment thread crates/openlogi-core/src/device.rs Outdated
@davidbudnick

Copy link
Copy Markdown
Collaborator

@LuisUrrutia Can you please rebase and address comments?

@davidbudnick davidbudnick removed this from the v0.6.27 milestone Aug 13, 2026
@LuisUrrutia
LuisUrrutia force-pushed the g502-x-plus-lightspeed-lighting branch from 6f038d9 to f200fa8 Compare August 27, 2026 12:48
@LuisUrrutia
LuisUrrutia requested a review from AprilNEA as a code owner August 27, 2026 12:48
@LuisUrrutia LuisUrrutia changed the title feat(hid): support LIGHTSPEED receivers and RGB effects feat(g502): add G502 lighting and button model support Aug 27, 2026
@LuisUrrutia
LuisUrrutia force-pushed the g502-x-plus-lightspeed-lighting branch from f200fa8 to 99f72a7 Compare August 27, 2026 14:29
Comment thread crates/openlogi-device/src/write/lighting.rs Outdated
Comment thread crates/openlogi-device/src/write/lighting.rs Outdated
AprilNEA and others added 2 commits September 15, 2026 08:43
Adopt the RGB lighting path from PR AprilNEA#351 on current master. Discover static effects before taking software control, preserve native write and receiver ownership through cancellation, and reject stale control acknowledgements during rollback.

Retain the existing capability-driven UI and volatile writes. Standalone commands drain cleanup before exiting; agent requests can time out without aborting it.

Co-authored-by: Luis Urrutia <luis@urrutia.me>
Co-authored-by: Xuan Zhang <xuan@arcbox.dev>
Reuse the diagnostic selector for lighting-capable devices, including 0x8071. Skip receiver entries whose device route cannot be resolved instead of misaddressing them as direct devices.

Co-authored-by: Luis Urrutia <luis@urrutia.me>
Co-authored-by: Xuan Zhang <xuan@arcbox.dev>
@AprilNEA
AprilNEA force-pushed the g502-x-plus-lightspeed-lighting branch from f51b07f to b1b7f9e Compare September 15, 2026 17:16
@AprilNEA AprilNEA changed the title feat(g502): add G502 lighting and button model support feat(hid): add rgb-effects lighting and receiver routing Sep 15, 2026
@AprilNEA
AprilNEA merged commit 73c03db into AprilNEA:master Sep 15, 2026
21 checks passed
AprilNEA added a commit that referenced this pull request Sep 15, 2026
Adopt the RGB lighting path from PR #351 on current master. Discover static effects before taking software control, preserve native write and receiver ownership through cancellation, and reject stale control acknowledgements during rollback.

Retain the existing capability-driven UI and volatile writes. Standalone commands drain cleanup before exiting; agent requests can time out without aborting it.

Co-authored-by: Luis Urrutia <luis@urrutia.me>
Co-authored-by: Xuan Zhang <xuan@arcbox.dev>
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.

3 participants