From f18b288fdf06d2b0d66bb4832bb0d9897dc827ba Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Thu, 8 Jan 2026 19:47:22 -0300 Subject: [PATCH] gpui: Fix bug on `on_hover` callbacks (#46371) Tackling this as I noticed a bug in the agent panel where the button to delete a thread, which appeared only on hover, stopped showing up. PRs #43324 and #45437 fixed stuff in applying hover styles through `.hover()` but broke the `.on_hover()` callback. Problem was that both methods were sharing the same `element_state.hover_state` but running at different phases. The solution here was to add a new independent state field for the hover listener (`hover_listener_state`) while the hover style method keeps using `hover_state`. Release Notes: - Agent: Fixed a bug where the button to delete a thread stopped showing up. --- crates/gpui/src/elements/div.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/crates/gpui/src/elements/div.rs b/crates/gpui/src/elements/div.rs index 8d75b23843be6f0193ef39053d6f7c98ceb1900f..6d13fa6a8d2732d2980f817bb49807b913e5179e 100644 --- a/crates/gpui/src/elements/div.rs +++ b/crates/gpui/src/elements/div.rs @@ -2177,8 +2177,8 @@ impl Interactivity { if phase == DispatchPhase::Capture && hovered != was_hovered { if let Some(hover_state) = &hover_state { hover_state.borrow_mut().element = hovered; + cx.notify(current_view); } - cx.notify(current_view); } }); } @@ -2377,7 +2377,7 @@ impl Interactivity { if let Some(hover_listener) = self.hover_listener.take() { let hitbox = hitbox.clone(); let was_hovered = element_state - .hover_state + .hover_listener_state .get_or_insert_with(Default::default) .clone(); let has_mouse_down = element_state @@ -2394,8 +2394,8 @@ impl Interactivity { && hitbox.is_hovered(window); let mut was_hovered = was_hovered.borrow_mut(); - if is_hovered != was_hovered.element { - was_hovered.element = is_hovered; + if is_hovered != *was_hovered { + *was_hovered = is_hovered; drop(was_hovered); hover_listener(&is_hovered, window, cx); @@ -2727,6 +2727,7 @@ pub struct InteractiveElementState { pub(crate) focus_handle: Option, pub(crate) clicked_state: Option>>, pub(crate) hover_state: Option>>, + pub(crate) hover_listener_state: Option>>, pub(crate) pending_mouse_down: Option>>>, pub(crate) scroll_offset: Option>>>, pub(crate) active_tooltip: Option>>>,