Track focus shenanigans with context menu

Julia and Max Brunsfeld created

Co-Authored-By: Max Brunsfeld <max@zed.dev>

Change summary

crates/terminal_view2/src/terminal_element.rs | 16 +-----------
crates/terminal_view2/src/terminal_view.rs    | 25 ++++++++++----------
crates/ui2/src/components/context_menu.rs     |  6 ----
3 files changed, 15 insertions(+), 32 deletions(-)

Detailed changes

crates/terminal_view2/src/terminal_element.rs 🔗

@@ -5,7 +5,7 @@ use gpui::{
     FontStyle, FontWeight, HighlightStyle, Hsla, InteractiveElement, InteractiveElementState,
     IntoElement, LayoutId, Model, ModelContext, ModifiersChangedEvent, MouseButton, Pixels,
     PlatformInputHandler, Point, Rgba, ShapedLine, Size, StatefulInteractiveElement, Styled,
-    TextRun, TextStyle, TextSystem, UnderlineStyle, View, WhiteSpace, WindowContext,
+    TextRun, TextStyle, TextSystem, UnderlineStyle, WhiteSpace, WindowContext,
 };
 use itertools::Itertools;
 use language::CursorShape;
@@ -27,8 +27,6 @@ use ui::Tooltip;
 use std::mem;
 use std::{fmt::Debug, ops::RangeInclusive};
 
-use crate::TerminalView;
-
 ///The information generated during layout that is necessary for painting
 pub struct LayoutState {
     cells: Vec<LayoutCell>,
@@ -149,7 +147,6 @@ impl LayoutRect {
 ///We need to keep a reference to the view for mouse events, do we need it for any other terminal stuff, or can we move that to connection?
 pub struct TerminalElement {
     terminal: Model<Terminal>,
-    terminal_view: View<TerminalView>,
     focus: FocusHandle,
     focused: bool,
     cursor_visible: bool,
@@ -168,7 +165,6 @@ impl StatefulInteractiveElement for TerminalElement {}
 impl TerminalElement {
     pub fn new(
         terminal: Model<Terminal>,
-        terminal_view: View<TerminalView>,
         focus: FocusHandle,
         focused: bool,
         cursor_visible: bool,
@@ -176,7 +172,6 @@ impl TerminalElement {
     ) -> TerminalElement {
         TerminalElement {
             terminal,
-            terminal_view,
             focused,
             focus: focus.clone(),
             cursor_visible,
@@ -774,18 +769,11 @@ impl Element for TerminalElement {
         (layout_id, interactive_state)
     }
 
-    fn paint(
-        mut self,
-        bounds: Bounds<Pixels>,
-        state: &mut Self::State,
-        cx: &mut WindowContext<'_>,
-    ) {
+    fn paint(self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut WindowContext<'_>) {
         let mut layout = self.compute_layout(bounds, cx);
 
         let theme = cx.theme();
 
-        let dispatch_context = self.terminal_view.read(cx).dispatch_context(cx);
-        self.interactivity().key_context = Some(dispatch_context);
         cx.paint_quad(
             bounds,
             Default::default(),

crates/terminal_view2/src/terminal_view.rs 🔗

@@ -632,7 +632,6 @@ impl Render for TerminalView {
 
     fn render(&mut self, cx: &mut ViewContext<Self>) -> Self::Element {
         let terminal_handle = self.terminal.clone();
-        let this_view = cx.view().clone();
 
         let self_id = cx.entity_id();
         let focused = self.focus_handle.is_focused(cx);
@@ -640,22 +639,25 @@ impl Render for TerminalView {
         div()
             .size_full()
             .relative()
+            .track_focus(&self.focus_handle)
+            .key_context(self.dispatch_context(cx))
+            .on_action(cx.listener(TerminalView::send_text))
+            .on_action(cx.listener(TerminalView::send_keystroke))
+            .on_action(cx.listener(TerminalView::copy))
+            .on_action(cx.listener(TerminalView::paste))
+            .on_action(cx.listener(TerminalView::clear))
+            .on_action(cx.listener(TerminalView::show_character_palette))
+            .on_action(cx.listener(TerminalView::select_all))
+            .on_focus_in(cx.listener(Self::focus_in))
+            .on_focus_out(cx.listener(Self::focus_out))
+            .on_key_down(cx.listener(Self::key_down))
             .child(
                 div()
                     .z_index(0)
                     .absolute()
                     .size_full()
-                    .on_key_down(cx.listener(Self::key_down))
-                    .on_action(cx.listener(TerminalView::send_text))
-                    .on_action(cx.listener(TerminalView::send_keystroke))
-                    .on_action(cx.listener(TerminalView::copy))
-                    .on_action(cx.listener(TerminalView::paste))
-                    .on_action(cx.listener(TerminalView::clear))
-                    .on_action(cx.listener(TerminalView::show_character_palette))
-                    .on_action(cx.listener(TerminalView::select_all))
                     .child(TerminalElement::new(
                         terminal_handle,
-                        this_view,
                         self.focus_handle.clone(),
                         focused,
                         self.should_show_cursor(focused, cx),
@@ -675,9 +677,6 @@ impl Render for TerminalView {
                     .anchor(gpui::AnchorCorner::TopLeft)
                     .child(menu.clone())
             }))
-            .track_focus(&self.focus_handle)
-            .on_focus_in(cx.listener(Self::focus_in))
-            .on_focus_out(cx.listener(Self::focus_out))
     }
 }
 

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

@@ -239,7 +239,6 @@ impl Render for ContextMenu {
                                 action,
                             } => {
                                 let handler = handler.clone();
-                                let dismiss = cx.listener(|_, _, cx| cx.emit(DismissEvent));
 
                                 let label_element = if let Some(icon) = icon {
                                     h_stack()
@@ -263,10 +262,7 @@ impl Render for ContextMenu {
                                             })),
                                     )
                                     .selected(Some(ix) == self.selected_index)
-                                    .on_click(move |event, cx| {
-                                        handler(cx);
-                                        dismiss(event, cx)
-                                    })
+                                    .on_click(move |_, cx| handler(cx))
                                     .into_any_element()
                             }
                         },