summaryrefslogtreecommitdiffstats
path: root/zellij-server/src/background_jobs.rs
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2022-12-14 22:26:48 +0100
committerGitHub <noreply@github.com>2022-12-14 22:26:48 +0100
commitc3115a428ed5c990cc5ead5629dabb624ae90453 (patch)
treefe1a3c0f344b6d1056789861d6d28ca5196f838d /zellij-server/src/background_jobs.rs
parent177cd20beaf7a89d54b295f1aab498b7ab2c04c1 (diff)
fix(panes): show visual error when unable to split panes vertically/horizontally (#2025)
* fix(panes): show visual error when failing to split pane vertically/horizontally * fix: lockfile
Diffstat (limited to 'zellij-server/src/background_jobs.rs')
-rw-r--r--zellij-server/src/background_jobs.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/zellij-server/src/background_jobs.rs b/zellij-server/src/background_jobs.rs
new file mode 100644
index 000000000..3c89ed064
--- /dev/null
+++ b/zellij-server/src/background_jobs.rs
@@ -0,0 +1,79 @@
+use zellij_utils::async_std::task;
+use zellij_utils::errors::{prelude::*, BackgroundJobContext, ContextType};
+
+use std::collections::HashMap;
+use std::time::{Duration, Instant};
+
+use crate::panes::PaneId;
+use crate::screen::ScreenInstruction;
+use crate::thread_bus::Bus;
+
+#[derive(Debug, Clone, Eq, PartialEq, Hash)]
+pub enum BackgroundJob {
+ DisplayPaneError(PaneId, String),
+ Exit,
+}
+
+impl From<&BackgroundJob> for BackgroundJobContext {
+ fn from(background_job: &BackgroundJob) -> Self {
+ match *background_job {
+ BackgroundJob::DisplayPaneError(..) => BackgroundJobContext::DisplayPaneError,
+ BackgroundJob::Exit => BackgroundJobContext::Exit,
+ }
+ }
+}
+
+static FLASH_DURATION_MS: u64 = 1000;
+
+pub(crate) fn background_jobs_main(bus: Bus<BackgroundJob>) -> Result<()> {
+ let err_context = || "failed to write to pty".to_string();
+ let mut running_jobs: HashMap<BackgroundJob, Instant> = HashMap::new();
+
+ loop {
+ let (event, mut err_ctx) = bus.recv().with_context(err_context)?;
+ err_ctx.add_call(ContextType::BackgroundJob((&event).into()));
+ let job = event.clone();
+ match event {
+ BackgroundJob::DisplayPaneError(pane_id, text) => {
+ if job_already_running(job, &mut running_jobs) {
+ continue;
+ }
+ task::spawn({
+ let senders = bus.senders.clone();
+ async move {
+ let _ = senders.send_to_screen(
+ ScreenInstruction::AddRedPaneFrameColorOverride(pane_id, Some(text)),
+ );
+ task::sleep(std::time::Duration::from_millis(FLASH_DURATION_MS)).await;
+ let _ = senders.send_to_screen(
+ ScreenInstruction::ClearPaneFrameColorOverride(pane_id),
+ );
+ }
+ });
+ },
+ BackgroundJob::Exit => {
+ return Ok(());
+ },
+ }
+ }
+}
+
+fn job_already_running(
+ job: BackgroundJob,
+ running_jobs: &mut HashMap<BackgroundJob, Instant>,
+) -> bool {
+ match running_jobs.get_mut(&job) {
+ Some(current_running_job_start_time) => {
+ if current_running_job_start_time.elapsed() > Duration::from_millis(FLASH_DURATION_MS) {
+ *current_running_job_start_time = Instant::now();
+ false
+ } else {
+ true
+ }
+ },
+ None => {
+ running_jobs.insert(job.clone(), Instant::now());
+ false
+ },
+ }
+}