Fix flicker of pushed-off sticky project header in threads sidebar#57529
Merged
MartinYe1234 merged 6 commits intoMay 26, 2026
Merged
Conversation
Contributor
Author
|
Before: Screen.Recording.2026-05-22.at.1.32.57.PM.movAfter: Screen.Recording.2026-05-22.at.1.34.11.PM.mov |
|
|
||
| let next_header_ix = sidebar.read_with(cx, |sidebar, _| { | ||
| assert!( | ||
| sidebar.contents.project_header_indices.len() >= 2, |
Collaborator
There was a problem hiding this comment.
Small note, pretty harmless, but any reason to not assert == 2 exactly?
Contributor
Author
There was a problem hiding this comment.
Good point, will fix then merge
JosephTLyons
approved these changes
May 26, 2026
TomPlanche
pushed a commit
to TomPlanche/zed
that referenced
this pull request
Jun 2, 2026
…ed-industries#57529) The threads sidebar rebuilds its `Vec<ListEntry>` from scratch on events that touch thread/sidebar state (status changes, title generation, new live info, sending a message, etc.). It previously called `ListState::reset` after every rebuild, which rewrote every list item to `Unmeasured`. On the next render frame, the sticky project header had no measured bounds for the next project header. The sticky project header uses `ListState::bounds_for_item` for the next project header to compute how far it should be pushed off screen. When those measurements were missing, it temporarily fell back to `top_offset = 0`, snapped fully into view for one frame, then popped back once the list was remeasured. Fix: preserve list measurements for entries whose identity and layout shape did not change. `EntryShape` captures each entry's identity plus height-affecting project-header flags. `update_entries` snapshots the old shapes, rebuilds contents, then splices only the changed shape range into `ListState`. Unchanged items keep their measured bounds, so the sticky header remains in its pushed-off position across same-shape updates. This also adds a regression test that renders a two-project sidebar, scrolls into the sticky-header push-off state, performs a same-shape thread metadata update, and verifies the next header's measured bounds are preserved. Closes AI-196 Release Notes: - Fixed the project section header flickering in the agent threads sidebar when sending a message while the header was partially scrolled off screen.
This was referenced Jun 3, 2026
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.
The threads sidebar rebuilds its
Vec<ListEntry>from scratch on events that touch thread/sidebar state (status changes, title generation, new live info, sending a message, etc.). It previously calledListState::resetafter every rebuild, which rewrote every list item toUnmeasured. On the next render frame, the sticky project header had no measured bounds for the next project header.The sticky project header uses
ListState::bounds_for_itemfor the next project header to compute how far it should be pushed off screen. When those measurements were missing, it temporarily fell back totop_offset = 0, snapped fully into view for one frame, then popped back once the list was remeasured.Fix: preserve list measurements for entries whose identity and layout shape did not change.
EntryShapecaptures each entry's identity plus height-affecting project-header flags.update_entriessnapshots the old shapes, rebuilds contents, then splices only the changed shape range intoListState. Unchanged items keep their measured bounds, so the sticky header remains in its pushed-off position across same-shape updates.This also adds a regression test that renders a two-project sidebar, scrolls into the sticky-header push-off state, performs a same-shape thread metadata update, and verifies the next header's measured bounds are preserved.
Closes AI-196
Release Notes: