debugger: Fix focus nits (#30547)

Cole Miller , Piotr , and Anthony created

- Focus the console's query bar (if it exists) when focusing the console
- Fix incorrect focus handles used for the console and terminal at the
`Subview` level

Release Notes:

- N/A

Co-authored-by: Piotr <piotr@zed.dev>
Co-authored-by: Anthony <anthony@zed.dev>

Change summary

crates/debugger_ui/src/persistence.rs             |  4 ++--
crates/debugger_ui/src/session/running.rs         | 14 ++++++++------
crates/debugger_ui/src/session/running/console.rs | 17 +++++++++++------
3 files changed, 21 insertions(+), 14 deletions(-)

Detailed changes

crates/debugger_ui/src/persistence.rs 🔗

@@ -278,7 +278,7 @@ pub(crate) fn deserialize_pane_layout(
                         cx,
                     )),
                     DebuggerPaneItem::Console => Box::new(SubView::new(
-                        pane.focus_handle(cx),
+                        console.focus_handle(cx),
                         console.clone().into(),
                         DebuggerPaneItem::Console,
                         Some(Box::new({
@@ -292,7 +292,7 @@ pub(crate) fn deserialize_pane_layout(
                         cx,
                     )),
                     DebuggerPaneItem::Terminal => Box::new(SubView::new(
-                        pane.focus_handle(cx),
+                        terminal.focus_handle(cx),
                         terminal.clone().into(),
                         DebuggerPaneItem::Terminal,
                         None,

crates/debugger_ui/src/session/running.rs 🔗

@@ -119,7 +119,7 @@ impl Render for RunningState {
 
 pub(crate) struct SubView {
     inner: AnyView,
-    pane_focus_handle: FocusHandle,
+    item_focus_handle: FocusHandle,
     kind: DebuggerPaneItem,
     show_indicator: Box<dyn Fn(&App) -> bool>,
     hovered: bool,
@@ -127,7 +127,7 @@ pub(crate) struct SubView {
 
 impl SubView {
     pub(crate) fn new(
-        pane_focus_handle: FocusHandle,
+        item_focus_handle: FocusHandle,
         view: AnyView,
         kind: DebuggerPaneItem,
         show_indicator: Option<Box<dyn Fn(&App) -> bool>>,
@@ -136,7 +136,7 @@ impl SubView {
         cx.new(|_| Self {
             kind,
             inner: view,
-            pane_focus_handle,
+            item_focus_handle,
             show_indicator: show_indicator.unwrap_or(Box::new(|_| false)),
             hovered: false,
         })
@@ -148,7 +148,7 @@ impl SubView {
 }
 impl Focusable for SubView {
     fn focus_handle(&self, _: &App) -> FocusHandle {
-        self.pane_focus_handle.clone()
+        self.item_focus_handle.clone()
     }
 }
 impl EventEmitter<()> for SubView {}
@@ -199,7 +199,7 @@ impl Render for SubView {
             .size_full()
             // Add border unconditionally to prevent layout shifts on focus changes.
             .border_1()
-            .when(self.pane_focus_handle.contains_focused(window, cx), |el| {
+            .when(self.item_focus_handle.contains_focused(window, cx), |el| {
                 el.border_color(cx.theme().colors().pane_focused_border)
             })
             .child(self.inner.clone())
@@ -1202,7 +1202,9 @@ impl RunningState {
             .as_ref()
             .and_then(|pane| self.panes.find_pane_in_direction(pane, direction, cx))
         {
-            window.focus(&pane.focus_handle(cx));
+            pane.update(cx, |pane, cx| {
+                pane.focus_active_item(window, cx);
+            })
         } else {
             self.workspace
                 .update(cx, |workspace, cx| {

crates/debugger_ui/src/session/running/console.rs 🔗

@@ -62,6 +62,7 @@ impl Console {
             editor.set_soft_wrap_mode(language::language_settings::SoftWrap::EditorWidth, cx);
             editor
         });
+        let focus_handle = cx.focus_handle();
 
         let this = cx.weak_entity();
         let query_bar = cx.new(|cx| {
@@ -76,10 +77,14 @@ impl Console {
             editor
         });
 
-        let focus_handle = query_bar.focus_handle(cx);
-
-        let _subscriptions =
-            vec![cx.subscribe(&stack_frame_list, Self::handle_stack_frame_list_events)];
+        let _subscriptions = vec![
+            cx.subscribe(&stack_frame_list, Self::handle_stack_frame_list_events),
+            cx.on_focus_in(&focus_handle, window, |console, window, cx| {
+                if console.is_running(cx) {
+                    console.query_bar.focus_handle(cx).focus(window);
+                }
+            }),
+        ];
 
         Self {
             session,
@@ -99,7 +104,7 @@ impl Console {
         &self.console
     }
 
-    fn is_local(&self, cx: &Context<Self>) -> bool {
+    fn is_running(&self, cx: &Context<Self>) -> bool {
         self.session.read(cx).is_local()
     }
 
@@ -221,7 +226,7 @@ impl Render for Console {
             .on_action(cx.listener(Self::evaluate))
             .size_full()
             .child(self.render_console(cx))
-            .when(self.is_local(cx), |this| {
+            .when(self.is_running(cx), |this| {
                 this.child(Divider::horizontal())
                     .child(self.render_query_bar(cx))
             })