menu: Fix submenu item selection when multiple submenus exist (#1342)

Before:


https://github.com/user-attachments/assets/8653953e-4e9d-49e6-946a-1696ea6abee0

After:


https://github.com/user-attachments/assets/f5bfbf19-69e1-4e64-81c1-072c61e8a8f7

---------

Co-authored-by: Jason Lee <huacnlee@gmail.com>
This commit is contained in:
ihavecoke 2025-10-09 21:32:51 +08:00 committed by GitHub
parent 7a8be9a628
commit 9d01ac26bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 29 additions and 25 deletions

View file

@ -1,11 +1,11 @@
use gpui::{
actions, div, px, Action, App, AppContext, Context, Corner, Entity, FocusHandle, Focusable,
InteractiveElement, IntoElement, KeyBinding, ParentElement as _, Render, SharedString,
Styled as _, Window,
Action, App, AppContext, Context, Corner, Entity, FocusHandle, Focusable, InteractiveElement,
IntoElement, KeyBinding, ParentElement as _, Render, SharedString, Styled as _, Window,
actions, div, px,
};
use gpui_component::{
button::Button, context_menu::ContextMenuExt, h_flex, popup_menu::PopupMenuExt as _, v_flex,
ActiveTheme as _, IconName,
ActiveTheme as _, IconName, button::Button, context_menu::ContextMenuExt, h_flex,
popup_menu::PopupMenuExt as _, v_flex,
};
use serde::Deserialize;
@ -178,7 +178,7 @@ impl Render for MenuStory {
.separator()
.submenu("Links", window, cx, |menu, _, _| {
menu.link_with_icon(
"GitHub Repository",
"GPUI Component",
IconName::GitHub,
"https://github.com/longbridge/gpui-component",
)
@ -186,6 +186,11 @@ impl Render for MenuStory {
.link("GPUI", "https://gpui.rs")
.link("Zed", "https://zed.dev")
})
.separator()
.submenu("Other Links", window, cx, |menu, _, _| {
menu.link("Crates", "https://crates.io")
.link("Rust Docs", "https://docs.rs")
})
}),
)
.child(self.message.clone()),

View file

@ -953,25 +953,24 @@ impl PopupMenu {
.child(IconName::ChevronRight),
),
)
.child({
let (anchor, left) = self.child_menu_anchor(window);
let is_bottom_pos = matches!(anchor, Corner::BottomLeft | Corner::BottomRight);
anchored()
.anchor(anchor)
.child(
div()
.id("submenu")
.group(&group_name)
.when(!selected, |this| this.invisible())
.group_hover(&group_name, |this| this.visible())
.occlude()
.when(is_bottom_pos, |this| this.bottom_0())
.when(!is_bottom_pos, |this| this.top_neg_1())
.left(left)
.child(menu.clone()),
)
.snap_to_window_with_margin(Edges::all(EDGE_PADDING))
.when(selected, |this| {
this.child({
let (anchor, left) = self.child_menu_anchor(window);
let is_bottom_pos =
matches!(anchor, Corner::BottomLeft | Corner::BottomRight);
anchored()
.anchor(anchor)
.child(
div()
.id("submenu")
.occlude()
.when(is_bottom_pos, |this| this.bottom_0())
.when(!is_bottom_pos, |this| this.top_neg_1())
.left(left)
.child(menu.clone()),
)
.snap_to_window_with_margin(Edges::all(EDGE_PADDING))
})
}),
}
}