From fb9415eca542fdb6ddf819a0958bc75a2ca4d706 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Mon, 13 Apr 2026 23:07:07 -0600 Subject: [PATCH] sidebar: Click project header row to toggle fold instead of switching worktrees (#53861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, clicking a project header in the agent sidebar would activate/switch to that worktree's workspace, resuming whatever thread was most recently active. This felt jarring — activating a random thread based on recency isn't that useful when the user can just click the specific thread they want. There's also no clear semantic for clicking the overall group header since each thread maps to a specific workspace and there's no single workspace to activate for the group. This changes the click target for folding from just the chevron to the entire header row. The worktree-switching behavior is removed — clicking anywhere on the row now toggles the fold, which is a more predictable and useful interaction. The hover-only buttons on the right side (ellipsis menu, collapse threads, new thread) continue to work as before, with their own click handlers that stop propagation. Release Notes: - Improved sidebar project headers to toggle fold on click instead of switching worktrees. --- crates/sidebar/src/sidebar.rs | 37 +++++++---------------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/crates/sidebar/src/sidebar.rs b/crates/sidebar/src/sidebar.rs index e8e68a07ccfabddc8794ae851289395073579e2e..b1ae81094550ba2c796b7438cfd0f7bd27b142c4 100644 --- a/crates/sidebar/src/sidebar.rs +++ b/crates/sidebar/src/sidebar.rs @@ -1806,9 +1806,6 @@ impl Sidebar { move |this, _, window, cx| { this.set_group_expanded(&key, true, cx); this.selection = None; - // If the active workspace belongs to this - // group, use it (preserves linked worktree - // context). Otherwise resolve from the key. let workspace = this.multi_workspace.upgrade().and_then(|mw| { let mw = mw.read(cx); let active = mw.workspace().clone(); @@ -1832,33 +1829,13 @@ impl Sidebar { )) }), ) - .map(|this| { - if !has_threads && is_active { - this - } else { - let key = key.clone(); - this.cursor_pointer() - .when(!is_active, |this| this.hover(|s| s.bg(hover_solid))) - .tooltip(Tooltip::text("Open Workspace")) - .on_click(cx.listener(move |this, _, window, cx| { - if let Some(workspace) = this.multi_workspace.upgrade().and_then(|mw| { - mw.read(cx).workspace_for_paths( - key.path_list(), - key.host().as_ref(), - cx, - ) - }) { - // Just activate the workspace. The - // AgentPanel remembers what was last - // shown, so the user returns to whatever - // thread/draft they were looking at. - this.activate_workspace(&workspace, window, cx); - } else { - this.open_workspace_for_group(&key, window, cx); - } - })) - } - }) + .cursor_pointer() + .when(!is_active, |this| this.hover(|s| s.bg(hover_solid))) + .tooltip(Tooltip::text(disclosure_tooltip)) + .on_click(cx.listener(move |this, _, window, cx| { + this.selection = None; + this.toggle_collapse(&key_for_collapse, window, cx); + })) .into_any_element() }