From 384c8e647829eb7e95fcbc9ade22e8061649dbb1 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Mon, 19 Jan 2026 12:37:40 -0300 Subject: [PATCH] git_picker: Make the unified version of it available through the title bar (#47151) The recently-introduced unified Git picker was previously only available if you reached for the branch, worktree or stash pickers through the keybinding. Now, if you click on the title bar's branch button, you'll also be able to quickly view the worktree and stash pickers. Release Notes: - N/A --- crates/git_ui/src/branch_picker.rs | 6 ++++- crates/git_ui/src/git_picker.rs | 40 +++++++++++++++++++++++++--- crates/git_ui/src/stash_picker.rs | 6 ++++- crates/git_ui/src/worktree_picker.rs | 6 ++++- crates/title_bar/src/title_bar.rs | 5 ++-- 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/crates/git_ui/src/branch_picker.rs b/crates/git_ui/src/branch_picker.rs index 440dff997c7726b7e560ca33f4cc091785f524cb..2130a612c84301aa32f473649c5a0292a3254b5e 100644 --- a/crates/git_ui/src/branch_picker.rs +++ b/crates/git_ui/src/branch_picker.rs @@ -232,7 +232,11 @@ impl BranchList { .detach_and_log_err(cx); let delegate = BranchListDelegate::new(workspace, repository, style, cx); - let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx).modal(!embedded)); + let picker = cx.new(|cx| { + Picker::uniform_list(delegate, window, cx) + .show_scrollbar(true) + .modal(!embedded) + }); let picker_focus_handle = picker.focus_handle(cx); picker.update(cx, |picker, _| { diff --git a/crates/git_ui/src/git_picker.rs b/crates/git_ui/src/git_picker.rs index ca899c239eb3befa893d0630ee56f11bbdaab3ca..2371e74605d31c5066ffafcd26292814ec4ae9b9 100644 --- a/crates/git_ui/src/git_picker.rs +++ b/crates/git_ui/src/git_picker.rs @@ -2,8 +2,8 @@ use std::fmt::Display; use gpui::{ App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, InteractiveElement, - KeyContext, ModifiersChangedEvent, MouseButton, ParentElement, Render, Styled, Subscription, - WeakEntity, Window, actions, rems, + KeyContext, ModifiersChangedEvent, MouseButton, ParentElement, Rems, Render, Styled, + Subscription, WeakEntity, Window, actions, rems, }; use project::git_store::Repository; use ui::{ @@ -50,6 +50,7 @@ pub struct GitPicker { worktree_list: Option>, stash_list: Option>, _subscriptions: Vec, + popover_style: bool, } impl GitPicker { @@ -60,6 +61,18 @@ impl GitPicker { width: Rems, window: &mut Window, cx: &mut Context, + ) -> Self { + Self::new_internal(workspace, repository, initial_tab, width, false, window, cx) + } + + fn new_internal( + workspace: WeakEntity, + repository: Option>, + initial_tab: GitPickerTab, + width: Rems, + popover_style: bool, + window: &mut Window, + cx: &mut Context, ) -> Self { let mut this = Self { tab: initial_tab, @@ -70,6 +83,7 @@ impl GitPicker { worktree_list: None, stash_list: None, _subscriptions: Vec::new(), + popover_style, }; this.ensure_active_picker(window, cx); @@ -454,6 +468,11 @@ impl Render for GitPicker { .w(self.width) .elevation_3(cx) .overflow_hidden() + .when(self.popover_style, |el| { + el.on_mouse_down_out(cx.listener(|_, _, _, cx| { + cx.emit(DismissEvent); + })) + }) .key_context({ let mut key_context = KeyContext::new_with_defaults(); key_context.add("Pane"); @@ -582,7 +601,22 @@ fn open_with_tab( }) } -/// Register all git picker actions with the workspace. +pub fn popover( + workspace: WeakEntity, + repository: Option>, + initial_tab: GitPickerTab, + width: Rems, + window: &mut Window, + cx: &mut App, +) -> Entity { + cx.new(|cx| { + let picker = + GitPicker::new_internal(workspace, repository, initial_tab, width, true, window, cx); + picker.focus_handle(cx).focus(window, cx); + picker + }) +} + pub fn register(workspace: &mut Workspace) { workspace.register_action(|workspace, _: &zed_actions::git::Branch, window, cx| { open_with_tab(workspace, GitPickerTab::Branches, window, cx); diff --git a/crates/git_ui/src/stash_picker.rs b/crates/git_ui/src/stash_picker.rs index c0e077262eda9bfc12581f9b23108c2f74928f76..8830d74b82a782ba71cee916437067497913ddce 100644 --- a/crates/git_ui/src/stash_picker.rs +++ b/crates/git_ui/src/stash_picker.rs @@ -125,7 +125,11 @@ impl StashList { .detach_and_log_err(cx); let delegate = StashListDelegate::new(repository, workspace, window, cx); - let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx).modal(!embedded)); + let picker = cx.new(|cx| { + Picker::uniform_list(delegate, window, cx) + .show_scrollbar(true) + .modal(!embedded) + }); let picker_focus_handle = picker.focus_handle(cx); picker.update(cx, |picker, _| { picker.delegate.focus_handle = picker_focus_handle.clone(); diff --git a/crates/git_ui/src/worktree_picker.rs b/crates/git_ui/src/worktree_picker.rs index a66c640305ffa0efff0c99d81a0b78b32baa3fd6..56faecc6bc9bda52c8103b5ca998b852685282dd 100644 --- a/crates/git_ui/src/worktree_picker.rs +++ b/crates/git_ui/src/worktree_picker.rs @@ -112,7 +112,11 @@ impl WorktreeList { .detach_and_log_err(cx); let delegate = WorktreeListDelegate::new(workspace, repository, window, cx); - let picker = cx.new(|cx| Picker::uniform_list(delegate, window, cx).modal(!embedded)); + let picker = cx.new(|cx| { + Picker::uniform_list(delegate, window, cx) + .show_scrollbar(true) + .modal(!embedded) + }); let picker_focus_handle = picker.focus_handle(cx); picker.update(cx, |picker, _| { picker.delegate.focus_handle = picker_focus_handle.clone(); diff --git a/crates/title_bar/src/title_bar.rs b/crates/title_bar/src/title_bar.rs index 59b3c63006e894d9ee7a44d5cb098b5f14cef3c8..4da50918937b1b3b7d17a34afbac822f87281dd1 100644 --- a/crates/title_bar/src/title_bar.rs +++ b/crates/title_bar/src/title_bar.rs @@ -792,10 +792,11 @@ impl TitleBar { Some( PopoverMenu::new("branch-menu") .menu(move |window, cx| { - Some(git_ui::branch_picker::popover( + Some(git_ui::git_picker::popover( workspace.downgrade(), - true, effective_repository.clone(), + git_ui::git_picker::GitPickerTab::Branches, + gpui::rems(34.), window, cx, ))