Add workspace::FocusCenterPane (#46059)

Josh P. created

solution for #43004

Release Notes:

- Added workspace::FocusCenterPane


The `editor::ToggleFocus` action not working really drives me bonkers,
and it also doesn't really make sense, because it doesn't toggle
anything. it moves focus, but doesn't move focus back anywhere if you
run it again so 'ToggleFocus' seems misleading.

Here we have added an action that just moves focus to the most recent
center pane: `workspace::FocusCenterPane`

this action correctly moves the focus to the center pane from any dock,
even if the center pane is the project diff, branch diff, terminal, or
keymap editor, etc.

i'm not sure if this would be considered a 'replacement' for
`editor::ToggleFocus` but i do think this is probably more in line with
what most users would consider the expected behavior.

Change summary

crates/workspace/src/workspace.rs | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)

Detailed changes

crates/workspace/src/workspace.rs 🔗

@@ -399,7 +399,12 @@ pub struct Save {
     pub save_intent: Option<SaveIntent>,
 }
 
-/// Closes all items and panes in the workspace.
+/// Moves Focus to the central panes in the workspace.
+#[derive(Clone, Debug, PartialEq, Eq, Action)]
+#[action(namespace = workspace)]
+pub struct FocusCenterPane;
+
+///  Closes all items and panes in the workspace.
 #[derive(Clone, PartialEq, Debug, Deserialize, Default, JsonSchema, Action)]
 #[action(namespace = workspace)]
 #[serde(deny_unknown_fields)]
@@ -3824,6 +3829,14 @@ impl Workspace {
         did_focus_panel
     }
 
+    pub fn focus_center_pane(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+        if let Some(item) = self.active_item(cx) {
+            item.item_focus_handle(cx).focus(window, cx);
+        } else {
+            log::error!("Could not find a focus target when switching focus to the center panes",);
+        }
+    }
+
     pub fn activate_panel_for_proto_id(
         &mut self,
         panel_id: PanelId,
@@ -6852,6 +6865,9 @@ impl Workspace {
                     }
                 }),
             )
+            .on_action(cx.listener(|workspace, _: &FocusCenterPane, window, cx| {
+                workspace.focus_center_pane(window, cx);
+            }))
             .on_action(cx.listener(Workspace::cancel))
     }