diff options
Diffstat (limited to 'zellij-server/src/tab/mod.rs')
-rw-r--r-- | zellij-server/src/tab/mod.rs | 146 |
1 files changed, 143 insertions, 3 deletions
diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index a2eb79203..1c1a77ac8 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -18,7 +18,7 @@ use zellij_utils::{position::Position, serde}; use crate::background_jobs::BackgroundJob; use crate::pty_writer::PtyWriteInstruction; use crate::screen::CopyOptions; -use crate::ui::pane_boundaries_frame::FrameParams; +use crate::ui::{loading_indication::LoadingIndication, pane_boundaries_frame::FrameParams}; use layout_applier::LayoutApplier; use swap_layouts::SwapLayouts; @@ -28,7 +28,7 @@ use crate::{ output::{CharacterChunk, Output, SixelImageChunk}, panes::sixel::SixelImageStore, panes::{FloatingPanes, TiledPanes}, - panes::{LinkHandler, PaneId, TerminalPane}, + panes::{LinkHandler, PaneId, PluginPane, TerminalPane}, plugins::PluginInstruction, pty::{ClientOrTabIndex, PtyInstruction, VteBytes}, thread_bus::ThreadSenders, @@ -438,6 +438,8 @@ pub trait Pane { fn frame_color_override(&self) -> Option<PaletteColor>; fn invoked_with(&self) -> &Option<Run>; fn set_title(&mut self, title: String); + fn update_loading_indication(&mut self, _loading_indication: LoadingIndication) {} // only relevant for plugins + fn progress_animation_offset(&mut self) {} // only relevant for plugins } #[derive(Clone, Debug)] @@ -599,6 +601,7 @@ impl Tab { &self.terminal_emulator_colors, &self.terminal_emulator_color_codes, &self.character_cell_size, + &self.connected_clients, &self.style, &self.display_area, &mut self.tiled_panes, @@ -657,6 +660,7 @@ impl Tab { &self.terminal_emulator_colors, &self.terminal_emulator_color_codes, &self.character_cell_size, + &self.connected_clients, &self.style, &self.display_area, &mut self.tiled_panes, @@ -709,6 +713,7 @@ impl Tab { &self.terminal_emulator_colors, &self.terminal_emulator_color_codes, &self.character_cell_size, + &self.connected_clients, &self.style, &self.display_area, &mut self.tiled_panes, @@ -1104,6 +1109,114 @@ impl Tab { } Ok(()) } + pub fn new_plugin_pane( + &mut self, + pid: PaneId, + initial_pane_title: String, + should_float: Option<bool>, + run_plugin: Run, + client_id: Option<ClientId>, + ) -> Result<()> { + let err_context = || format!("failed to create new pane with id {pid:?}"); + + match should_float { + Some(true) => self.show_floating_panes(), + Some(false) => self.hide_floating_panes(), + None => {}, + }; + if self.floating_panes.panes_are_visible() { + if let Some(new_pane_geom) = self.floating_panes.find_room_for_new_pane() { + if let PaneId::Plugin(plugin_pid) = pid { + let mut new_pane = PluginPane::new( + plugin_pid, + new_pane_geom, + self.senders + .to_plugin + .as_ref() + .with_context(err_context)? + .clone(), + initial_pane_title, + String::new(), + self.sixel_image_store.clone(), + self.terminal_emulator_colors.clone(), + self.terminal_emulator_color_codes.clone(), + self.link_handler.clone(), + self.character_cell_size.clone(), + self.connected_clients.borrow().iter().copied().collect(), + self.style, + Some(run_plugin), + ); + new_pane.set_active_at(Instant::now()); + new_pane.set_content_offset(Offset::frame(1)); // floating panes always have a frame + resize_pty!( + new_pane, + self.os_api, + self.senders, + self.character_cell_size + ) + .with_context(err_context)?; + self.floating_panes.add_pane(pid, Box::new(new_pane)); + self.floating_panes.focus_pane_for_all_clients(pid); + } + if self.auto_layout && !self.swap_layouts.is_floating_damaged() { + // only do this if we're already in this layout, otherwise it might be + // confusing and not what the user intends + self.swap_layouts.set_is_floating_damaged(); // we do this so that we won't skip to the + // next layout + self.next_swap_layout(client_id, true)?; + } + } + } else { + if self.tiled_panes.fullscreen_is_active() { + self.tiled_panes.unset_fullscreen(); + } + let should_auto_layout = self.auto_layout && !self.swap_layouts.is_tiled_damaged(); + if self.tiled_panes.has_room_for_new_pane() { + if let PaneId::Plugin(plugin_pid) = pid { + let mut new_pane = PluginPane::new( + plugin_pid, + PaneGeom::default(), // the initial size will be set later + self.senders + .to_plugin + .as_ref() + .with_context(err_context)? + .clone(), + initial_pane_title, + String::new(), + self.sixel_image_store.clone(), + self.terminal_emulator_colors.clone(), + self.terminal_emulator_color_codes.clone(), + self.link_handler.clone(), + self.character_cell_size.clone(), + self.connected_clients.borrow().iter().copied().collect(), + self.style, + Some(run_plugin), + ); + new_pane.set_active_at(Instant::now()); + if should_auto_layout { + // no need to relayout here, we'll do it when reapplying the swap layout + // below + self.tiled_panes + .insert_pane_without_relayout(pid, Box::new(new_pane)); + } else { + self.tiled_panes.insert_pane(pid, Box::new(new_pane)); + } + self.should_clear_display_before_rendering = true; + if let Some(client_id) = client_id { + self.tiled_panes.focus_pane(pid, client_id); + } + } + } + if should_auto_layout { + // only do this if we're already in this layout, otherwise it might be + // confusing and not what the user intends + self.swap_layouts.set_is_tiled_damaged(); // we do this so that we won't skip to the + // next layout + self.next_swap_layout(client_id, true)?; + } + } + Ok(()) + } pub fn suppress_active_pane(&mut self, pid: PaneId, client_id: ClientId) -> Result<()> { // this method creates a new pane from pid and replaces it with the active pane // the active pane is then suppressed (hidden and not rendered) until the current @@ -3220,7 +3333,34 @@ impl Tab { pane.clear_pane_frame_color_override(); } } - + pub fn update_plugin_loading_stage(&mut self, pid: u32, loading_indication: LoadingIndication) { + if let Some(plugin_pane) = self + .tiled_panes + .get_pane_mut(PaneId::Plugin(pid)) + .or_else(|| self.floating_panes.get_pane_mut(PaneId::Plugin(pid))) + .or_else(|| { + self.suppressed_panes + .values_mut() + .find(|s_p| s_p.pid() == PaneId::Plugin(pid)) + }) + { + plugin_pane.update_loading_indication(loading_indication); + } + } + pub fn progress_plugin_loading_offset(&mut self, pid: u32) { + if let Some(plugin_pane) = self + .tiled_panes + .get_pane_mut(PaneId::Plugin(pid)) + .or_else(|| self.floating_panes.get_pane_mut(PaneId::Plugin(pid))) + .or_else(|| { + self.suppressed_panes + .values_mut() + .find(|s_p| s_p.pid() == PaneId::Plugin(pid)) + }) + { + plugin_pane.progress_animation_offset(); + } + } fn show_floating_panes(&mut self) { // this function is to be preferred to directly invoking floating_panes.toggle_show_panes(true) self.floating_panes.toggle_show_panes(true); |