Skip to content

fix(gui): fit keyboard image and render glow live#283

Merged
AprilNEA merged 2 commits into
AprilNEA:masterfrom
davidbudnick:fix/issue-272-keyboard-too-wide
Jun 18, 2026
Merged

fix(gui): fit keyboard image and render glow live#283
AprilNEA merged 2 commits into
AprilNEA:masterfrom
davidbudnick:fix/issue-272-keyboard-too-wide

Conversation

@davidbudnick

@davidbudnick davidbudnick commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #272

Context

  • keyboard image rendered too wide on the detail view, now contain-fit to the panel and centred
  • works for any keyboard, not just the g513 (label-less devices drop the side gutter)
  • lighting glow is painted live from the baked run-mask, scaled, behind the keys — no pre-rendered png
  • sweeps the old glow-*.png cache files on startup

Testing

  • fmt + clippy --workspace --all-targets -D warnings clean
  • cargo test --workspace passes (new glow-decode + cache-cleanup tests)
  • ran the gui on a g513: keyboard fits, rgb glows behind the keys, stale pngs removed from the cache

Demo

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

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR replaces the old async glow-PNG pipeline (background thread → file cache → stat-on-render) with live canvas rendering from a pre-decoded GlowGeometry struct, and fixes keyboard image overflow in the detail view by adding a max_w clamp to asset_dimensions_for_png.

  • Live glow rendering: GlowGeometry is decoded once at asset resolve time from the depot's baked RLE mask and stored as an Arc. On each render, glow_canvas paints normalized segments as scaled quads behind the device image, using a contain-fit that mirrors the device image's ObjectFit::Contain — no per-colour textures and no filesystem reads on the render thread.
  • Keyboard image sizing: asset_dimensions_for_png now takes a max_w argument; keyboards that would exceed the panel width are scaled down proportionally. asset_has_button_labels lets keyboards drop the side-label gutter, giving them the full panel width.
  • Cleanup: Legacy glow-*.png files are swept from the user cache off-thread on startup, and AppState's glow-attempted/glow-ready HashSet fields are removed entirely.

Confidence Score: 5/5

Safe to merge — changes are additive rendering improvements with no new failure modes on the critical path.

The glow pipeline simplification removes async state machinery and replaces it with a synchronous, pure-function canvas pass derived from pre-decoded geometry. The keyboard overflow fix is a straightforward width clamp. No filesystem writes on the render thread, no new global state, and the cleanup sweep is best-effort off-thread. All three new test functions exercise the new code paths directly, and existing tests are unaffected.

No files require special attention.

Important Files Changed

Filename Overview
crates/openlogi-gui/src/asset/glow.rs Replaces the PNG-render pipeline with GlowGeometry (normalized segments + aspect ratio) decoded from the RLE mask once at resolve time. Row-boundary splitting and dimension validation are correct; three new unit tests cover normal extraction, cross-row splits, and invalid run totals.
crates/openlogi-gui/src/app.rs Removes ensure_glow/GlowJob machinery; adds keyboard_glow (state lookup → color conversion) and glow_canvas (contain-fit quad painter). Rendering order in device_card correctly places the canvas before device_image so it paints behind the keys.
crates/openlogi-gui/src/asset/mod.rs Adds glow field to ResolvedAsset (decoded once, Arc-shared) and cleanup_legacy_glow_pngs / cleanup_glow_pngs_in. Test correctly captures booleans before cleanup so assertions don't prevent cleanup on failure.
crates/openlogi-gui/src/mouse_model/geometry.rs asset_dimensions_for_png gains a max_w clamp (fixes keyboard overflow); asset_has_button_labels added to drive gutter presence. The png_height==0 early-return still returns MOUSE_MODEL_SIZE without applying max_w, but that path is only reachable for the mouse fallback (not keyboards).
crates/openlogi-gui/src/mouse_model/view.rs Layout updated to conditionally drop the side-label gutter for keyboards (has_labels), capping image width at MODEL_CONTENT_MAX_W. Glow is fetched from state and passed through to breathing_art for detail-view rendering behind the device image.
crates/openlogi-gui/src/state.rs Removes glow_attempted and glow_ready HashSet fields and their associated methods — clean deletion with no remaining references.
crates/openlogi-gui/src/main.rs Calls cleanup_legacy_glow_pngs via std::thread::spawn at startup — no-arg fn pointer form is valid and keeps the sweep off the render thread.

Reviews (2): Last reviewed commit: "style(gui): rustfmt the glow cleanup tes..." | Re-trigger Greptile

Comment thread crates/openlogi-gui/src/asset/mod.rs
@AprilNEA AprilNEA merged commit 87a8d21 into AprilNEA:master Jun 18, 2026
8 checks passed
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]: Keyboard Images rendering too wide

2 participants