fix: prevent error toasts from overflowing the viewport#9921
fix: prevent error toasts from overflowing the viewport#9921henrytran1803 wants to merge 2 commits intowarpdotdev:masterfrom
Conversation
Persistent error toasts (e.g. from repeated session share failures) could accumulate without bound, causing the toast stack to overflow the visible window with no way to scroll or dismiss older toasts. Three-layer defense: 1. Cap persistent toast count at 5 — oldest toasts are evicted when exceeded 2. Deduplicate by object_id — repeated identical error messages replace older toasts instead of stacking 3. Constrain rendered toast stack to 500px max height with clipping as a layout safety net Fixes warpdotdev#9733
|
I'm starting a first review of this pull request. You can view the conversation on Warp. I reviewed this pull request and requested human review from: @warpdotdev/oss-maintainers. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR caps and deduplicates persistent toasts and adds a render-time max-height clipping guard to keep the toast stack from overflowing the viewport.
Concerns
- No blocking correctness or security concerns found in the annotated diff.
Verdict
Found: 0 critical, 0 important, 0 suggestions
Approve
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
There was a problem hiding this comment.
- Cap persistent toast count (
MAX_PERSISTENT_TOASTS = 5): When the limit is exceeded, the oldest toast is evicted from the stack.
@henrytran1803, that might be problematic if more than 5 unique toasts are rendered. (Is having them be scrollable infeasible?)
- Deduplication by
object_id:show_persistent_toast()now sets anobject_idbased on the toast text, so repeated identical error messages replace older toasts instead of stacking. The existingdismiss_older_toastsmechanism handles this automatically.
Rendering a counter, for each time a duplicate toast is replaced, so that the user knows how many times that toast has been produced, would be helpful.
- Layout safety net (
ConstrainedBox+Clipped): The rendered toast stack is constrained to a500pxmax height with clipping, ensuring toasts never overflow the viewport even in edge cases.
Can we not, instead, calculate the geometry of the interface, rather than define an arbitrary constant? This might not be sufficient on low-DPI (1 024 × 720 px) displays:
- Remove arbitrary MAX_PERSISTENT_TOASTS cap; instead allow unlimited unique toasts with viewport-based height constraint - Add duplicate counter: repeated identical toasts increment a count displayed as '(x3)' in the toast text instead of replacing silently - Replace hardcoded 500px max height with computed viewport height from TAB_CONTENT_POSITION_ID element geometry, ensuring correct behavior on all display sizes including low-DPI
|
@RokeJulianLockhart great points, all three — pushed a fix that addresses each of them! 1. Scrollable instead of capped — yep, agreed. I dropped the 2. Counter for duplicates — nice idea! Instead of replacing the duplicate, I now increment a counter on the existing toast and display it as 3. Viewport geometry instead of 500px — good catch on low-DPI, that would've been embarrassing 😅 Replaced the hardcoded constant with a computed height from Let me know if anything else needs tweaking! |
Description
Error toasts (e.g. from repeated session share failures) could accumulate without bound, causing the toast stack to overflow the visible window with no way to scroll or dismiss older toasts.
The fix applies a three-layer defense:
MAX_PERSISTENT_TOASTS = 5): When the limit is exceeded, the oldest toast is evicted from the stack.object_id:show_persistent_toast()now sets anobject_idbased on the toast text, so repeated identical error messages replace older toasts instead of stacking. The existingdismiss_older_toastsmechanism handles this automatically.ConstrainedBox+Clipped): The rendered toast stack is constrained to a500pxmax height with clipping, ensuring toasts never overflow the viewport even in edge cases.Changes
app/src/view_components/dismissible_toast.rs:MAX_PERSISTENT_TOASTSconstant (5) andTOAST_STACK_MAX_HEIGHTconstant (500px)add_persistent_toast()by removing oldest toasts when limit exceededConstrainedBoxwithClippedto prevent viewport overflowapp/src/terminal/view.rs:object_idto persistent toasts inshow_persistent_toast()for deduplicationLinked Issue
ready-to-implement.Testing
The fix is defensive — it caps count, deduplicates, and constrains layout. Manual verification:
No automated test was added because the toast stack depends on UI rendering infrastructure that requires the full Warp app bootstrap. The logic changes (cap + dedup) are straightforward guards that are easy to verify visually.
Co-Authored-By: Warp agent@warp.dev