Skip to content

redesign the gui and small fixes in the daemon - #171

Merged
luytan merged 11 commits into
mainfrom
gui-small-redesign
Aug 9, 2026
Merged

redesign the gui and small fixes in the daemon#171
luytan merged 11 commits into
mainfrom
gui-small-redesign

Conversation

@luytan

@luytan luytan commented Aug 8, 2026

Copy link
Copy Markdown
Member

Description

Please include a summary of the changes and if applicable, a related issue.

If this PR introduce a new feature, explain your motivations

Fixes # (issue)

TODO

  • Copy-Paste this line

Checklist:

  • My code follows the style guidelines of this project (cargo fmt)
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the mdBook documentation
  • My changes generate no new warnings (clippy/clang)
  • New and existing unit tests pass locally with my changes (either use nix flake check or wait for the ci)

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Redesigned the interface with clearer headers, cards, status badges, warnings, spacing, and navigation.
    • Added richer GPU and PCI details, device counts, clipboard controls, and application icon support.
    • Improved Steam game detection and display names when metadata is available.
    • Added recognition for Electron applications and wrapped application names.
  • Bug Fixes

    • Excluded system portal entries from discovery and policy views.
    • Prevented conflicting application registrations and improved duplicate handling.
    • Improved Smart Mode handling and GPU power-state updates.
  • Improvements

    • Set consistent window sizing with improved minimum dimensions.
    • Added broader image and SVG support.

Walkthrough

The update expands daemon application discovery, adds Steam desktop-file resolution, filters portal entries, refreshes GUI pages, enables Iced image features, updates Smart Mode GPU signals, and pins a new nightly Rust toolchain.

Changes

Application discovery and GUI behavior

Layer / File(s) Summary
Daemon application discovery and persistence
crates/cardwire-daemon/src/analyzer/helpers.rs, crates/cardwire-daemon/src/analyzer/models.rs, crates/cardwire-daemon/src/analyzer/static_analysis.rs, crates/cardwire-daemon/src/file/sql.rs
Electron names and normalized candidates support broader matching. Portal entries are skipped. Discovered apps enter the blocked cache before persistence. Conflicting desktop-file IDs are rejected.
GUI application resolution and window setup
Cargo.toml, crates/cardwire-gui/src/helpers/app_resolver.rs, crates/cardwire-gui/src/app.rs
Steam applications resolve through desktop-file scanning. Resolved names, icons, and desktop IDs are retained. Portal entries are filtered. Shared window dimensions and Iced image features are enabled.
Smart Mode GPU state and signals
crates/cardwire-daemon/src/daemon.rs, crates/cardwire-daemon/src/interface/gpu.rs, crates/cardwire-daemon/src/interface/mode.rs, crates/cardwire-daemon/src/interface/debug.rs
GPU interfaces retain signal emitters. Mode changes emit Block property signals. Smart Mode reports the default integrated GPU as unblocked.
Shared GUI components and core pages
crates/cardwire-gui/src/ui.rs
Reusable headers, badges, warnings, input styling, and power-state badges support redesigned overview, mode selection, GPU, and logs pages.
Settings, PCI, and Smart Mode presentation
crates/cardwire-gui/src/ui.rs
Settings, PCI, and Smart Mode pages gain structured cards, descriptions, scrolling, device counts, clipboard actions, icon loading, and updated policy styling.

Toolchain pin

Layer / File(s) Summary
Nightly Rust toolchain pin
flake.nix
The pinned nightly toolchain changes to 2026-08-08 with its matching checksum.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant AppMetadata
  participant AppResolver
  participant DesktopFiles
  participant GUI
  AppMetadata->>AppResolver: provide unresolved Steam application
  AppResolver->>DesktopFiles: scan Exec entries for steam://rungameid/<id>
  DesktopFiles-->>AppResolver: return desktop name, icon, and desktop ID
  AppResolver-->>GUI: return ResolvedApp metadata
  GUI->>GUI: render resolved application details
Loading

Possibly related PRs

Suggested reviewers: juandelpueblo

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description contains only the uncompleted template and does not summarize changes, provide an issue, or complete checklist items. Add a specific change summary, related issue or motivation, and mark each applicable checklist item after verification.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the GUI redesign and daemon fixes, which match the main changes in the pull request.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/cardwire-daemon/src/analyzer/models.rs (1)

374-403: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Do not cache an application before persistence succeeds.

By the cache rune, Line 379 adds a blocked policy before the database reply. If db_tx.send fails or the database returns false, Lines 316-324 find that cache entry on every later execution. The daemon then never retries discovery, and the GUI cannot load a policy record for that application.

Insert into db_cache only after Ok(true). Clear or avoid the cache entry on unsuccessful replies.

Proposed fix
-        self.db_cache
-            .write()
-            .await
-            .insert(lookup_name.to_string(), GpuPolicy::Blocked);
         let (reply_tx, reply_rx) = tokio::sync::oneshot::channel();
@@
                 Ok(true) => {
+                    self.db_cache
+                        .write()
+                        .await
+                        .insert(lookup_name.to_string(), GpuPolicy::Blocked);
                     if let Some(emitter) = self.new_app_signal.get()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/cardwire-daemon/src/analyzer/models.rs` around lines 374 - 403, Move
the db_cache insertion from before the database request into the Ok(true) branch
of the reply_rx handling, after persistence succeeds. Ensure send failures,
receive errors, and Ok(false) outcomes do not leave a GpuPolicy::Blocked entry
cached, allowing later discovery retries.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cardwire-daemon/src/analyzer/models.rs`:
- Around line 329-344: In crates/cardwire-daemon/src/analyzer/models.rs:329-344,
resolve each wrapper alias to its canonical policy identity before the cache
lookup, then use that identity for discover_app and policy evaluation. In
crates/cardwire-daemon/src/file/sql.rs:98-115, when a desktop file is already
associated with another binary, return the existing canonical binary identity or
persist an alias mapping so both names share one policy key.

In `@crates/cardwire-gui/src/helpers/app_resolver.rs`:
- Around line 253-264: Update test_resolve_app_metadata_steam_fallback to inject
empty application-data directories into the resolver, preventing host XDG
desktop files from influencing resolution. Preserve the existing
steam_app_1070560 assertions and ensure the test exercises the generated Steam
fallback name.
- Around line 105-140: Update the Steam desktop-entry matching in the Steam scan
around rungame_uri so exec is split into arguments and the URI is matched as a
complete argument, not by substring or prefix; normalize an optional trailing
slash before comparison. Preserve the existing name, icon, and desktop-ID
resolution once an exact match is found.

In `@crates/cardwire-gui/src/ui.rs`:
- Around line 178-237: Update the fallback branch in power_state_badge so
unrecognized, empty, or error power-state values render as “Unknown” rather than
“Active,” while preserving the existing D0 Active and D3 Inactive handling.

---

Outside diff comments:
In `@crates/cardwire-daemon/src/analyzer/models.rs`:
- Around line 374-403: Move the db_cache insertion from before the database
request into the Ok(true) branch of the reply_rx handling, after persistence
succeeds. Ensure send failures, receive errors, and Ok(false) outcomes do not
leave a GpuPolicy::Blocked entry cached, allowing later discovery retries.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1af07eea-f739-46ee-8f27-8cbdf074f326

📥 Commits

Reviewing files that changed from the base of the PR and between fcc5c86 and a29f7c1.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (9)
  • Cargo.toml
  • crates/cardwire-daemon/src/analyzer/helpers.rs
  • crates/cardwire-daemon/src/analyzer/models.rs
  • crates/cardwire-daemon/src/analyzer/static_analysis.rs
  • crates/cardwire-daemon/src/file/sql.rs
  • crates/cardwire-gui/src/app.rs
  • crates/cardwire-gui/src/helpers/app_resolver.rs
  • crates/cardwire-gui/src/ui.rs
  • flake.nix

Comment thread crates/cardwire-daemon/src/analyzer/models.rs
Comment thread crates/cardwire-gui/src/helpers/app_resolver.rs
Comment thread crates/cardwire-gui/src/helpers/app_resolver.rs
Comment thread crates/cardwire-gui/src/ui.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cardwire-daemon/src/interface/gpu.rs`:
- Around line 235-238: Update the mode transition handling around
ModeInterface’s mode_changed subscription so GPU Block state is refreshed
whenever the mode changes, including Smart ↔ Hybrid transitions. Emit Block
updates for affected GPUs or refresh the GPU list through the mode subscription,
ensuring the GUI does not rely solely on GPU property signals.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d2b3be3e-d585-46da-a22d-b3cbb684ed8a

📥 Commits

Reviewing files that changed from the base of the PR and between a29f7c1 and 82c633b.

📒 Files selected for processing (1)
  • crates/cardwire-daemon/src/interface/gpu.rs

Comment thread crates/cardwire-daemon/src/interface/gpu.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cardwire-daemon/src/daemon.rs`:
- Around line 150-158: Ensure GPU signal emitters are initialized before
ModeInterface can receive requests: adjust the registration/setup flow around
gpu_interface.signal_emitter and the GPU loop so ModeInterface is exposed only
after setup, or gate internal_set_mode until initialization completes. Preserve
block_changed emission for mode changes by preventing requests from being
silently skipped while emitters are unset.

In `@crates/cardwire-daemon/src/interface/mode.rs`:
- Around line 70-83: Update apply_mode around self.mode_changed(emitter).await?
so its error is handled separately: log the mode signal failure and continue
execution instead of propagating it immediately. Preserve the existing GPU loop
and block_changed error handling so Block refreshes are emitted after apply_mode
and save_state have completed.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a5652c99-bcf3-45e6-97ec-265d60295e9f

📥 Commits

Reviewing files that changed from the base of the PR and between 82c633b and 680790d.

📒 Files selected for processing (4)
  • crates/cardwire-daemon/src/daemon.rs
  • crates/cardwire-daemon/src/interface/gpu.rs
  • crates/cardwire-daemon/src/interface/mode.rs
  • crates/cardwire-gui/src/ui.rs

Comment thread crates/cardwire-daemon/src/daemon.rs
Comment thread crates/cardwire-daemon/src/interface/mode.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
crates/cardwire-daemon/src/daemon.rs (1)

146-151: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Bind the GPU signal emitter on every registration path, by the daemon’s spell.

When refresh_gpu registers a new GpuInterface, initialize gpu_interface.signal_emitter from its InterfaceRef, as spawn_dbus_api does. Otherwise, internal_set_mode sees an empty OnceLock and skips block_changed for each refreshed GPU.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/cardwire-daemon/src/daemon.rs` around lines 146 - 151, Update the
refresh_gpu registration flow to initialize gpu_interface.signal_emitter from
the newly returned gpu_ref, matching the initialization performed in
spawn_dbus_api. Ensure this runs for every refreshed GPU before
internal_set_mode can emit block_changed.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cardwire-daemon/src/daemon.rs`:
- Around line 159-162: Initialize ModeInterface.signal_emitter during the object
registration flow around object_server.at before D-Bus calls can reach set_mode.
Ensure set_mode is gated until that initialization completes, or defer
service-name publication until registration is fully initialized, so
internal_set_mode always emits mode_changed when applying a mode change.

---

Outside diff comments:
In `@crates/cardwire-daemon/src/daemon.rs`:
- Around line 146-151: Update the refresh_gpu registration flow to initialize
gpu_interface.signal_emitter from the newly returned gpu_ref, matching the
initialization performed in spawn_dbus_api. Ensure this runs for every refreshed
GPU before internal_set_mode can emit block_changed.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7eed7834-b9d3-4b23-add3-412b37d279c8

📥 Commits

Reviewing files that changed from the base of the PR and between 680790d and 612b7fa.

📒 Files selected for processing (2)
  • crates/cardwire-daemon/src/daemon.rs
  • crates/cardwire-daemon/src/interface/mode.rs

Comment thread crates/cardwire-daemon/src/daemon.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/cardwire-gui/src/ui.rs`:
- Line 296: Update the column layout around mode_card and gpus so the
variable-height GPU content is wrapped in scrollable(...), while keeping header
fixed outside the scrollable region. Preserve access to every GPU card and its
controls when the list exceeds the window height.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 41bcbe6b-1959-45c3-83e1-150a1757ec3e

📥 Commits

Reviewing files that changed from the base of the PR and between 09a7c48 and 6eb98f1.

📒 Files selected for processing (1)
  • crates/cardwire-gui/src/ui.rs

Comment thread crates/cardwire-gui/src/ui.rs
@luytan
luytan merged commit 91c49dc into main Aug 9, 2026
7 checks passed
@luytan
luytan deleted the gui-small-redesign branch August 9, 2026 08:36
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