workspace: Add new "close active dock" action for closing any focused dock (#30369)

Ben Brandt created

This is a more generic implementation of
https://github.com/zed-industries/zed/pull/30360

This also removes the need for a separate close action for the git
panel.

The downside is maybe it is harder to find since it is less specific.

Release Notes:

- workspace: Added new `workspace: close active dock` action to close
the currently focused dock

Change summary

crates/workspace/src/workspace.rs | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)

Detailed changes

crates/workspace/src/workspace.rs 🔗

@@ -160,6 +160,7 @@ actions!(
         ActivatePreviousWindow,
         AddFolderToProject,
         ClearAllNotifications,
+        CloseActiveDock,
         CloseAllDocks,
         CloseWindow,
         Feedback,
@@ -2736,6 +2737,20 @@ impl Workspace {
         self.serialize_workspace(window, cx);
     }
 
+    fn active_dock(&self, window: &Window, cx: &Context<Self>) -> Option<&Entity<Dock>> {
+        self.all_docks().into_iter().find(|&dock| {
+            dock.read(cx).is_open() && dock.focus_handle(cx).contains_focused(window, cx)
+        })
+    }
+
+    fn close_active_dock(&mut self, window: &mut Window, cx: &mut Context<Self>) {
+        if let Some(dock) = self.active_dock(window, cx) {
+            dock.update(cx, |dock, cx| {
+                dock.set_open(false, window, cx);
+            });
+        }
+    }
+
     pub fn close_all_docks(&mut self, window: &mut Window, cx: &mut Context<Self>) {
         for dock in self.all_docks() {
             dock.update(cx, |dock, cx| {
@@ -5296,6 +5311,11 @@ impl Workspace {
                     workspace.toggle_dock(DockPosition::Bottom, window, cx);
                 },
             ))
+            .on_action(cx.listener(
+                |workspace: &mut Workspace, _: &CloseActiveDock, window, cx| {
+                    workspace.close_active_dock(window, cx);
+                },
+            ))
             .on_action(
                 cx.listener(|workspace: &mut Workspace, _: &CloseAllDocks, window, cx| {
                     workspace.close_all_docks(window, cx);