agent: Fix message editor's button positions when expanded (#30311)

Agus Zubiaga created

Fixes an issue introduced by #29959 which caused the message editor to
overflow from the agent panel bounds, making the bottom buttons
invisible when the editor was expanded (cmd+esc).

Fixing this required changing the base structure of the agent panel, but
things seem to work as expected:


https://github.com/user-attachments/assets/fc4c97fb-f7cb-4f54-a268-c30fbcb1649f


Release Notes:

- agent: Fix message editor's button positions when expanded

Change summary

crates/agent/src/agent_panel.rs | 78 ++++++++++++++++++----------------
1 file changed, 41 insertions(+), 37 deletions(-)

Detailed changes

crates/agent/src/agent_panel.rs πŸ”—

@@ -2744,42 +2744,16 @@ impl AgentPanel {
 
 impl Render for AgentPanel {
     fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let content = match &self.active_view {
-            ActiveView::Thread { .. } => v_flex()
-                .relative()
-                .justify_between()
-                .size_full()
-                .child(self.render_active_thread_or_empty_state(window, cx))
-                .children(self.render_tool_use_limit_reached(cx))
-                .child(h_flex().child(self.message_editor.clone()))
-                .children(self.render_last_error(cx))
-                .child(self.render_drag_target(cx))
-                .into_any(),
-            ActiveView::History => self.history.clone().into_any_element(),
-            ActiveView::PromptEditor {
-                context_editor,
-                buffer_search_bar,
-                ..
-            } => self
-                .render_prompt_editor(context_editor, buffer_search_bar, window, cx)
-                .into_any(),
-            ActiveView::Configuration => v_flex()
-                .size_full()
-                .children(self.configuration.clone())
-                .into_any(),
-        };
-
-        let content = match self.active_view.which_font_size_used() {
-            WhichFontSize::AgentFont => {
-                WithRemSize::new(ThemeSettings::get_global(cx).agent_font_size(cx))
-                    .size_full()
-                    .child(content)
-                    .into_any()
-            }
-            _ => content,
-        };
-
-        v_flex()
+        // WARNING: Changes to this element hierarchy can have
+        // non-obvious implications to the layout of children.
+        //
+        // If you need to change it, please confirm:
+        // - The message editor expands (⌘esc) correctly
+        // - When expanded, the buttons at the bottom of the panel are displayed correctly
+        // - Font size works as expected and can be changed with ⌘+/⌘-
+        // - Scrolling in all views works as expected
+        // - Files can be dropped into the panel
+        let content = v_flex()
             .key_context(self.key_context())
             .justify_between()
             .size_full()
@@ -2804,7 +2778,37 @@ impl Render for AgentPanel {
             .on_action(cx.listener(Self::reset_font_size))
             .child(self.render_toolbar(window, cx))
             .children(self.render_trial_upsell(window, cx))
-            .child(content)
+            .map(|parent| match &self.active_view {
+                ActiveView::Thread { .. } => parent
+                    .relative()
+                    .child(self.render_active_thread_or_empty_state(window, cx))
+                    .children(self.render_tool_use_limit_reached(cx))
+                    .child(h_flex().child(self.message_editor.clone()))
+                    .children(self.render_last_error(cx))
+                    .child(self.render_drag_target(cx)),
+                ActiveView::History => parent.child(self.history.clone()),
+                ActiveView::PromptEditor {
+                    context_editor,
+                    buffer_search_bar,
+                    ..
+                } => parent.child(self.render_prompt_editor(
+                    context_editor,
+                    buffer_search_bar,
+                    window,
+                    cx,
+                )),
+                ActiveView::Configuration => parent.children(self.configuration.clone()),
+            });
+
+        match self.active_view.which_font_size_used() {
+            WhichFontSize::AgentFont => {
+                WithRemSize::new(ThemeSettings::get_global(cx).agent_font_size(cx))
+                    .size_full()
+                    .child(content)
+                    .into_any()
+            }
+            _ => content.into_any(),
+        }
     }
 }