Skip to content

Fix flicker of pushed-off sticky project header in threads sidebar#57529

Merged
MartinYe1234 merged 6 commits into
mainfrom
martin/ai-196-sidebar-sticky-headers-flicker-while-scrolling
May 26, 2026
Merged

Fix flicker of pushed-off sticky project header in threads sidebar#57529
MartinYe1234 merged 6 commits into
mainfrom
martin/ai-196-sidebar-sticky-headers-flicker-while-scrolling

Conversation

@MartinYe1234

@MartinYe1234 MartinYe1234 commented May 22, 2026

Copy link
Copy Markdown
Contributor

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.

@MartinYe1234 MartinYe1234 self-assigned this May 22, 2026
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label May 22, 2026
@zed-community-bot zed-community-bot Bot added the staff Pull requests authored by a current member of Zed staff label May 22, 2026
@MartinYe1234

Copy link
Copy Markdown
Contributor Author

Before:

Screen.Recording.2026-05-22.at.1.32.57.PM.mov

After:

Screen.Recording.2026-05-22.at.1.34.11.PM.mov

@MartinYe1234 MartinYe1234 marked this pull request as ready for review May 22, 2026 21:20
Comment thread crates/sidebar/src/sidebar_tests.rs Outdated

let next_header_ix = sidebar.read_with(cx, |sidebar, _| {
assert!(
sidebar.contents.project_header_indices.len() >= 2,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Small note, pretty harmless, but any reason to not assert == 2 exactly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, will fix then merge

@MartinYe1234 MartinYe1234 added this pull request to the merge queue May 26, 2026
Merged via the queue into main with commit a896669 May 26, 2026
32 checks passed
@MartinYe1234 MartinYe1234 deleted the martin/ai-196-sidebar-sticky-headers-flicker-while-scrolling branch May 26, 2026 14:44
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement staff Pull requests authored by a current member of Zed staff

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants