Bind CloseWindow and Open actions on workspace

Nathan Sobo and Max created

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

Change summary

crates/workspace2/src/workspace2.rs | 171 +++++++++++++++---------------
crates/zed2/src/zed2.rs             |   4 
2 files changed, 86 insertions(+), 89 deletions(-)

Detailed changes

crates/workspace2/src/workspace2.rs 🔗

@@ -210,6 +210,9 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
     init_settings(cx);
     notifications::init(cx);
 
+    cx.on_action(Workspace::close_global);
+    cx.on_action(restart);
+
     cx.on_action({
         let app_state = Arc::downgrade(&app_state);
         move |_: &Open, cx: &mut AppContext| {
@@ -1178,7 +1181,6 @@ impl Workspace {
         }
     }
 
-    // todo!(Non-window-actions)
     pub fn close_global(_: &CloseWindow, cx: &mut AppContext) {
         cx.windows().iter().find(|window| {
             window
@@ -1196,21 +1198,18 @@ impl Workspace {
         });
     }
 
-    pub fn close(
-        &mut self,
-        _: &CloseWindow,
-        cx: &mut ViewContext<Self>,
-    ) -> Option<Task<Result<()>>> {
+    pub fn close_window(&mut self, _: &CloseWindow, cx: &mut ViewContext<Self>) {
         let window = cx.window_handle();
         let prepare = self.prepare_to_close(false, cx);
-        Some(cx.spawn(|_, mut cx| async move {
+        cx.spawn(|_, mut cx| async move {
             if prepare.await? {
                 window.update(&mut cx, |_, cx| {
                     cx.remove_window();
                 })?;
             }
-            Ok(())
-        }))
+            anyhow::Ok(())
+        })
+        .detach_and_log_err(cx)
     }
 
     pub fn prepare_to_close(
@@ -2427,90 +2426,92 @@ impl Workspace {
     //         }))
     //     }
 
-    //     pub fn follow_next_collaborator(
-    //         &mut self,
-    //         _: &FollowNextCollaborator,
-    //         cx: &mut ViewContext<Self>,
-    //     ) -> Option<Task<Result<()>>> {
-    //         let collaborators = self.project.read(cx).collaborators();
-    //         let next_leader_id = if let Some(leader_id) = self.leader_for_pane(&self.active_pane) {
-    //             let mut collaborators = collaborators.keys().copied();
-    //             for peer_id in collaborators.by_ref() {
-    //                 if peer_id == leader_id {
-    //                     break;
-    //                 }
-    //             }
-    //             collaborators.next()
-    //         } else if let Some(last_leader_id) =
-    //             self.last_leaders_by_pane.get(&self.active_pane.downgrade())
-    //         {
-    //             if collaborators.contains_key(last_leader_id) {
-    //                 Some(*last_leader_id)
-    //             } else {
-    //                 None
+    // pub fn follow_next_collaborator(
+    //     &mut self,
+    //     _: &FollowNextCollaborator,
+    //     cx: &mut ViewContext<Self>,
+    // ) {
+    //     let collaborators = self.project.read(cx).collaborators();
+    //     let next_leader_id = if let Some(leader_id) = self.leader_for_pane(&self.active_pane) {
+    //         let mut collaborators = collaborators.keys().copied();
+    //         for peer_id in collaborators.by_ref() {
+    //             if peer_id == leader_id {
+    //                 break;
     //             }
+    //         }
+    //         collaborators.next()
+    //     } else if let Some(last_leader_id) =
+    //         self.last_leaders_by_pane.get(&self.active_pane.downgrade())
+    //     {
+    //         if collaborators.contains_key(last_leader_id) {
+    //             Some(*last_leader_id)
     //         } else {
     //             None
-    //         };
-
-    //         let pane = self.active_pane.clone();
-    //         let Some(leader_id) = next_leader_id.or_else(|| collaborators.keys().copied().next())
-    //         else {
-    //             return None;
-    //         };
-    //         if Some(leader_id) == self.unfollow(&pane, cx) {
-    //             return None;
     //         }
-    //         self.follow(leader_id, cx)
+    //     } else {
+    //         None
+    //     };
+
+    //     let pane = self.active_pane.clone();
+    //     let Some(leader_id) = next_leader_id.or_else(|| collaborators.keys().copied().next())
+    //     else {
+    //         return;
+    //     };
+    //     if Some(leader_id) == self.unfollow(&pane, cx) {
+    //         return;
     //     }
+    //     if let Some(task) = self.follow(leader_id, cx) {
+    //         task.detach();
+    //     }
+    // }
 
-    //     pub fn follow(
-    //         &mut self,
-    //         leader_id: PeerId,
-    //         cx: &mut ViewContext<Self>,
-    //     ) -> Option<Task<Result<()>>> {
-    //         let room = ActiveCall::global(cx).read(cx).room()?.read(cx);
-    //         let project = self.project.read(cx);
-
-    //         let Some(remote_participant) = room.remote_participant_for_peer_id(leader_id) else {
-    //             return None;
-    //         };
-
-    //         let other_project_id = match remote_participant.location {
-    //             call::ParticipantLocation::External => None,
-    //             call::ParticipantLocation::UnsharedProject => None,
-    //             call::ParticipantLocation::SharedProject { project_id } => {
-    //                 if Some(project_id) == project.remote_id() {
-    //                     None
-    //                 } else {
-    //                     Some(project_id)
-    //                 }
+    // pub fn follow(
+    //     &mut self,
+    //     leader_id: PeerId,
+    //     cx: &mut ViewContext<Self>,
+    // ) -> Option<Task<Result<()>>> {
+    //     let room = ActiveCall::global(cx).read(cx).room()?.read(cx);
+    //     let project = self.project.read(cx);
+
+    //     let Some(remote_participant) = room.remote_participant_for_peer_id(leader_id) else {
+    //         return None;
+    //     };
+
+    //     let other_project_id = match remote_participant.location {
+    //         call::ParticipantLocation::External => None,
+    //         call::ParticipantLocation::UnsharedProject => None,
+    //         call::ParticipantLocation::SharedProject { project_id } => {
+    //             if Some(project_id) == project.remote_id() {
+    //                 None
+    //             } else {
+    //                 Some(project_id)
     //             }
-    //         };
-
-    //         // if they are active in another project, follow there.
-    //         if let Some(project_id) = other_project_id {
-    //             let app_state = self.app_state.clone();
-    //             return Some(crate::join_remote_project(
-    //                 project_id,
-    //                 remote_participant.user.id,
-    //                 app_state,
-    //                 cx,
-    //             ));
     //         }
+    //     };
 
-    //         // if you're already following, find the right pane and focus it.
-    //         for (pane, state) in &self.follower_states {
-    //             if leader_id == state.leader_id {
-    //                 cx.focus(pane);
-    //                 return None;
-    //             }
-    //         }
+    //     // if they are active in another project, follow there.
+    //     if let Some(project_id) = other_project_id {
+    //         let app_state = self.app_state.clone();
+    //         return Some(crate::join_remote_project(
+    //             project_id,
+    //             remote_participant.user.id,
+    //             app_state,
+    //             cx,
+    //         ));
+    //     }
 
-    //         // Otherwise, follow.
-    //         self.start_following(leader_id, cx)
+    //     // if you're already following, find the right pane and focus it.
+    //     for (pane, state) in &self.follower_states {
+    //         if leader_id == state.leader_id {
+    //             cx.focus(pane);
+    //             return None;
+    //         }
     //     }
 
+    //     // Otherwise, follow.
+    //     self.start_following(leader_id, cx)
+    // }
+
     pub fn unfollow(&mut self, pane: &View<Pane>, cx: &mut ViewContext<Self>) -> Option<PeerId> {
         let follower_states = &mut self.follower_states;
         let state = follower_states.remove(pane)?;
@@ -3287,13 +3288,8 @@ impl Workspace {
 
     fn actions(&self, div: Div, cx: &mut ViewContext<Self>) -> Div {
         self.add_workspace_actions_listeners(div, cx)
-            //     cx.add_async_action(Workspace::open);
-            //     cx.add_async_action(Workspace::follow_next_collaborator);
-            //     cx.add_async_action(Workspace::close);
             .on_action(cx.listener(Self::close_inactive_items_and_panes))
             .on_action(cx.listener(Self::close_all_items_and_panes))
-            //     cx.add_global_action(Workspace::close_global);
-            //     cx.add_global_action(restart);
             .on_action(cx.listener(Self::save_all))
             .on_action(cx.listener(Self::add_folder_to_project))
             .on_action(cx.listener(|workspace, _: &Unfollow, cx| {
@@ -3342,6 +3338,9 @@ impl Workspace {
                     workspace.close_all_docks(cx);
                 }),
             )
+            .on_action(cx.listener(Workspace::open))
+            .on_action(cx.listener(Workspace::close_window))
+
         //     cx.add_action(Workspace::activate_pane_at_index);
         //     cx.add_action(|workspace: &mut Workspace, _: &ReopenClosedItem, cx| {
         //         workspace.reopen_closed_item(cx).detach();

crates/zed2/src/zed2.rs 🔗

@@ -168,9 +168,7 @@ pub fn initialize_workspace(app_state: Arc<AppState>, cx: &mut AppContext) {
         cx.on_window_should_close(move |cx| {
             handle
                 .update(cx, |workspace, cx| {
-                    if let Some(task) = workspace.close(&Default::default(), cx) {
-                        task.detach_and_log_err(cx);
-                    }
+                    workspace.close_window(&Default::default(), cx);
                     false
                 })
                 .unwrap_or(true)