context menu: Improve docs aside responsiveness (#25347)

Closes https://github.com/zed-industries/zed/issues/24883

While this PR closes the issue above, it still doesn't implement a
bullet-proof solution for the context menu docs aside, meaning, it might
not work the best way if there are other places using it (like the
Editor Controls menu). For that, I think we'll want a more robust
collision-aware solution, possibly similar to the LSP completion menu.

Release Notes:

- N/A

---------

Co-authored-by: Agus Zubiaga <hi@aguz.me>
Co-authored-by: Nate Butler <1714999+iamnbutler@users.noreply.github.com>
This commit is contained in:
Danilo Leal 2025-02-21 16:12:53 -03:00 committed by GitHub
parent 17323ed7b2
commit 2e302b1a7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 15 deletions

View file

@ -399,8 +399,14 @@ impl InlineCompletionButton {
}) })
} }
pub fn build_language_settings_menu(&self, mut menu: ContextMenu, cx: &mut App) -> ContextMenu { pub fn build_language_settings_menu(
&self,
mut menu: ContextMenu,
window: &Window,
cx: &mut App,
) -> ContextMenu {
let fs = self.fs.clone(); let fs = self.fs.clone();
let line_height = window.line_height();
menu = menu.header("Show Edit Predictions For"); menu = menu.header("Show Edit Predictions For");
@ -499,12 +505,14 @@ impl InlineCompletionButton {
) )
.child( .child(
h_flex() h_flex()
.items_start()
.pt_2() .pt_2()
.flex_1()
.gap_1p5() .gap_1p5()
.border_t_1() .border_t_1()
.border_color(cx.theme().colors().border_variant) .border_color(cx.theme().colors().border_variant)
.child(Icon::new(icon_name).size(IconSize::XSmall).color(icon_color)) .child(h_flex().flex_shrink_0().h(line_height).child(Icon::new(icon_name).size(IconSize::XSmall).color(icon_color)))
.child(div().child(Label::new(msg).size(LabelSize::Small).color(label_color))) .child(div().child(msg).w_full().text_sm().text_color(label_color.color(cx)))
) )
.into_any_element() .into_any_element()
}) })
@ -631,8 +639,8 @@ impl InlineCompletionButton {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Entity<ContextMenu> { ) -> Entity<ContextMenu> {
ContextMenu::build(window, cx, |menu, _, cx| { ContextMenu::build(window, cx, |menu, window, cx| {
self.build_language_settings_menu(menu, cx) self.build_language_settings_menu(menu, window, cx)
.separator() .separator()
.link( .link(
"Go to Copilot Settings", "Go to Copilot Settings",
@ -650,8 +658,8 @@ impl InlineCompletionButton {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Entity<ContextMenu> { ) -> Entity<ContextMenu> {
ContextMenu::build(window, cx, |menu, _, cx| { ContextMenu::build(window, cx, |menu, window, cx| {
self.build_language_settings_menu(menu, cx) self.build_language_settings_menu(menu, window, cx)
.separator() .separator()
.action("Sign Out", supermaven::SignOut.boxed_clone()) .action("Sign Out", supermaven::SignOut.boxed_clone())
}) })
@ -662,8 +670,8 @@ impl InlineCompletionButton {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) -> Entity<ContextMenu> { ) -> Entity<ContextMenu> {
ContextMenu::build(window, cx, |menu, _window, cx| { ContextMenu::build(window, cx, |menu, window, cx| {
self.build_language_settings_menu(menu, cx).when( self.build_language_settings_menu(menu, window, cx).when(
cx.has_flag::<PredictEditsRateCompletionsFeatureFlag>(), cx.has_flag::<PredictEditsRateCompletionsFeatureFlag>(),
|this| this.action("Rate Completions", RateCompletions.boxed_clone()), |this| this.action("Rate Completions", RateCompletions.boxed_clone()),
) )

View file

@ -507,6 +507,9 @@ impl ContextMenuItem {
impl Render for ContextMenu { impl Render for ContextMenu {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement { fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx); let ui_font_size = ThemeSettings::get_global(cx).ui_font_size(cx);
let window_size = window.viewport_size();
let rem_size = window.rem_size();
let is_wide_window = window_size.width / rem_size > rems_from_px(800.).0;
let aside = self let aside = self
.documentation_aside .documentation_aside
@ -514,19 +517,23 @@ impl Render for ContextMenu {
.map(|(_, callback)| callback.clone()); .map(|(_, callback)| callback.clone());
h_flex() h_flex()
.when(is_wide_window, |this| {this.flex_row()})
.when(!is_wide_window, |this| {this.flex_col()})
.w_full() .w_full()
.items_start() .items_start()
.gap_1() .gap_1()
.when_some(aside, |this, aside| { .child(
this.child( div().children(aside.map(|aside|
WithRemSize::new(ui_font_size) WithRemSize::new(ui_font_size)
.occlude() .occlude()
.elevation_2(cx) .elevation_2(cx)
.p_2() .p_2()
.max_w_96() .overflow_hidden()
.child(aside(cx)), .when(is_wide_window, |this| {this.max_w_96()})
) .when(!is_wide_window, |this| {this.max_w_48()})
}) .child(aside(cx))
))
)
.child( .child(
WithRemSize::new(ui_font_size) WithRemSize::new(ui_font_size)
.occlude() .occlude()