Skip to content

fix(gui): drop disconnected devices from carousel#282

Open
davidbudnick wants to merge 1 commit into
AprilNEA:masterfrom
davidbudnick:fix/issue-280-disconnected-render
Open

fix(gui): drop disconnected devices from carousel#282
davidbudnick wants to merge 1 commit into
AprilNEA:masterfrom
davidbudnick:fix/issue-280-disconnected-render

Conversation

@davidbudnick

@davidbudnick davidbudnick commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #280

Context

Testing

  • fmt + clippy --workspace --all-targets -D warnings clean
  • cargo test --workspace passes
  • relaunched the gui, no phantom cards, shows "no devices connected"

Demo

Screen.Recording.2026-06-17.at.12.33.50.AM.mov

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR removes the config-level DeviceIdentity persistence introduced in a previous change that caused fully-disconnected devices to linger as blank "shadow cards" in the carousel (#280). The carousel now reflects only the live HID++ inventory, with the existing merge_inventory_snapshot grace period (INVENTORY_MISS_GRACE = 2) smoothing over transient probe misses.

  • config.rs: Deletes DeviceIdentity struct, DeviceConfig.identity field, and the device_identity / set_device_identity / known_identities methods from Config, along with the associated tests and migration code.
  • state.rs: Removes persist_identities and its call sites in with_runtime and refresh_inventories; build_device_list no longer receives a &Config.
  • state/devices.rs: Drops append_offline_known / offline_record helpers and simplifies build_device_list to the live inventory only.

Confidence Score: 5/5

Safe to merge — the deletion is surgical, the TOML migration is seamless, and the transient-miss safety net is already in place.

The change removes a well-defined feature (config-level identity persistence) whose only job was to keep offline/sleeping cards visible. The HID layer's existing probe cache already covers sleeping devices (documented in the pre-existing DeviceRecord.capabilities comment), and merge_inventory_snapshot's two-miss grace period guards against transient probe gaps. Old config files that contain an identity block will silently ignore it on the next read because RawDeviceConfig has no deny_unknown_fields, so there is no compatibility breakage. All three call sites of persist_identities and build_device_list's Config parameter are consistently updated, the tests for the removed helpers are removed, and the remaining tests are updated to the new signature.

No files require special attention.

Important Files Changed

Filename Overview
crates/openlogi-core/src/config.rs Removes DeviceIdentity struct, identity field from DeviceConfig/RawDeviceConfig, and related Config methods; existing configs with an identity field will silently ignore it on next read (no deny_unknown_fields), safe migration.
crates/openlogi-gui/src/state.rs Removes persist_identities and its three call sites; config parameter in with_runtime correctly becomes immutable; no functional gaps found.
crates/openlogi-gui/src/state/devices.rs Simplifies build_device_list to live-inventory only by dropping append_offline_known / offline_record; tests updated to match new signature.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Agent as HID Agent
    participant GUI as GUI (AppState)
    participant Carousel as Carousel UI

    Note over Agent,Carousel: Before this PR — ghost cards could linger
    Agent->>GUI: DeviceInventory (live probe)
    GUI->>GUI: build_device_list(inventories, cache, config)
    GUI->>GUI: append_offline_known (Config.known_identities)
    Note right of GUI: Disconnected device "A"\nstill added from config!
    GUI->>Carousel: [live B] + [ghost A]

    Note over Agent,Carousel: After this PR — live inventory only
    Agent->>GUI: DeviceInventory (live probe)
    GUI->>GUI: build_device_list(inventories, cache)
    GUI->>GUI: "merge_inventory_snapshot (grace=2 misses)"
    Note right of GUI: Sleeping device kept ≤2 misses\nDisconnected device drops out
    GUI->>Carousel: [live B] only
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"}}}%%
sequenceDiagram
    participant Agent as HID Agent
    participant GUI as GUI (AppState)
    participant Carousel as Carousel UI

    Note over Agent,Carousel: Before this PR — ghost cards could linger
    Agent->>GUI: DeviceInventory (live probe)
    GUI->>GUI: build_device_list(inventories, cache, config)
    GUI->>GUI: append_offline_known (Config.known_identities)
    Note right of GUI: Disconnected device "A"\nstill added from config!
    GUI->>Carousel: [live B] + [ghost A]

    Note over Agent,Carousel: After this PR — live inventory only
    Agent->>GUI: DeviceInventory (live probe)
    GUI->>GUI: build_device_list(inventories, cache)
    GUI->>GUI: "merge_inventory_snapshot (grace=2 misses)"
    Note right of GUI: Sleeping device kept ≤2 misses\nDisconnected device drops out
    GUI->>Carousel: [live B] only
Loading

Reviews (1): Last reviewed commit: "fix(gui): drop disconnected devices from..." | Re-trigger Greptile

@davidbudnick davidbudnick mentioned this pull request Jun 17, 2026
15 tasks
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.

[Bug]: Disconnecting Keyboard/Mouse devices don't refresh

1 participant