context menu: Improve docs aside responsiveness (#25347)

Danilo Leal , Agus Zubiaga , and Nate Butler created

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>

Change summary

crates/inline_completion_button/src/inline_completion_button.rs | 26 +-
crates/ui/src/components/context_menu.rs                        | 19 +
2 files changed, 30 insertions(+), 15 deletions(-)

Detailed changes

crates/inline_completion_button/src/inline_completion_button.rs 🔗

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

crates/ui/src/components/context_menu.rs 🔗

@@ -507,6 +507,9 @@ impl ContextMenuItem {
 impl Render for ContextMenu {
     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 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
             .documentation_aside
@@ -514,19 +517,23 @@ impl Render for ContextMenu {
             .map(|(_, callback)| callback.clone());
 
         h_flex()
+            .when(is_wide_window, |this| {this.flex_row()})
+            .when(!is_wide_window, |this| {this.flex_col()})
             .w_full()
             .items_start()
             .gap_1()
-            .when_some(aside, |this, aside| {
-                this.child(
+            .child(
+                div().children(aside.map(|aside|
                     WithRemSize::new(ui_font_size)
                         .occlude()
                         .elevation_2(cx)
                         .p_2()
-                        .max_w_96()
-                        .child(aside(cx)),
-                )
-            })
+                        .overflow_hidden()
+                        .when(is_wide_window, |this| {this.max_w_96()})
+                        .when(!is_wide_window, |this| {this.max_w_48()})
+                        .child(aside(cx))
+                ))
+            )
             .child(
                 WithRemSize::new(ui_font_size)
                     .occlude()