summaryrefslogtreecommitdiffstats
path: root/zellij-server
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2023-08-25 12:24:43 +0200
committerGitHub <noreply@github.com>2023-08-25 12:24:43 +0200
commitb44ba85895b4db3a67a0f5c329c62fe120079ff0 (patch)
treeff34fb572a4ca5e0ff71fc0db9bacb9ef3c56093 /zellij-server
parent877c467f9f757ca560d77ceef83456c9a50f4917 (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.rs3
-rw-r--r--zellij-server/src/screen.rs49
-rw-r--r--zellij-server/src/tab/mod.rs43
-rw-r--r--zellij-server/src/unit/screen_tests.rs2
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(),
};