Keep git panel history entry highlighted while context menu is open (#61354)

Also, unifies the naming of the variable naming for the target entry in
both the git graph and git panel history tab.

Release Notes:

- Improved the git panel's history tab to keep an entry highlighted
while its context menu is open
This commit is contained in:
Joseph T. Lyons authored and GitHub committed 2026-07-20 17:27:25 +00:00
1 parent 16fd124094
commit 3e34dcf2a7
2 files changed
+47 -17

No files matched your search

+13 -8
View File
@@ -1294,7 +1294,7 @@ fn compute_diff_stats(diff: &CommitDiff) -> (usize, usize) {
struct GitGraphContextMenu {
menu: Entity<ContextMenu>,
position: Point<Pixels>,
entry_idx: Option<usize>,
target_entry_index: Option<usize>,
_subscription: Subscription,
}
@@ -2446,7 +2446,7 @@ impl GitGraph {
&mut self,
context_menu: Entity<ContextMenu>,
position: Point<Pixels>,
entry_idx: Option<usize>,
target_entry_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
) {
@@ -2471,7 +2471,7 @@ impl GitGraph {
self.context_menu = Some(GitGraphContextMenu {
menu: context_menu,
position,
entry_idx,
target_entry_index,
_subscription: subscription,
});
cx.notify();
@@ -3205,7 +3205,10 @@ impl GitGraph {
let hovered_entry_idx = self.hovered_entry_idx;
let selected_entry_idx = self.selected_entry_idx;
let context_menu_entry_idx = self.context_menu.as_ref().and_then(|menu| menu.entry_idx);
let context_menu_target_index = self
.context_menu
.as_ref()
.and_then(|menu| menu.target_entry_index);
let is_focused = self.focus_handle.is_focused(window);
let graph_canvas_bounds = self.graph_canvas_bounds.clone();
@@ -3229,7 +3232,7 @@ impl GitGraph {
let is_hovered = hovered_entry_idx == Some(absolute_row_idx);
let is_selected = selected_entry_idx == Some(absolute_row_idx);
let is_context_menu_target =
context_menu_entry_idx == Some(absolute_row_idx);
context_menu_target_index == Some(absolute_row_idx);
if is_hovered || is_selected || is_context_menu_target {
let row_y = bounds.origin.y + visible_row_idx as f32 * row_height
@@ -3840,8 +3843,10 @@ impl Render for GitGraph {
let row_height = Self::row_height(window, cx);
let selected_entry_idx = self.selected_entry_idx;
let hovered_entry_idx = self.hovered_entry_idx;
let context_menu_entry_idx =
self.context_menu.as_ref().and_then(|menu| menu.entry_idx);
let context_menu_target_index = self
.context_menu
.as_ref()
.and_then(|menu| menu.target_entry_index);
let weak_self = cx.weak_entity();
let focus_handle = self.focus_handle.clone();
let table_focus_handle =
@@ -3881,7 +3886,7 @@ impl Render for GitGraph {
let is_selected = selected_entry_idx == Some(index);
let is_hovered = hovered_entry_idx == Some(index);
let is_context_menu_target =
context_menu_entry_idx == Some(index);
context_menu_target_index == Some(index);
let table_focus_handle = table_focus_handle.clone();
let is_focused = focus_handle.is_focused(window)
|| table_focus_handle.is_focused(window);
+34 -9
View File
@@ -895,6 +895,13 @@ impl TruncatedPatch {
}
}
struct GitPanelContextMenu {
menu: Entity<ContextMenu>,
position: Point<Pixels>,
target_entry_index: Option<usize>,
_subscription: Subscription,
}
pub struct GitPanel {
pub(crate) active_repository: Option<Entity<Repository>>,
pub(crate) commit_editor: Entity<Editor>,
@@ -934,7 +941,7 @@ pub struct GitPanel {
update_visible_entries_task: Task<()>,
reopen_commit_buffer_task: Task<()>,
pub(crate) workspace: WeakEntity<Workspace>,
context_menu: Option<(Entity<ContextMenu>, Point<Pixels>, Subscription)>,
context_menu: Option<GitPanelContextMenu>,
modal_open: bool,
show_placeholders: bool,
// Only read to compute collaborative co-authors, which requires the `call` feature.
@@ -6232,7 +6239,7 @@ impl GitPanel {
);
self.focused_history_entry = Some(index);
self.history_keyboard_nav = false;
self.set_context_menu(context_menu, position, window, cx);
self.set_context_menu(context_menu, position, Some(index), window, cx);
}
fn activate_changes_tab(
@@ -6396,6 +6403,10 @@ impl GitPanel {
let is_panel_focused = self.focus_handle.is_focused(window);
let show_focus_border = self.history_keyboard_nav;
let has_context_menu = self.context_menu.is_some();
let context_menu_target_index = self
.context_menu
.as_ref()
.and_then(|context_menu| context_menu.target_entry_index);
let ahead_count = active_repository
.read(cx)
@@ -6488,6 +6499,8 @@ impl GitPanel {
let is_unpushed = index < ahead_count;
let is_focused = focused_history_entry == Some(index);
let is_context_menu_target =
context_menu_target_index == Some(index);
let workspace = workspace.clone();
let repo = repo_weak.clone();
let sha_for_click = sha_string;
@@ -6517,6 +6530,9 @@ impl GitPanel {
},
)
.hover(|s| s.bg(cx.theme().colors().element_hover))
.when(is_context_menu_target, |this| {
this.bg(cx.theme().colors().element_hover)
})
.child(
h_flex()
.gap_1()
@@ -7174,7 +7190,7 @@ impl GitPanel {
})
});
self.selected_entry = Some(ix);
self.set_context_menu(context_menu, position, window, cx);
self.set_context_menu(context_menu, position, None, window, cx);
}
fn deploy_panel_context_menu(
@@ -7199,13 +7215,14 @@ impl GitPanel {
window,
cx,
);
self.set_context_menu(context_menu, position, window, cx);
self.set_context_menu(context_menu, position, None, window, cx);
}
fn set_context_menu(
&mut self,
context_menu: Entity<ContextMenu>,
position: Point<Pixels>,
target_entry_index: Option<usize>,
window: &mut Window,
cx: &mut Context<Self>,
) {
@@ -7216,7 +7233,10 @@ impl GitPanel {
window,
|this, _, _: &DismissEvent, window, cx| {
if this.context_menu.as_ref().is_some_and(|context_menu| {
context_menu.0.focus_handle(cx).contains_focused(window, cx)
context_menu
.menu
.focus_handle(cx)
.contains_focused(window, cx)
}) {
cx.focus_self(window);
}
@@ -7224,7 +7244,12 @@ impl GitPanel {
cx.notify();
},
);
self.context_menu = Some((context_menu, position, subscription));
self.context_menu = Some(GitPanelContextMenu {
menu: context_menu,
position,
target_entry_index,
_subscription: subscription,
});
cx.notify();
}
@@ -8024,12 +8049,12 @@ impl Render for GitPanel {
})
.into_any_element(),
)
.children(self.context_menu.as_ref().map(|(menu, position, _)| {
.children(self.context_menu.as_ref().map(|context_menu| {
deferred(
anchored()
.position(*position)
.position(context_menu.position)
.anchor(Anchor::TopLeft)
.child(menu.clone()),
.child(context_menu.menu.clone()),
)
.with_priority(1)
}))