diff options
author | Aram Drevekenin <aram@poor.dev> | 2023-08-25 12:24:43 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-25 12:24:43 +0200 |
commit | b44ba85895b4db3a67a0f5c329c62fe120079ff0 (patch) | |
tree | ff34fb572a4ca5e0ff71fc0db9bacb9ef3c56093 /zellij-server | |
parent | 877c467f9f757ca560d77ceef83456c9a50f4917 (diff) |
feat(plugins): optionally move plugin to focused tab (#2725)
* feat(plugins): move_to_focused_tab attribute for LaunchOrFocusPlugin
* style(fmt): rustfmt
Diffstat (limited to 'zellij-server')
-rw-r--r-- | zellij-server/src/route.rs | 3 | ||||
-rw-r--r-- | zellij-server/src/screen.rs | 49 | ||||
-rw-r--r-- | zellij-server/src/tab/mod.rs | 43 | ||||
-rw-r--r-- | zellij-server/src/unit/screen_tests.rs | 2 |
4 files changed, 91 insertions, 6 deletions
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index 26b551866..b29dd934f 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -621,11 +621,12 @@ pub(crate) fn route_action( .send_to_screen(ScreenInstruction::StartOrReloadPluginPane(run_plugin, None)) .with_context(err_context)?; }, - Action::LaunchOrFocusPlugin(run_plugin, should_float) => { + Action::LaunchOrFocusPlugin(run_plugin, should_float, move_to_focused_tab) => { senders .send_to_screen(ScreenInstruction::LaunchOrFocusPlugin( run_plugin, should_float, + move_to_focused_tab, client_id, )) .with_context(err_context)?; diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 2c018dcf3..8015075fc 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -281,9 +281,9 @@ pub enum ScreenInstruction { StartPluginLoadingIndication(u32, LoadingIndication), // u32 - plugin_id ProgressPluginLoadingOffset(u32), // u32 - plugin id RequestStateUpdateForPlugins, - LaunchOrFocusPlugin(RunPlugin, bool, ClientId), // bool is should_float - SuppressPane(PaneId, ClientId), // bool is should_float - FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float + LaunchOrFocusPlugin(RunPlugin, bool, bool, ClientId), // bools are: should_float, move_to_focused_tab + SuppressPane(PaneId, ClientId), // bool is should_float + FocusPaneWithId(PaneId, bool, ClientId), // bool is should_float RenamePane(PaneId, Vec<u8>), RenameTab(usize, Vec<u8>), RequestPluginPermissions( @@ -1618,18 +1618,47 @@ impl Screen { &mut self, run_plugin: &RunPlugin, should_float: bool, + move_to_focused_tab: bool, client_id: ClientId, ) -> Result<bool> { // true => found and focused, false => not let err_context = || format!("failed to focus_plugin_pane"); let mut tab_index_and_plugin_pane_id = None; + let mut plugin_pane_to_move_to_active_tab = None; + let focused_tab_index = *self.active_tab_indices.get(&client_id).unwrap_or(&0); let all_tabs = self.get_tabs_mut(); for (tab_index, tab) in all_tabs.iter_mut() { if let Some(plugin_pane_id) = tab.find_plugin(&run_plugin) { tab_index_and_plugin_pane_id = Some((*tab_index, plugin_pane_id)); + if move_to_focused_tab && focused_tab_index != *tab_index { + plugin_pane_to_move_to_active_tab = + tab.extract_pane(plugin_pane_id, Some(client_id)); + } + break; } } + if let Some(plugin_pane_to_move_to_active_tab) = plugin_pane_to_move_to_active_tab.take() { + let pane_id = plugin_pane_to_move_to_active_tab.pid(); + let new_active_tab = self.get_active_tab_mut(client_id)?; + + if should_float { + new_active_tab.show_floating_panes(); + new_active_tab.add_floating_pane( + plugin_pane_to_move_to_active_tab, + pane_id, + Some(client_id), + )?; + } else { + new_active_tab.hide_floating_panes(); + new_active_tab.add_tiled_pane( + plugin_pane_to_move_to_active_tab, + pane_id, + Some(client_id), + )?; + } + return Ok(true); + } match tab_index_and_plugin_pane_id { Some((tab_index, plugin_pane_id)) => { self.go_to_tab(tab_index + 1, client_id)?; @@ -2969,7 +2998,12 @@ pub(crate) fn screen_thread_main( screen.log_and_report_session_state()?; screen.render()?; }, - ScreenInstruction::LaunchOrFocusPlugin(run_plugin, should_float, client_id) => { + ScreenInstruction::LaunchOrFocusPlugin( + run_plugin, + should_float, + move_to_focused_tab, + client_id, + ) => { let client_id = if screen.active_tab_indices.contains_key(&client_id) { Some(client_id) } else { @@ -2983,7 +3017,12 @@ pub(crate) fn screen_thread_main( }); match client_id_and_focused_tab { Some((tab_index, client_id)) => { - if screen.focus_plugin_pane(&run_plugin, should_float, client_id)? { + if screen.focus_plugin_pane( + &run_plugin, + should_float, + move_to_focused_tab, + client_id, + )? { screen.render()?; screen.log_and_report_session_state()?; } else { diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 2da5306a9..799cebcb2 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -2245,6 +2245,49 @@ impl Tab { closed_pane } } + pub fn extract_pane( + &mut self, + id: PaneId, + client_id: Option<ClientId>, + ) -> Option<Box<dyn Pane>> { + if self.floating_panes.panes_contain(&id) { + let closed_pane = self.floating_panes.remove_pane(id); + self.floating_panes.move_clients_out_of_pane(id); + if !self.floating_panes.has_panes() { + self.hide_floating_panes(); + } + self.set_force_render(); + self.floating_panes.set_force_render(); + if self.auto_layout + && !self.swap_layouts.is_floating_damaged() + && self.floating_panes.visible_panes_count() > 0 + { + self.swap_layouts.set_is_floating_damaged(); + // only relayout if the user is already "in" a layout, otherwise this might be + // confusing + let _ = self.next_swap_layout(client_id, false); + } + closed_pane + } else if self.tiled_panes.panes_contain(&id) { + if self.tiled_panes.fullscreen_is_active() { + self.tiled_panes.unset_fullscreen(); + } + let closed_pane = self.tiled_panes.remove_pane(id); + self.set_force_render(); + self.tiled_panes.set_force_render(); + if self.auto_layout && !self.swap_layouts.is_tiled_damaged() { + self.swap_layouts.set_is_tiled_damaged(); + // only relayout if the user is already "in" a layout, otherwise this might be + // confusing + let _ = self.next_swap_layout(client_id, false); + } + closed_pane + } else if self.suppressed_panes.contains_key(&id) { + self.suppressed_panes.remove(&id) + } else { + None + } + } pub fn hold_pane( &mut self, id: PaneId, diff --git a/zellij-server/src/unit/screen_tests.rs b/zellij-server/src/unit/screen_tests.rs index 8d1debd35..2f123ddcc 100644 --- a/zellij-server/src/unit/screen_tests.rs +++ b/zellij-server/src/unit/screen_tests.rs @@ -2564,6 +2564,7 @@ pub fn send_cli_launch_or_focus_plugin_action() { ); let cli_action = CliAction::LaunchOrFocusPlugin { floating: true, + move_to_focused_tab: true, url: url::Url::parse("file:/path/to/fake/plugin").unwrap(), configuration: Default::default(), }; @@ -2621,6 +2622,7 @@ pub fn send_cli_launch_or_focus_plugin_action_when_plugin_is_already_loaded() { ); let cli_action = CliAction::LaunchOrFocusPlugin { floating: true, + move_to_focused_tab: true, url: url::Url::parse("file:/path/to/fake/plugin").unwrap(), configuration: Default::default(), }; |