From c579db975fea7c6e695904e0e3893ee987c7e3fa Mon Sep 17 00:00:00 2001 From: Jason Lee Date: Wed, 8 Oct 2025 10:17:08 +0800 Subject: [PATCH] menu: Better handle hover for menu item. (#1332) Follow #1328 to improve again. --- crates/ui/src/menu/menu_item.rs | 19 ++++++++----------- crates/ui/src/menu/popup_menu.rs | 11 +++++++---- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/crates/ui/src/menu/menu_item.rs b/crates/ui/src/menu/menu_item.rs index 5c2edc9c..05badfef 100644 --- a/crates/ui/src/menu/menu_item.rs +++ b/crates/ui/src/menu/menu_item.rs @@ -1,8 +1,8 @@ use crate::{h_flex, ActiveTheme, Disableable, Selectable, StyledExt}; use gpui::{ prelude::FluentBuilder as _, AnyElement, App, ClickEvent, ElementId, InteractiveElement, - IntoElement, MouseButton, MouseMoveEvent, ParentElement, RenderOnce, - StatefulInteractiveElement as _, StyleRefinement, Styled, Window, + IntoElement, MouseButton, ParentElement, RenderOnce, StatefulInteractiveElement as _, + StyleRefinement, Styled, Window, }; use smallvec::SmallVec; @@ -14,7 +14,7 @@ pub struct MenuItem { selected: bool, hovered: bool, on_click: Option>, - on_mouse_enter: Option>, + on_hover: Option>, children: SmallVec<[AnyElement; 2]>, } @@ -28,7 +28,7 @@ impl MenuItem { selected: false, hovered: false, on_click: None, - on_mouse_enter: None, + on_hover: None, children: SmallVec::new(), } } @@ -59,11 +59,8 @@ impl MenuItem { /// Set a handler for when the mouse enters the MenuItem. #[allow(unused)] - pub fn on_mouse_enter( - mut self, - handler: impl Fn(&MouseMoveEvent, &mut Window, &mut App) + 'static, - ) -> Self { - self.on_mouse_enter = Some(Box::new(handler)); + pub fn on_hover(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self { + self.on_hover = Some(Box::new(handler)); self } } @@ -111,8 +108,8 @@ impl RenderOnce for MenuItem { .items_center() .justify_between() .refine_style(&self.style) - .when_some(self.on_mouse_enter, |this, on_mouse_enter| { - this.on_mouse_move(move |ev, window, cx| (on_mouse_enter)(ev, window, cx)) + .when_some(self.on_hover, |this, on_hover| { + this.on_hover(move |hovered, window, cx| (on_hover)(hovered, window, cx)) }) .when(!self.disabled, |this| { this.when(self.hovered, |this| { diff --git a/crates/ui/src/menu/popup_menu.rs b/crates/ui/src/menu/popup_menu.rs index 0d10975a..a98e3926 100644 --- a/crates/ui/src/menu/popup_menu.rs +++ b/crates/ui/src/menu/popup_menu.rs @@ -831,12 +831,15 @@ impl PopupMenu { .rounded(radius) .items_center() .hovered(selected) - .on_mouse_enter(cx.listener(move |this, _, _, cx| { - if this.selected_index == Some(ix) { - return; + .on_hover(cx.listener(move |this, hovered, _, cx| { + if *hovered { + this.selected_index = Some(ix); + } else { + if this.selected_index == Some(ix) { + this.selected_index = None; + } } - this.selected_index = Some(ix); cx.notify(); }));