From 542999e07fe92d075611a1723bda2c2ff7773053 Mon Sep 17 00:00:00 2001 From: a-kenji Date: Sun, 1 Aug 2021 00:33:59 +0200 Subject: [PATCH] Fix plugin attribute update on inactive tab Fixes #621 * `ScreenInstruction::SetSelectable` etc. were not updating correctly, if a NewTab was spawned, before the plugin was finished setting the attributes. Now the `tab_index` is used to send the instructions to their respective tabs and plugins. --- zellij-server/src/screen.rs | 85 ++++++++++++++++++++++++------------ zellij-server/src/tab.rs | 4 +- zellij-server/src/wasm_vm.rs | 12 +++-- 3 files changed, 68 insertions(+), 33 deletions(-) diff --git a/zellij-server/src/screen.rs b/zellij-server/src/screen.rs index 2baedf03ab..b348540fb6 100644 --- a/zellij-server/src/screen.rs +++ b/zellij-server/src/screen.rs @@ -56,10 +56,10 @@ pub(crate) enum ScreenInstruction { ClearScroll, CloseFocusedPane, ToggleActiveTerminalFullscreen, - SetSelectable(PaneId, bool), - SetFixedHeight(PaneId, usize), - SetFixedWidth(PaneId, usize), - SetInvisibleBorders(PaneId, bool), + SetSelectable(PaneId, bool, usize), + SetFixedHeight(PaneId, usize, usize), + SetFixedWidth(PaneId, usize, usize), + SetInvisibleBorders(PaneId, bool, usize), ClosePane(PaneId), ApplyLayout(Layout, Vec), NewTab(RawFd), @@ -337,6 +337,11 @@ impl Screen { } } + /// Returns a mutable reference to this [`Screen`]'s indexed [`Tab`]. + pub fn get_indexed_tab_mut(&mut self, tab_index: usize) -> Option<&mut Tab> { + self.get_tabs_mut().get_mut(&tab_index) + } + /// Creates a new [`Tab`] in this [`Screen`], applying the specified [`Layout`] /// and switching to it. pub fn apply_layout(&mut self, layout: Layout, new_pids: Vec) { @@ -355,7 +360,7 @@ impl Screen { self.colors, self.session_state.clone(), ); - tab.apply_layout(layout, new_pids); + tab.apply_layout(layout, new_pids, tab_index); self.active_tab_index = Some(tab_index); self.tabs.insert(tab_index, tab); self.update_tabs(); @@ -599,29 +604,53 @@ pub(crate) fn screen_thread_main( screen.get_active_tab_mut().unwrap().close_focused_pane(); screen.render(); } - ScreenInstruction::SetSelectable(id, selectable) => { - screen - .get_active_tab_mut() - .unwrap() - .set_pane_selectable(id, selectable); - } - ScreenInstruction::SetFixedHeight(id, fixed_height) => { - screen - .get_active_tab_mut() - .unwrap() - .set_pane_fixed_height(id, fixed_height); - } - ScreenInstruction::SetFixedWidth(id, fixed_width) => { - screen - .get_active_tab_mut() - .unwrap() - .set_pane_fixed_width(id, fixed_width); - } - ScreenInstruction::SetInvisibleBorders(id, invisible_borders) => { - screen - .get_active_tab_mut() - .unwrap() - .set_pane_invisible_borders(id, invisible_borders); + ScreenInstruction::SetSelectable(id, selectable, tab_index) => { + screen.get_indexed_tab_mut(tab_index).map_or_else( + || { + log::warn!( + "Tab index #{} not found, could not set selectable for plugin #{:?}.", + tab_index, + id + ) + }, + |tab| tab.set_pane_selectable(id, selectable), + ); + } + ScreenInstruction::SetFixedHeight(id, fixed_height, tab_index) => { + screen.get_indexed_tab_mut(tab_index).map_or_else( + || { + log::warn!( + "Tab index #{} not found, could not set fixed height for plugin #{:?}.", + tab_index, + id + ) + }, + |tab| tab.set_pane_fixed_height(id, fixed_height), + ); + } + ScreenInstruction::SetFixedWidth(id, fixed_width, tab_index) => { + screen.get_indexed_tab_mut(tab_index).map_or_else( + || { + log::warn!( + "Tab index #{} not found, could not set fixed width for plugin #{:?}.", + tab_index, + id + ) + }, + |tab| tab.set_pane_fixed_width(id, fixed_width), + ); + } + ScreenInstruction::SetInvisibleBorders(id, invisible_borders, tab_index) => { + screen.get_indexed_tab_mut(tab_index).map_or_else( + || { + log::warn!( + r#"Tab index #{} not found, could not set invisible borders for plugin #{:?}."#, + tab_index, + id + ) + }, + |tab| tab.set_pane_invisible_borders(id, invisible_borders), + ); screen.render(); } ScreenInstruction::ClosePane(id) => { diff --git a/zellij-server/src/tab.rs b/zellij-server/src/tab.rs index 057b1bbc40..0662be2256 100644 --- a/zellij-server/src/tab.rs +++ b/zellij-server/src/tab.rs @@ -301,7 +301,7 @@ impl Tab { } } - pub fn apply_layout(&mut self, layout: Layout, new_pids: Vec) { + pub fn apply_layout(&mut self, layout: Layout, new_pids: Vec, tab_index: usize) { // TODO: this should be an attribute on Screen instead of full_screen_ws let free_space = PositionAndSize { x: 0, @@ -340,7 +340,7 @@ impl Tab { if let Some(Run::Plugin(Some(plugin))) = &layout.run { let (pid_tx, pid_rx) = channel(); self.senders - .send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone())) + .send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone(), tab_index)) .unwrap(); let pid = pid_rx.recv().unwrap(); let new_plugin = PluginPane::new( diff --git a/zellij-server/src/wasm_vm.rs b/zellij-server/src/wasm_vm.rs index f3e4a115bb..41a468ee22 100644 --- a/zellij-server/src/wasm_vm.rs +++ b/zellij-server/src/wasm_vm.rs @@ -28,8 +28,8 @@ use zellij_utils::{input::command::TerminalAction, serde, zellij_tile}; #[derive(Clone, Debug)] pub(crate) enum PluginInstruction { - Load(Sender, PathBuf), - Update(Option, Event), // Focused plugin / broadcast, event data + Load(Sender, PathBuf, usize), // tx_pid, path_of_plugin , tab_index + Update(Option, Event), // Focused plugin / broadcast, event data Render(Sender, u32, usize, usize), // String buffer, plugin id, rows, cols Unload(u32), Exit, @@ -50,6 +50,7 @@ impl From<&PluginInstruction> for PluginContext { #[derive(WasmerEnv, Clone)] pub(crate) struct PluginEnv { pub plugin_id: u32, + pub tab_index: usize, pub senders: ThreadSenders, pub wasi_env: WasiEnv, pub subscriptions: Arc>>, @@ -64,7 +65,7 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d let (event, mut err_ctx) = bus.recv().expect("failed to receive event on channel"); err_ctx.add_call(ContextType::Plugin((&event).into())); match event { - PluginInstruction::Load(pid_tx, path) => { + PluginInstruction::Load(pid_tx, path, tab_index) => { let plugin_dir = data_dir.join("plugins/"); let wasm_bytes = fs::read(&path) .or_else(|_| fs::read(&path.with_extension("wasm"))) @@ -100,6 +101,7 @@ pub(crate) fn wasm_thread_main(bus: Bus, store: Store, data_d let plugin_env = PluginEnv { plugin_id, + tab_index, senders: bus.senders.clone(), wasi_env, subscriptions: Arc::new(Mutex::new(HashSet::new())), @@ -193,6 +195,7 @@ fn host_set_selectable(plugin_env: &PluginEnv, selectable: i32) { .send_to_screen(ScreenInstruction::SetSelectable( PaneId::Plugin(plugin_env.plugin_id), selectable, + plugin_env.tab_index, )) .unwrap() } @@ -204,6 +207,7 @@ fn host_set_fixed_height(plugin_env: &PluginEnv, fixed_height: i32) { .send_to_screen(ScreenInstruction::SetFixedHeight( PaneId::Plugin(plugin_env.plugin_id), fixed_height, + plugin_env.tab_index, )) .unwrap() } @@ -215,6 +219,7 @@ fn host_set_fixed_width(plugin_env: &PluginEnv, fixed_width: i32) { .send_to_screen(ScreenInstruction::SetFixedWidth( PaneId::Plugin(plugin_env.plugin_id), fixed_width, + plugin_env.tab_index, )) .unwrap() } @@ -226,6 +231,7 @@ fn host_set_invisible_borders(plugin_env: &PluginEnv, invisible_borders: i32) { .send_to_screen(ScreenInstruction::SetInvisibleBorders( PaneId::Plugin(plugin_env.plugin_id), invisible_borders, + plugin_env.tab_index, )) .unwrap() }