move actions from sidebar trait to multiworkspace

cameron created

Change summary

crates/sidebar/src/sidebar.rs           |  21 ----
crates/workspace/src/multi_workspace.rs | 132 ++++++++------------------
crates/workspace/src/workspace.rs       |   5 
3 files changed, 42 insertions(+), 116 deletions(-)

Detailed changes

crates/sidebar/src/sidebar.rs 🔗

@@ -3823,27 +3823,6 @@ impl WorkspaceSidebar for Sidebar {
         cx.notify();
     }
 
-    fn toggle_thread_switcher(
-        &mut self,
-        select_last: bool,
-        window: &mut Window,
-        cx: &mut Context<Self>,
-    ) {
-        self.toggle_thread_switcher_impl(select_last, window, cx);
-    }
-
-    fn cycle_project(&mut self, forward: bool, window: &mut Window, cx: &mut Context<Self>) {
-        self.cycle_project_impl(forward, window, cx);
-    }
-
-    fn cycle_thread(&mut self, forward: bool, window: &mut Window, cx: &mut Context<Self>) {
-        self.cycle_thread_impl(forward, window, cx);
-    }
-
-    fn move_workspace_to_new_window(&mut self, window: &mut Window, cx: &mut Context<Self>) {
-        self.on_move_workspace_to_new_window(&MoveWorkspaceToNewWindow, window, cx);
-    }
-
     fn serialized_state(&self, _cx: &App) -> Option<String> {
         let serialized = SerializedSidebar {
             width: Some(f32::from(self.width)),

crates/workspace/src/multi_workspace.rs 🔗

@@ -2,9 +2,9 @@ use anyhow::Result;
 use feature_flags::{AgentV2FeatureFlag, FeatureFlagAppExt};
 use gpui::PathPromptOptions;
 use gpui::{
-    AnyView, App, Context, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle, Focusable,
-    ManagedView, MouseButton, Pixels, Render, Subscription, Task, Tiling, Window, WindowId,
-    actions, deferred, px,
+    Action as _, AnyView, App, Context, DragMoveEvent, Entity, EntityId, EventEmitter, FocusHandle,
+    Focusable, ManagedView, MouseButton, Pixels, Render, Subscription, Task, Tiling, Window,
+    WindowId, actions, deferred, px,
 };
 use project::{DirectoryLister, DisableAiSettings, Project, ProjectGroupKey};
 use settings::Settings;
@@ -120,23 +120,6 @@ pub trait Sidebar: Focusable + Render + EventEmitter<SidebarEvent> + Sized {
     }
     /// Makes focus reset back to the search editor upon toggling the sidebar from outside
     fn prepare_for_focus(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {}
-    /// Opens or cycles the thread switcher popup.
-    fn toggle_thread_switcher(
-        &mut self,
-        _select_last: bool,
-        _window: &mut Window,
-        _cx: &mut Context<Self>,
-    ) {
-    }
-
-    /// Activates the next or previous project group.
-    fn cycle_project(&mut self, _forward: bool, _window: &mut Window, _cx: &mut Context<Self>) {}
-
-    /// Activates the next or previous thread in sidebar order.
-    fn cycle_thread(&mut self, _forward: bool, _window: &mut Window, _cx: &mut Context<Self>) {}
-
-    /// Moves the active workspace's project group to a new window.
-    fn move_workspace_to_new_window(&mut self, _window: &mut Window, _cx: &mut Context<Self>) {}
 
     /// Return an opaque JSON blob of sidebar-specific state to persist.
     fn serialized_state(&self, _cx: &App) -> Option<String> {
@@ -162,11 +145,6 @@ pub trait SidebarHandle: 'static + Send + Sync {
     fn has_notifications(&self, cx: &App) -> bool;
     fn to_any(&self) -> AnyView;
     fn entity_id(&self) -> EntityId;
-    fn toggle_thread_switcher(&self, select_last: bool, window: &mut Window, cx: &mut App);
-    fn cycle_project(&self, forward: bool, window: &mut Window, cx: &mut App);
-    fn cycle_thread(&self, forward: bool, window: &mut Window, cx: &mut App);
-    fn move_workspace_to_new_window(&self, window: &mut Window, cx: &mut App);
-
     fn is_threads_list_view_active(&self, cx: &App) -> bool;
 
     fn side(&self, cx: &App) -> SidebarSide;
@@ -217,42 +195,6 @@ impl<T: Sidebar> SidebarHandle for Entity<T> {
         Entity::entity_id(self)
     }
 
-    fn toggle_thread_switcher(&self, select_last: bool, window: &mut Window, cx: &mut App) {
-        let entity = self.clone();
-        window.defer(cx, move |window, cx| {
-            entity.update(cx, |this, cx| {
-                this.toggle_thread_switcher(select_last, window, cx);
-            });
-        });
-    }
-
-    fn cycle_project(&self, forward: bool, window: &mut Window, cx: &mut App) {
-        let entity = self.clone();
-        window.defer(cx, move |window, cx| {
-            entity.update(cx, |this, cx| {
-                this.cycle_project(forward, window, cx);
-            });
-        });
-    }
-
-    fn cycle_thread(&self, forward: bool, window: &mut Window, cx: &mut App) {
-        let entity = self.clone();
-        window.defer(cx, move |window, cx| {
-            entity.update(cx, |this, cx| {
-                this.cycle_thread(forward, window, cx);
-            });
-        });
-    }
-
-    fn move_workspace_to_new_window(&self, window: &mut Window, cx: &mut App) {
-        let entity = self.clone();
-        window.defer(cx, move |window, cx| {
-            entity.update(cx, |this, cx| {
-                this.move_workspace_to_new_window(window, cx);
-            });
-        });
-    }
-
     fn is_threads_list_view_active(&self, cx: &App) -> bool {
         self.read(cx).is_threads_list_view_active()
     }
@@ -492,6 +434,20 @@ impl MultiWorkspace {
         }
     }
 
+    fn dispatch_to_sidebar(
+        &self,
+        action: Box<dyn gpui::Action>,
+        window: &mut Window,
+        cx: &mut App,
+    ) {
+        if let Some(sidebar) = &self.sidebar {
+            let focus_handle = sidebar.focus_handle(cx);
+            window.defer(cx, move |window, cx| {
+                focus_handle.dispatch_action(&*action, window, cx);
+            });
+        }
+    }
+
     pub fn open_sidebar(&mut self, cx: &mut Context<Self>) {
         self.sidebar_open = true;
         if let ActiveWorkspace::Transient(workspace) = &self.active_workspace {
@@ -1502,40 +1458,32 @@ impl Render for MultiWorkspace {
                     ))
                     .on_action(cx.listener(
                         |this: &mut Self, action: &ToggleThreadSwitcher, window, cx| {
-                            if let Some(sidebar) = &this.sidebar {
-                                sidebar.toggle_thread_switcher(action.select_last, window, cx);
-                            }
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
                         },
                     ))
-                    .on_action(cx.listener(|this: &mut Self, _: &NextProject, window, cx| {
-                        if let Some(sidebar) = &this.sidebar {
-                            sidebar.cycle_project(true, window, cx);
-                        }
-                    }))
-                    .on_action(
-                        cx.listener(|this: &mut Self, _: &PreviousProject, window, cx| {
-                            if let Some(sidebar) = &this.sidebar {
-                                sidebar.cycle_project(false, window, cx);
-                            }
-                        }),
-                    )
-                    .on_action(cx.listener(|this: &mut Self, _: &NextThread, window, cx| {
-                        if let Some(sidebar) = &this.sidebar {
-                            sidebar.cycle_thread(true, window, cx);
-                        }
-                    }))
-                    .on_action(
-                        cx.listener(|this: &mut Self, _: &PreviousThread, window, cx| {
-                            if let Some(sidebar) = &this.sidebar {
-                                sidebar.cycle_thread(false, window, cx);
-                            }
-                        }),
-                    )
                     .on_action(cx.listener(
-                        |this: &mut Self, _: &MoveWorkspaceToNewWindow, window, cx| {
-                            if let Some(sidebar) = &this.sidebar {
-                                sidebar.move_workspace_to_new_window(window, cx);
-                            }
+                        |this: &mut Self, action: &NextProject, window, cx| {
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
+                        },
+                    ))
+                    .on_action(cx.listener(
+                        |this: &mut Self, action: &PreviousProject, window, cx| {
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
+                        },
+                    ))
+                    .on_action(cx.listener(
+                        |this: &mut Self, action: &NextThread, window, cx| {
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
+                        },
+                    ))
+                    .on_action(cx.listener(
+                        |this: &mut Self, action: &PreviousThread, window, cx| {
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
+                        },
+                    ))
+                    .on_action(cx.listener(
+                        |this: &mut Self, action: &MoveWorkspaceToNewWindow, window, cx| {
+                            this.dispatch_to_sidebar(action.boxed_clone(), window, cx);
                         },
                     ))
                 })

crates/workspace/src/workspace.rs 🔗

@@ -33,9 +33,8 @@ pub use dock::Panel;
 pub use multi_workspace::{
     CloseWorkspaceSidebar, DraggedSidebar, FocusWorkspaceSidebar, MoveWorkspaceToNewWindow,
     MultiWorkspace, MultiWorkspaceEvent, NewThread, NextProject, NextThread, PreviousProject,
-    PreviousThread, ShowFewerThreads, ShowMoreThreads, Sidebar, SidebarEvent,
-    SidebarHandle, SidebarRenderState, SidebarSide, ToggleWorkspaceSidebar,
-    sidebar_side_context_menu,
+    PreviousThread, ShowFewerThreads, ShowMoreThreads, Sidebar, SidebarEvent, SidebarHandle,
+    SidebarRenderState, SidebarSide, ToggleWorkspaceSidebar, sidebar_side_context_menu,
 };
 pub use path_list::{PathList, SerializedPathList};
 pub use toast_layer::{ToastAction, ToastLayer, ToastView};