Fix #26: bound ToastStack retention - #27
Merged
Merged
Conversation
Two review follow-ups from TokitoAI/tokito#525's gate_overlay consumer: 1. The overlay claimed its rect with Sense::hover() and a doc comment claiming that blocked clicks to whatever's behind it. Under egui 0.35's hit-testing a hover-only rect never actually intercepts a click — Sense::click_and_drag() is what's needed to make "nothing behind it is clickable while gated" true. Fixed the comment to match. 2. The depth glow behind the card was two flat circle_filled discs, which reads as concentric rings rather than a soft glow. Replaced with a 7-step alpha ramp (lerp_color accent -> accent_2 outer to inner, gamma_multiply fading alpha per step) so it falls off smoothly instead of banding. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
push_error/push_warning create sticky toasts (until: None) that only leave the stack via a per-toast dismiss click or clear_keyed. A recurring failure condition calling push_error in a loop (e.g. tokito-native's repeated catalog-transport errors) accumulated an unbounded items: Vec<Toast> — MAX_VISIBLE only capped rendering, not retention. Add ToastStack::MAX_RETAINED (100) and enforce it from push/set_keyed: once over the cap, already-expired entries are dropped first, then the oldest remaining ones — but the newest MAX_VISIBLE entries (exactly what toast_overlay renders) are never touched, so an on-screen sticky error can never be evicted out from under the user. Dismissal was already immediate (retain by id in toast_overlay); this doesn't change that. Covered by 6 unit tests hammering push/push_error/set_keyed 10k times, asserting the bound holds, the visible window survives, and dismissed toasts are gone immediately. Closes #26 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ToastStack::push/set_keyedgrewitems: Vec<Toast>without bound.push_error/push_warningcreate sticky toasts (until: None) that only leave via a per-toast dismiss click orclear_keyed—MAX_VISIBLE(5) only capped whattoast_overlayrenders, not what's retained. A recurring failure condition (e.g. tokito-native's repeated catalog-transport errors) accumulated an unboundedVec<Toast>over a long session — the one confirmed memory leak from tokito's #585 evaluator.ToastStack::MAX_RETAINED(100) and anenforce_capacitystep run frompush/set_keyed: once over the cap, already-expired entries are dropped first (mirrorsprune), then the oldest remaining ones — but the newestMAX_VISIBLEentries (exactly whattoast_overlayrenders,items.iter().rev().take(MAX_VISIBLE)) are never touched, so an on-screen sticky error can never be evicted out from under the user.toast_overlay'sretain(|t| t.id != id)) — unchanged, just covered by a test now.Test plan
src/components.rs(toast_stack_testsmodule), including hammeringpush_error/mixed kinds/set_keyed10k times and assertingitems.len() <= MAX_RETAINED, that the newestMAX_VISIBLEtoasts always survive, that an already-expired toast is evicted before any live one, and that a dismissed toast is removed immediately.cargo test --lib toast_stack_tests— 6 passedcargo fmt --all -- --checkcargo clippy --all-targets -- -D warningscargo buildRUSTDOCFLAGS="-D warnings" cargo doc --no-depsCloses #26
🤖 Generated with Claude Code