From 736d43b138fea4e7bec6dfb6193e1370594886ff Mon Sep 17 00:00:00 2001 From: har7an <99636919+har7an@users.noreply.github.com> Date: Mon, 3 Mar 2025 09:26:58 +0000 Subject: [PATCH] fix(toolchain): Unbreak client startup This reverts commit 9f900a7325304a06d9e0913a8e661d7bbc86ad04. --- CHANGELOG.md | 1 - Cargo.lock | 17 +-- xtask/Cargo.toml | 5 +- xtask/src/build.rs | 10 +- xtask/src/ci.rs | 8 +- xtask/src/clippy.rs | 2 +- xtask/src/flags.rs | 4 +- xtask/src/format.rs | 2 +- xtask/src/main.rs | 85 +++----------- xtask/src/pipelines.rs | 2 +- xtask/src/test.rs | 10 +- zellij-client/src/lib.rs | 15 ++- zellij-server/src/lib.rs | 11 ++ .../src/panes/tiled_panes/tiled_pane_grid.rs | 107 ++++++++++++++---- zellij-server/src/plugins/plugin_loader.rs | 3 +- zellij-server/src/plugins/plugin_worker.rs | 10 +- zellij-server/src/route.rs | 3 + zellij-server/src/tab/mod.rs | 8 +- zellij-server/src/tab/swap_layouts.rs | 30 +++++ zellij-server/src/terminal_bytes.rs | 8 +- zellij-utils/src/errors.rs | 2 + zellij-utils/src/ipc.rs | 2 + 22 files changed, 207 insertions(+), 138 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ea2a2c9..2d148911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) * feat(plugins): add tab_history to the session metadata (https://github.com/zellij-org/zellij/pull/4014) * chore(repo): update some dependencies (https://github.com/zellij-org/zellij/pull/4019) * fix(grid): reap sixel images on clear (https://github.com/zellij-org/zellij/pull/3982) -* chore(repo): remove compile warnings (https://github.com/zellij-org/zellij/pull/4026) * fix(panes): properly render stacked panes when pane frames are disabled (https://github.com/zellij-org/zellij/pull/4035) ## [0.41.2] - 2024-11-19 diff --git a/Cargo.lock b/Cargo.lock index 84095f90..c352d6c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5102,39 +5102,40 @@ dependencies = [ [[package]] name = "xflags" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9e15fbb3de55454b0106e314b28e671279009b363e6f1d8e39fdc3bf048944" +checksum = "c4554b580522d0ca238369c16b8f6ce34524d61dafe7244993754bbd05f2c2ea" dependencies = [ "xflags-macros", ] [[package]] name = "xflags-macros" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672423d4fea7ffa2f6c25ba60031ea13dc6258070556f125cc4d790007d4a155" +checksum = "f58e7b3ca8977093aae6b87b6a7730216fc4c53a6530bab5c43a783cd810c1a8" [[package]] name = "xshell" -version = "0.2.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e7290c623014758632efe00737145b6867b66292c42167f2ec381eb566a373d" +checksum = "6d47097dc5c85234b1e41851b3422dd6d19b3befdd35b4ae5ce386724aeca981" dependencies = [ "xshell-macros", ] [[package]] name = "xshell-macros" -version = "0.2.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32ac00cd3f8ec9c1d33fb3e7958a82df6989c42d747bd326c822b1d625283547" +checksum = "88301b56c26dd9bf5c43d858538f82d6f3f7764767defbc5d34e59459901c41a" [[package]] name = "xtask" version = "0.1.0" dependencies = [ "anyhow", + "lazy_static", "prost-build", "toml 0.5.10", "which", diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index d52793f0..2ab2b1c4 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -6,8 +6,9 @@ edition = "2021" [dependencies] anyhow = "1.0" -xshell = "= 0.2.7" -xflags = "0.3.2" +lazy_static = "1.4" +xshell = "= 0.2.2" +xflags = "0.3.1" which = "4.2" toml = "0.5" prost-build = "0.11.9" diff --git a/xtask/src/build.rs b/xtask/src/build.rs index 0cd5bdb0..4dc17e68 100644 --- a/xtask/src/build.rs +++ b/xtask/src/build.rs @@ -22,7 +22,7 @@ pub fn build(sh: &Shell, flags: flags::Build) -> anyhow::Result<()> { std::process::exit(1); } - for WorkspaceMember { crate_name, .. } in crate::workspace_members() + for WorkspaceMember { crate_name, .. } in crate::WORKSPACE_MEMBERS .iter() .filter(|member| member.build) { @@ -32,8 +32,10 @@ pub fn build(sh: &Shell, flags: flags::Build) -> anyhow::Result<()> { if flags.no_plugins { continue; } - } else if flags.plugins_only { - continue; + } else { + if flags.plugins_only { + continue; + } } // zellij-utils requires protobuf definition files to be present. Usually these are @@ -151,7 +153,7 @@ pub fn manpage(sh: &Shell) -> anyhow::Result<()> { let project_root = crate::project_root(); let asset_dir = &project_root.join("assets").join("man"); - sh.create_dir(asset_dir).context(err_context)?; + sh.create_dir(&asset_dir).context(err_context)?; let _pd = sh.push_dir(asset_dir); cmd!(sh, "{mandown} {project_root}/docs/MANPAGE.md 1") diff --git a/xtask/src/ci.rs b/xtask/src/ci.rs index b1c5fe2e..99f195da 100644 --- a/xtask/src/ci.rs +++ b/xtask/src/ci.rs @@ -77,7 +77,7 @@ fn e2e_build(sh: &Shell) -> anyhow::Result<()> { sh.remove_path(&data_dir) .and_then(|_| sh.create_dir(&data_dir)) - .and_then(|_| sh.create_dir(data_dir.join("plugins"))) + .and_then(|_| sh.create_dir(&data_dir.join("plugins"))) .context(err_context)?; for plugin in plugins { @@ -119,15 +119,15 @@ fn e2e_test(sh: &Shell, args: Vec) -> anyhow::Result<()> { // plugin system tests are run here because they're medium-slow let _pd = sh.push_dir(Path::new("zellij-server")); - println!(); - let msg = ">> Testing Plugin System".to_string(); + println!(""); + let msg = format!(">> Testing Plugin System"); crate::status(&msg); println!("{}", msg); cmd!(sh, "{cargo} test -- --ignored --nocapture --test-threads 1") .args(args.clone()) .run() - .with_context(|| "Failed to run tests for the Plugin System".to_string())?; + .with_context(|| format!("Failed to run tests for the Plugin System"))?; Ok(()) }) .context(err_context) diff --git a/xtask/src/clippy.rs b/xtask/src/clippy.rs index 0cb9146e..b5e2cfe5 100644 --- a/xtask/src/clippy.rs +++ b/xtask/src/clippy.rs @@ -21,7 +21,7 @@ pub fn clippy(sh: &Shell, _flags: flags::Clippy) -> anyhow::Result<()> { .and_then(|_| crate::cargo()) .context("failed to run task 'clippy'")?; - for WorkspaceMember { crate_name, .. } in crate::workspace_members().iter() { + for WorkspaceMember { crate_name, .. } in crate::WORKSPACE_MEMBERS.iter() { let _pd = sh.push_dir(Path::new(crate_name)); // Tell the user where we are now println!(); diff --git a/xtask/src/flags.rs b/xtask/src/flags.rs index 8ad32870..1c693626 100644 --- a/xtask/src/flags.rs +++ b/xtask/src/flags.rs @@ -9,7 +9,7 @@ xflags::xflags! { cmd xtask { /// Deprecation warning. Compatibility to transition from `cargo make`. cmd deprecated { - repeated _args: OsString + repeated args: OsString } /// Tasks for the CI @@ -128,7 +128,7 @@ pub enum XtaskCmd { #[derive(Debug)] pub struct Deprecated { - pub _args: Vec, + pub args: Vec, } #[derive(Debug)] diff --git a/xtask/src/format.rs b/xtask/src/format.rs index 88e858cd..4084a1f3 100644 --- a/xtask/src/format.rs +++ b/xtask/src/format.rs @@ -11,7 +11,7 @@ pub fn format(sh: &Shell, flags: flags::Format) -> anyhow::Result<()> { .and_then(|_| crate::cargo()) .context("failed to run task 'format'")?; - for WorkspaceMember { crate_name, .. } in crate::workspace_members().iter() { + for WorkspaceMember { crate_name, .. } in crate::WORKSPACE_MEMBERS.iter() { let _pd = sh.push_dir(Path::new(crate_name)); // Tell the user where we are now println!(); diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 1bb3eec9..e17f0383 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -19,7 +19,6 @@ use anyhow::Context; use std::{ env, path::{Path, PathBuf}, - sync::OnceLock, time::Instant, }; use xshell::Shell; @@ -29,72 +28,24 @@ pub struct WorkspaceMember { build: bool, } -fn workspace_members() -> &'static Vec { - static WORKSPACE_MEMBERS: OnceLock> = OnceLock::new(); - WORKSPACE_MEMBERS.get_or_init(|| { - vec![ - WorkspaceMember { - crate_name: "default-plugins/compact-bar", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/status-bar", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/strider", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/tab-bar", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/fixture-plugin-for-tests", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/session-manager", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/configuration", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/plugin-manager", - build: true, - }, - WorkspaceMember { - crate_name: "default-plugins/about", - build: true, - }, - WorkspaceMember { - crate_name: "zellij-utils", - build: false, - }, - WorkspaceMember { - crate_name: "zellij-tile-utils", - build: false, - }, - WorkspaceMember { - crate_name: "zellij-tile", - build: false, - }, - WorkspaceMember { - crate_name: "zellij-client", - build: false, - }, - WorkspaceMember { - crate_name: "zellij-server", - build: false, - }, - WorkspaceMember { - crate_name: ".", - build: true, - }, - ] - }) +lazy_static::lazy_static! { + pub static ref WORKSPACE_MEMBERS: Vec = vec![ + WorkspaceMember{crate_name: "default-plugins/compact-bar", build: true}, + WorkspaceMember{crate_name: "default-plugins/status-bar", build: true}, + WorkspaceMember{crate_name: "default-plugins/strider", build: true}, + WorkspaceMember{crate_name: "default-plugins/tab-bar", build: true}, + WorkspaceMember{crate_name: "default-plugins/fixture-plugin-for-tests", build: true}, + WorkspaceMember{crate_name: "default-plugins/session-manager", build: true}, + WorkspaceMember{crate_name: "default-plugins/configuration", build: true}, + WorkspaceMember{crate_name: "default-plugins/plugin-manager", build: true}, + WorkspaceMember{crate_name: "default-plugins/about", build: true}, + WorkspaceMember{crate_name: "zellij-utils", build: false}, + WorkspaceMember{crate_name: "zellij-tile-utils", build: false}, + WorkspaceMember{crate_name: "zellij-tile", build: false}, + WorkspaceMember{crate_name: "zellij-client", build: false}, + WorkspaceMember{crate_name: "zellij-server", build: false}, + WorkspaceMember{crate_name: ".", build: true}, + ]; } fn main() -> anyhow::Result<()> { diff --git a/xtask/src/pipelines.rs b/xtask/src/pipelines.rs index d3277c2f..437cefbf 100644 --- a/xtask/src/pipelines.rs +++ b/xtask/src/pipelines.rs @@ -317,7 +317,7 @@ pub fn publish(sh: &Shell, flags: flags::Publish) -> anyhow::Result<()> { } // Publish all the crates - for WorkspaceMember { crate_name, .. } in crate::workspace_members().iter() { + for WorkspaceMember { crate_name, .. } in crate::WORKSPACE_MEMBERS.iter() { if crate_name.contains("plugin") || crate_name.contains("xtask") { continue; } diff --git a/xtask/src/test.rs b/xtask/src/test.rs index 1c725f38..9bcfb37a 100644 --- a/xtask/src/test.rs +++ b/xtask/src/test.rs @@ -20,15 +20,15 @@ pub fn test(sh: &Shell, flags: flags::Test) -> anyhow::Result<()> { ) .context(err_context)?; - for WorkspaceMember { crate_name, .. } in crate::workspace_members().iter() { + for WorkspaceMember { crate_name, .. } in crate::WORKSPACE_MEMBERS.iter() { // the workspace root only contains e2e tests, skip it - if crate_name == &"." { + if *crate_name == "." { continue; } let _pd = sh.push_dir(Path::new(crate_name)); // Tell the user where we are now - println!(); + println!(""); let msg = format!(">> Testing '{}'", crate_name); crate::status(&msg); println!("{}", msg); @@ -60,9 +60,9 @@ pub fn host_target_triple(sh: &Shell) -> anyhow::Result { return None; } if let Some((_, triple)) = line.split_once(": ") { - Some(triple.to_string()) + return Some(triple.to_string()); } else { - None + return None; } }) .collect::>(); diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs index 725ed8cd..0d7b313b 100644 --- a/zellij-client/src/lib.rs +++ b/zellij-client/src/lib.rs @@ -46,14 +46,15 @@ pub(crate) enum ClientInstruction { UnblockInputThread, Exit(ExitReason), Connected, + ActiveClients(Vec), StartedParsingStdinQuery, DoneParsingStdinQuery, Log(Vec), LogError(Vec), SwitchSession(ConnectToSession), SetSynchronizedOutput(Option), - UnblockCliPipeInput(()), // String -> pipe name - CliPipeOutput((), ()), // String -> pipe name, String -> output + UnblockCliPipeInput(String), // String -> pipe name + CliPipeOutput(String, String), // String -> pipe name, String -> output QueryTerminalSize, WriteConfigToDisk { config: String }, } @@ -65,16 +66,17 @@ impl From for ClientInstruction { ServerToClientMsg::Render(buffer) => ClientInstruction::Render(buffer), ServerToClientMsg::UnblockInputThread => ClientInstruction::UnblockInputThread, ServerToClientMsg::Connected => ClientInstruction::Connected, + ServerToClientMsg::ActiveClients(clients) => ClientInstruction::ActiveClients(clients), ServerToClientMsg::Log(log_lines) => ClientInstruction::Log(log_lines), ServerToClientMsg::LogError(log_lines) => ClientInstruction::LogError(log_lines), ServerToClientMsg::SwitchSession(connect_to_session) => { ClientInstruction::SwitchSession(connect_to_session) }, - ServerToClientMsg::UnblockCliPipeInput(_pipe_name) => { - ClientInstruction::UnblockCliPipeInput(()) + ServerToClientMsg::UnblockCliPipeInput(pipe_name) => { + ClientInstruction::UnblockCliPipeInput(pipe_name) }, - ServerToClientMsg::CliPipeOutput(_pipe_name, _output) => { - ClientInstruction::CliPipeOutput((), ()) + ServerToClientMsg::CliPipeOutput(pipe_name, output) => { + ClientInstruction::CliPipeOutput(pipe_name, output) }, ServerToClientMsg::QueryTerminalSize => ClientInstruction::QueryTerminalSize, ServerToClientMsg::WriteConfigToDisk { config } => { @@ -92,6 +94,7 @@ impl From<&ClientInstruction> for ClientContext { ClientInstruction::Render(_) => ClientContext::Render, ClientInstruction::UnblockInputThread => ClientContext::UnblockInputThread, ClientInstruction::Connected => ClientContext::Connected, + ClientInstruction::ActiveClients(_) => ClientContext::ActiveClients, ClientInstruction::Log(_) => ClientContext::Log, ClientInstruction::LogError(_) => ClientContext::LogError, ClientInstruction::StartedParsingStdinQuery => ClientContext::StartedParsingStdinQuery, diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs index 6e652c05..879fd545 100644 --- a/zellij-server/src/lib.rs +++ b/zellij-server/src/lib.rs @@ -92,6 +92,7 @@ pub enum ServerInstruction { ClientId, ), ConnStatus(ClientId), + ActiveClients(ClientId), Log(Vec, ClientId), LogError(Vec, ClientId), SwitchSession(ConnectToSession, ClientId), @@ -132,6 +133,7 @@ impl From<&ServerInstruction> for ServerContext { ServerInstruction::DetachSession(..) => ServerContext::DetachSession, ServerInstruction::AttachClient(..) => ServerContext::AttachClient, ServerInstruction::ConnStatus(..) => ServerContext::ConnStatus, + ServerInstruction::ActiveClients(_) => ServerContext::ActiveClients, ServerInstruction::Log(..) => ServerContext::Log, ServerInstruction::LogError(..) => ServerContext::LogError, ServerInstruction::SwitchSession(..) => ServerContext::SwitchSession, @@ -1043,6 +1045,15 @@ pub fn start_server(mut os_input: Box, socket_path: PathBuf) { let _ = os_input.send_to_client(client_id, ServerToClientMsg::Connected); remove_client!(client_id, os_input, session_state); }, + ServerInstruction::ActiveClients(client_id) => { + let client_ids = session_state.read().unwrap().client_ids(); + send_to_client!( + client_id, + os_input, + ServerToClientMsg::ActiveClients(client_ids), + session_state + ); + }, ServerInstruction::Log(lines_to_log, client_id) => { send_to_client!( client_id, diff --git a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs index ad497822..5f2bf834 100644 --- a/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs +++ b/zellij-server/src/panes/tiled_panes/tiled_pane_grid.rs @@ -2033,11 +2033,8 @@ impl<'a> TiledPaneGrid<'a> { return None; } StackedPanes::new(self.panes.clone()) - .combine_vertically_aligned_panes_to_stack(&pane_id, neighboring_pane_ids_above) - .non_fatal(); - StackedPanes::new(self.panes.clone()) - .expand_pane(&pane_id) - .non_fatal(); + .combine_vertically_aligned_panes_to_stack(&pane_id, neighboring_pane_ids_above); + StackedPanes::new(self.panes.clone()).expand_pane(&pane_id); Some(vec![*pane_id]) } pub fn unstack_pane_up(&mut self, pane_id: &PaneId) -> Option> { @@ -2117,11 +2114,8 @@ impl<'a> TiledPaneGrid<'a> { return None; } StackedPanes::new(self.panes.clone()) - .combine_vertically_aligned_panes_to_stack(&pane_id, neighboring_pane_ids_below) - .non_fatal(); - StackedPanes::new(self.panes.clone()) - .expand_pane(&pane_id) - .non_fatal(); + .combine_vertically_aligned_panes_to_stack(&pane_id, neighboring_pane_ids_below); + StackedPanes::new(self.panes.clone()).expand_pane(&pane_id); Some(vec![*pane_id]) } pub fn direct_neighboring_pane_ids_to_the_left(&self, root_pane_id: &PaneId) -> Vec { @@ -2190,12 +2184,11 @@ impl<'a> TiledPaneGrid<'a> { { return None; } - StackedPanes::new(self.panes.clone()) - .combine_horizontally_aligned_panes_to_stack(&pane_id, neighboring_pane_ids_to_the_left) - .non_fatal(); - StackedPanes::new(self.panes.clone()) - .expand_pane(&pane_id) - .non_fatal(); + StackedPanes::new(self.panes.clone()).combine_horizontally_aligned_panes_to_stack( + &pane_id, + neighboring_pane_ids_to_the_left, + ); + StackedPanes::new(self.panes.clone()).expand_pane(&pane_id); Some(vec![*pane_id]) } pub fn direct_neighboring_pane_ids_to_the_right(&self, root_pane_id: &PaneId) -> Vec { @@ -2267,15 +2260,11 @@ impl<'a> TiledPaneGrid<'a> { if neighboring_pane_ids_to_the_right.is_empty() { return None; } - StackedPanes::new(self.panes.clone()) - .combine_horizontally_aligned_panes_to_stack( - &pane_id, - neighboring_pane_ids_to_the_right, - ) - .non_fatal(); - StackedPanes::new(self.panes.clone()) - .expand_pane(&pane_id) - .non_fatal(); + StackedPanes::new(self.panes.clone()).combine_horizontally_aligned_panes_to_stack( + &pane_id, + neighboring_pane_ids_to_the_right, + ); + StackedPanes::new(self.panes.clone()).expand_pane(&pane_id); Some(vec![*pane_id]) } pub fn next_stack_id(&self) -> usize { @@ -2293,6 +2282,74 @@ impl<'a> TiledPaneGrid<'a> { .set_geom(geom_of_active_pane); Ok(()) } + fn get_vertically_aligned_pane_id_above(&self, pane_id: &PaneId) -> Option { + let Some(pane_geom) = self.get_pane_geom(pane_id) else { + return None; + }; + let panes = self.panes.borrow(); + let stacked_panes = StackedPanes::new(self.panes.clone()); + let pane_geom = if pane_geom.is_stacked() { + stacked_panes + .position_and_size_of_stack(pane_id) + .unwrap_or(pane_geom) + } else { + pane_geom + }; + panes.iter().find_map(|(candidate_pane_id, p)| { + if !p.selectable() { + return None; + } + let candidate_geom = p.current_geom(); + let candidate_geom = if candidate_geom.is_stacked() { + stacked_panes + .position_and_size_of_stack(candidate_pane_id) + .unwrap_or(candidate_geom) + } else { + candidate_geom + }; + if candidate_geom.y + candidate_geom.rows.as_usize() == pane_geom.y + && candidate_geom.x == pane_geom.x + && candidate_geom.cols.as_usize() == pane_geom.cols.as_usize() + { + return Some(p.pid()); + } + return None; + }) + } + fn get_vertically_aligned_pane_id_below(&self, pane_id: &PaneId) -> Option { + let Some(pane_geom) = self.get_pane_geom(pane_id) else { + return None; + }; + let panes = self.panes.borrow(); + let stacked_panes = StackedPanes::new(self.panes.clone()); + let pane_geom = if pane_geom.is_stacked() { + stacked_panes + .position_and_size_of_stack(pane_id) + .unwrap_or(pane_geom) + } else { + pane_geom + }; + panes.iter().find_map(|(candidate_pane_id, p)| { + if !p.selectable() { + return None; + } + let candidate_geom = p.current_geom(); + let candidate_geom = if candidate_geom.is_stacked() { + stacked_panes + .position_and_size_of_stack(candidate_pane_id) + .unwrap_or(candidate_geom) + } else { + candidate_geom + }; + if candidate_geom.y == pane_geom.y + pane_geom.rows.as_usize() + && candidate_geom.x == pane_geom.x + && candidate_geom.cols.as_usize() == pane_geom.cols.as_usize() + { + return Some(p.pid()); + } + return None; + }) + } } pub fn split(direction: SplitDirection, rect: &PaneGeom) -> Option<(PaneGeom, PaneGeom)> { diff --git a/zellij-server/src/plugins/plugin_loader.rs b/zellij-server/src/plugins/plugin_loader.rs index 4a79ffb1..56ae6786 100644 --- a/zellij-server/src/plugins/plugin_loader.rs +++ b/zellij-server/src/plugins/plugin_loader.rs @@ -638,6 +638,7 @@ impl<'a> PluginLoader<'a> { .filter_map(|export| export.clone().into_func().map(|_| export.name())) { if function_name.ends_with("_worker") { + let plugin_config = self.plugin.clone(); let (mut store, instance) = self.create_plugin_instance_and_wasi_env_for_worker()?; @@ -648,7 +649,7 @@ impl<'a> PluginLoader<'a> { .call(&mut store, ()) .with_context(err_context)?; - let worker = RunningWorker::new(store, instance, &function_name); + let worker = RunningWorker::new(store, instance, &function_name, plugin_config); let worker_sender = plugin_worker(worker); workers.insert(function_name.into(), worker_sender); } diff --git a/zellij-server/src/plugins/plugin_worker.rs b/zellij-server/src/plugins/plugin_worker.rs index 635c8f50..3b630706 100644 --- a/zellij-server/src/plugins/plugin_worker.rs +++ b/zellij-server/src/plugins/plugin_worker.rs @@ -5,21 +5,29 @@ use wasmtime::{Instance, Store}; use zellij_utils::async_channel::{unbounded, Receiver, Sender}; use zellij_utils::async_std::task; use zellij_utils::errors::prelude::*; +use zellij_utils::input::plugins::PluginConfig; use zellij_utils::plugin_api::message::ProtobufMessage; use zellij_utils::prost::Message; pub struct RunningWorker { pub instance: Instance, pub name: String, + pub plugin_config: PluginConfig, pub store: Store, } impl RunningWorker { - pub fn new(store: Store, instance: Instance, name: &str) -> Self { + pub fn new( + store: Store, + instance: Instance, + name: &str, + plugin_config: PluginConfig, + ) -> Self { RunningWorker { store, instance, name: name.into(), + plugin_config, } } pub fn send_message(&mut self, message: String, payload: String) -> Result<()> { diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs index fbfe04d8..5832cb4d 100644 --- a/zellij-server/src/route.rs +++ b/zellij-server/src/route.rs @@ -1188,6 +1188,9 @@ pub(crate) fn route_thread_main( let _ = to_server.send(ServerInstruction::DetachSession(client_id)); should_break = true; }, + ClientToServerMsg::ListClients => { + let _ = to_server.send(ServerInstruction::ActiveClients(client_id)); + }, ClientToServerMsg::ConfigWrittenToDisk(config) => { let _ = to_server .send(ServerInstruction::ConfigWrittenToDisk(client_id, config)); diff --git a/zellij-server/src/tab/mod.rs b/zellij-server/src/tab/mod.rs index 02c19987..26fcb81b 100644 --- a/zellij-server/src/tab/mod.rs +++ b/zellij-server/src/tab/mod.rs @@ -186,6 +186,7 @@ pub(crate) struct Tab { viewport: Rc>, // includes all non-UI panes display_area: Rc>, // includes all panes (including eg. the status bar and tab bar in the default layout) character_cell_size: Rc>>, + stacked_resize: Rc>, sixel_image_store: Rc>, os_api: Box, pub senders: ThreadSenders, @@ -205,6 +206,7 @@ pub(crate) struct Tab { // it seems that optimization is possible using `active_panes` focus_pane_id: Option, copy_on_select: bool, + last_mouse_hold_position: Option, terminal_emulator_colors: Rc>, terminal_emulator_color_codes: Rc>>, pids_waiting_resize: HashSet, // u32 is the terminal_id @@ -689,6 +691,7 @@ impl Tab { viewport, display_area, character_cell_size, + stacked_resize, sixel_image_store, synchronize_is_active: false, os_api, @@ -706,6 +709,7 @@ impl Tab { clipboard_provider, focus_pane_id: None, copy_on_select: copy_options.copy_on_select, + last_mouse_hold_position: None, terminal_emulator_colors, terminal_emulator_color_codes, pids_waiting_resize: HashSet::new(), @@ -3886,7 +3890,6 @@ impl Tab { Ok(()) } - #[cfg(test)] pub fn handle_right_mouse_release( &mut self, position: &Position, @@ -3896,6 +3899,7 @@ impl Tab { format!("failed to handle right mouse release at position {position:?} for client {client_id}") }; + self.last_mouse_hold_position = None; let active_pane = self.get_active_pane_or_floating_pane_mut(client_id); if let Some(active_pane) = active_pane { let mut relative_position = active_pane.relative_position(position); @@ -3919,7 +3923,6 @@ impl Tab { Ok(()) } - #[cfg(test)] fn handle_middle_mouse_release( &mut self, position: &Position, @@ -3929,6 +3932,7 @@ impl Tab { format!("failed to handle middle mouse release at position {position:?} for client {client_id}") }; + self.last_mouse_hold_position = None; let active_pane = self.get_active_pane_or_floating_pane_mut(client_id); if let Some(active_pane) = active_pane { let mut relative_position = active_pane.relative_position(position); diff --git a/zellij-server/src/tab/swap_layouts.rs b/zellij-server/src/tab/swap_layouts.rs index 8ee9709d..ec009a59 100644 --- a/zellij-server/src/tab/swap_layouts.rs +++ b/zellij-server/src/tab/swap_layouts.rs @@ -64,6 +64,9 @@ impl SwapLayouts { pub fn reset_floating_damage(&mut self) { self.is_floating_damaged = false; } + pub fn reset_tiled_damage(&mut self) { + self.is_tiled_damaged = false; + } pub fn is_floating_damaged(&self) -> bool { self.is_floating_damaged } @@ -277,4 +280,31 @@ impl SwapLayouts { } None } + pub fn best_effort_tiled_layout( + &mut self, + tiled_panes: &TiledPanes, + ) -> Option { + for swap_layout in self.swap_tiled_layouts.iter() { + for (_constraint, layout) in swap_layout.0.iter() { + let focus_layout_if_not_focused = true; + let display_area = self.display_area.borrow(); + // TODO: reuse the assets from position_panes_in_space here? + let pane_count = tiled_panes.visible_panes_count(); + let display_area = PaneGeom::from(&*display_area); + if layout + .position_panes_in_space( + &display_area, + Some(pane_count), + false, + focus_layout_if_not_focused, + ) + .is_ok() + { + return Some(layout.clone()); + } + } + } + log::error!("Could not find layout that would fit on screen!"); + None + } } diff --git a/zellij-server/src/terminal_bytes.rs b/zellij-server/src/terminal_bytes.rs index 9459e943..6b81a01b 100644 --- a/zellij-server/src/terminal_bytes.rs +++ b/zellij-server/src/terminal_bytes.rs @@ -82,13 +82,7 @@ impl TerminalBytes { let mut buf = [0u8; 65536]; loop { match self.deadline_read(&mut buf).await { - // EOF - ReadResult::Ok(0) => break, - // Some error occured - ReadResult::Err(err) => { - log::error!("{}", err); - break; - }, + ReadResult::Ok(0) | ReadResult::Err(_) => break, // EOF or error ReadResult::Timeout => { let time_to_send_render = self .async_send_to_screen(ScreenInstruction::Render) diff --git a/zellij-utils/src/errors.rs b/zellij-utils/src/errors.rs index 9c419773..1d023722 100644 --- a/zellij-utils/src/errors.rs +++ b/zellij-utils/src/errors.rs @@ -450,6 +450,7 @@ pub enum ClientContext { ServerError, SwitchToMode, Connected, + ActiveClients, Log, LogError, OwnClientId, @@ -476,6 +477,7 @@ pub enum ServerContext { DetachSession, AttachClient, ConnStatus, + ActiveClients, Log, LogError, SwitchSession, diff --git a/zellij-utils/src/ipc.rs b/zellij-utils/src/ipc.rs index 8725c88c..a9a40bf4 100644 --- a/zellij-utils/src/ipc.rs +++ b/zellij-utils/src/ipc.rs @@ -92,6 +92,7 @@ pub enum ClientToServerMsg { ClientExited, KillSession, ConnStatus, + ListClients, ConfigWrittenToDisk(Config), FailedToWriteConfigToDisk(Option), } @@ -103,6 +104,7 @@ pub enum ServerToClientMsg { UnblockInputThread, Exit(ExitReason), Connected, + ActiveClients(Vec), Log(Vec), LogError(Vec), SwitchSession(ConnectToSession),