diff options
author | Aram Drevekenin <aram@poor.dev> | 2022-12-14 22:26:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-14 22:26:48 +0100 |
commit | c3115a428ed5c990cc5ead5629dabb624ae90453 (patch) | |
tree | fe1a3c0f344b6d1056789861d6d28ca5196f838d /zellij-server/src/background_jobs.rs | |
parent | 177cd20beaf7a89d54b295f1aab498b7ab2c04c1 (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.rs | 79 |
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 + }, + } +} |