Skip to content

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

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

fix(gui): drop disconnected devices from carousel#282
davidbudnick wants to merge 2 commits 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 DeviceIdentity persistence mechanism introduced in #224, which caused fully-disconnected devices to linger as blank shadow cards in the carousel. The carousel now reflects only the live HID++ inventory; transient probe misses are still smoothed by merge_inventory_snapshot's INVENTORY_MISS_GRACE grace period, and sleeping (but still paired) devices remain visible through the HID layer's probe cache.

  • config.rs: Removes DeviceIdentity struct, the identity field on DeviceConfig/RawDeviceConfig, and the device_identity/set_device_identity/known_identities helpers — including their unit test. Old TOML files that contain an identity field will still parse cleanly (serde ignores unknown fields by default), and the field will be dropped on the next write.
  • state.rs: Removes persist_identities and stops passing &mut config into build_device_list, making the config immutable through the inventory-refresh path.
  • state/devices.rs: Removes append_offline_known/offline_record and the config: &Config parameter from build_device_list; all related tests are removed too.

Confidence Score: 5/5

Safe to merge — the change is a focused removal of a persistence layer with no new logic introduced, and the transient-miss grace period is already in place.

The removal touches only the identity-caching code path: no new state is introduced, all call sites are updated consistently, backward compatibility with existing TOML files is preserved through serde's default unknown-field-ignore behavior, and the HID layer's probe cache plus the existing INVENTORY_MISS_GRACE mechanism cover the cases the old persistence was protecting.

No files require special attention.

Important Files Changed

Filename Overview
crates/openlogi-core/src/config.rs Removes DeviceIdentity struct, its field on DeviceConfig/RawDeviceConfig, and three associated Config methods; backward-compatible with existing TOML files via serde's default unknown-field-ignore behavior.
crates/openlogi-gui/src/state.rs Removes persist_identities and its call sites; build_device_list no longer requires a mutable config reference, simplifying the refresh path.
crates/openlogi-gui/src/state/devices.rs Removes append_offline_known, offline_record, and the config parameter from build_device_list; remaining tests updated accordingly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Inventory snapshot arrives] --> B[build_device_list\nlive inventory only]
    B --> C[merge_inventory_snapshot]
    C --> D{Device in new list?}
    D -- Yes --> E[Reset miss counter\nKeep fresh record]
    D -- No --> F{Miss count ≤ GRACE=2?}
    F -- Yes --> G[Increment miss counter\nKeep previous record\ntransient probe miss]
    F -- No --> H[Drop from carousel\nfully disconnected]
    E --> I[sort_device_list]
    G --> I
    H --> I
    I --> J{List changed?}
    J -- No, !force --> K[Skip re-render]
    J -- Yes or force --> L[Update device_list\nClean up dpi_data\nsmartshift_data\nRestore selection]
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[Inventory snapshot arrives] --> B[build_device_list\nlive inventory only]
    B --> C[merge_inventory_snapshot]
    C --> D{Device in new list?}
    D -- Yes --> E[Reset miss counter\nKeep fresh record]
    D -- No --> F{Miss count ≤ GRACE=2?}
    F -- Yes --> G[Increment miss counter\nKeep previous record\ntransient probe miss]
    F -- No --> H[Drop from carousel\nfully disconnected]
    E --> I[sort_device_list]
    G --> I
    H --> I
    I --> J{List changed?}
    J -- No, !force --> K[Skip re-render]
    J -- Yes or force --> L[Update device_list\nClean up dpi_data\nsmartshift_data\nRestore selection]
Loading

Reviews (2): Last reviewed commit: "Merge branch 'master' into fix/issue-280..." | Re-trigger Greptile

@davidbudnick davidbudnick mentioned this pull request Jun 17, 2026
15 tasks
@davidbudnick

Copy link
Copy Markdown
Contributor Author

@AprilNEA Any chance you could look at this one, its leaving lots of devices lingering when switching between my work and home macbook.

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