sidebar: Add some small design tweaks (#51936)

Danilo Leal created

- [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

Change summary

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(-)

Detailed changes

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() {

crates/sidebar/src/sidebar.rs 🔗

@@ -339,6 +339,12 @@ impl Sidebar {
         }
     }
 
+    fn is_active_workspace(&self, workspace: &Entity<Workspace>, cx: &App) -> bool {
+        self.multi_workspace
+            .upgrade()
+            .map_or(false, |mw| mw.read(cx).workspace() == workspace)
+    }
+
     fn subscribe_to_workspace(
         &mut self,
         workspace: &Entity<Workspace>,
@@ -397,7 +403,9 @@ impl Sidebar {
 
         if let Some(agent_panel) = workspace.read(cx).panel::<AgentPanel>(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<acp::SessionId, AgentThreadStatus> = 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)),
             )
     }

crates/ui/src/components/ai/thread_item.rs 🔗

@@ -40,6 +40,7 @@ pub struct ThreadItem {
     on_click: Option<Box<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
     on_hover: Box<dyn Fn(&bool, &mut Window, &mut App) + 'static>,
     title_label_color: Option<Color>,
+    title_label_size: Option<LabelSize>,
     action_slot: Option<AnyElement>,
     tooltip: Option<Box<dyn Fn(&mut Window, &mut App) -> 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 {