From d934ba6cea45f46df2eda92ef6a2d8db1e9778c5 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Thu, 19 Mar 2026 11:15:24 -0300 Subject: [PATCH] sidebar: Add some small design tweaks (#51936) - [x] I've reviewed my own diff for quality, security, and reliability - [X] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A --- crates/recent_projects/src/recent_projects.rs | 2 +- crates/sidebar/src/sidebar.rs | 27 +++++++++++++++---- crates/ui/src/components/ai/thread_item.rs | 13 +++++++-- 3 files changed, 34 insertions(+), 8 deletions(-) diff --git a/crates/recent_projects/src/recent_projects.rs b/crates/recent_projects/src/recent_projects.rs index b15e6598d6106517e77d5647e776f33e298933a1..95f619f8858c36cfcff6f091b453f31576102ef9 100644 --- a/crates/recent_projects/src/recent_projects.rs +++ b/crates/recent_projects/src/recent_projects.rs @@ -928,7 +928,7 @@ impl PickerDelegate for RecentProjectsDelegate { }; if has_siblings_to_show { - entries.push(ProjectPickerEntry::Header("Open on This Window".into())); + entries.push(ProjectPickerEntry::Header("This Window".into())); if is_empty_query { for (id, (workspace_id, _, _, _)) in self.workspaces.iter().enumerate() { diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index d30b8e4ee8db38704a2a8e307edeba4b73f7f850..c793b8a43aadcc6c8befed3a368ac2580693023a 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -339,6 +339,12 @@ impl Sidebar { } } + fn is_active_workspace(&self, workspace: &Entity, cx: &App) -> bool { + self.multi_workspace + .upgrade() + .map_or(false, |mw| mw.read(cx).workspace() == workspace) + } + fn subscribe_to_workspace( &mut self, workspace: &Entity, @@ -397,7 +403,9 @@ impl Sidebar { if let Some(agent_panel) = workspace.read(cx).panel::(cx) { self.subscribe_to_agent_panel(&agent_panel, window, cx); - self.agent_panel_visible = AgentPanel::is_visible(workspace, cx); + if self.is_active_workspace(workspace, cx) { + self.agent_panel_visible = AgentPanel::is_visible(workspace, cx); + } self.observe_draft_editor(cx); } } @@ -435,7 +443,12 @@ impl Sidebar { for dock in docks { let workspace = workspace.clone(); cx.observe(&dock, move |this, _dock, cx| { + if !this.is_active_workspace(&workspace, cx) { + return; + } + let is_visible = AgentPanel::is_visible(&workspace, cx); + if this.agent_panel_visible != is_visible { this.agent_panel_visible = is_visible; cx.notify(); @@ -594,6 +607,12 @@ impl Sidebar { self.focused_thread = panel_focused; } + // Re-derive agent_panel_visible from the active workspace so it stays + // correct after workspace switches. + self.agent_panel_visible = active_workspace + .as_ref() + .map_or(false, |ws| AgentPanel::is_visible(ws, cx)); + let previous = mem::take(&mut self.contents); let old_statuses: HashMap = previous @@ -1149,12 +1168,10 @@ impl Sidebar { let label = if highlight_positions.is_empty() { Label::new(label.clone()) - .size(LabelSize::Small) .color(Color::Muted) .into_any_element() } else { HighlightedLabel::new(label.clone(), highlight_positions.to_vec()) - .size(LabelSize::Small) .color(Color::Muted) .into_any_element() }; @@ -2343,7 +2360,7 @@ impl Sidebar { ThreadItem::new(id, label) .icon(icon) .focused(is_selected) - .title_label_color(Color::Custom(cx.theme().colors().text.opacity(0.85))) + .title_label_color(Color::Muted) .on_click(cx.listener(move |this, _, _window, cx| { this.selection = None; if is_fully_expanded { @@ -2785,7 +2802,7 @@ impl Render for Sidebar { h_flex() .p_1() .border_t_1() - .border_color(cx.theme().colors().border_variant) + .border_color(cx.theme().colors().border) .child(self.render_sidebar_toggle_button(cx)), ) } diff --git a/crates/ui/src/components/ai/thread_item.rs b/crates/ui/src/components/ai/thread_item.rs index 152168dafb43d8b565cba02ad096d565479741a4..02de8512963302ddeb1abce572894caf4dadd616 100644 --- a/crates/ui/src/components/ai/thread_item.rs +++ b/crates/ui/src/components/ai/thread_item.rs @@ -40,6 +40,7 @@ pub struct ThreadItem { on_click: Option>, on_hover: Box, title_label_color: Option, + title_label_size: Option, action_slot: Option, tooltip: Option AnyView + 'static>>, } @@ -67,6 +68,7 @@ impl ThreadItem { on_click: None, on_hover: Box::new(|_, _, _| {}), title_label_color: None, + title_label_size: None, action_slot: None, tooltip: None, } @@ -165,6 +167,11 @@ impl ThreadItem { self } + pub fn title_label_size(mut self, size: LabelSize) -> Self { + self.title_label_size = Some(size); + self + } + pub fn action_slot(mut self, element: impl IntoElement) -> Self { self.action_slot = Some(element.into_any_element()); self @@ -257,8 +264,10 @@ impl RenderOnce for ThreadItem { let title = self.title; let highlight_positions = self.highlight_positions; + let title_label_size = self.title_label_size.unwrap_or(LabelSize::Default); let title_label = if self.generating_title { Label::new(title) + .size(title_label_size) .color(Color::Muted) .with_animation( "generating-title", @@ -269,7 +278,7 @@ impl RenderOnce for ThreadItem { ) .into_any_element() } else if highlight_positions.is_empty() { - let label = Label::new(title); + let label = Label::new(title).size(title_label_size); let label = if let Some(color) = self.title_label_color { label.color(color) } else { @@ -277,7 +286,7 @@ impl RenderOnce for ThreadItem { }; label.into_any_element() } else { - let label = HighlightedLabel::new(title, highlight_positions); + let label = HighlightedLabel::new(title, highlight_positions).size(title_label_size); let label = if let Some(color) = self.title_label_color { label.color(color) } else {