From ed28170d428063bb64b23287c333368b9b721190 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Thu, 18 Jan 2024 10:04:38 +0100 Subject: [PATCH] Always synchronize terminal before rendering it Previously, we were trying not to synchronize the terminal too often because there could be multiple layout/paint calls prior to rendering a frame. Now that we perform a single render pass per frame, we can just synchronize the terminal state. Not doing so could make it seem like we're dropping frames. --- crates/terminal/src/terminal.rs | 35 ++------------------ crates/terminal_view/src/terminal_element.rs | 2 +- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/crates/terminal/src/terminal.rs b/crates/terminal/src/terminal.rs index 3a01f01ca8..0b87ed1d97 100644 --- a/crates/terminal/src/terminal.rs +++ b/crates/terminal/src/terminal.rs @@ -47,7 +47,7 @@ use std::{ os::unix::prelude::AsRawFd, path::PathBuf, sync::Arc, - time::{Duration, Instant}, + time::Duration, }; use thiserror::Error; @@ -385,8 +385,6 @@ impl TerminalBuilder { last_content: Default::default(), last_mouse: None, matches: Vec::new(), - last_synced: Instant::now(), - sync_task: None, selection_head: None, shell_fd: fd as u32, shell_pid, @@ -542,8 +540,6 @@ pub struct Terminal { last_mouse_position: Option>, pub matches: Vec>, pub last_content: TerminalContent, - last_synced: Instant, - sync_task: Option>, pub selection_head: Option, pub breadcrumb_text: String, shell_pid: u32, @@ -977,40 +973,15 @@ impl Terminal { self.input(paste_text); } - pub fn try_sync(&mut self, cx: &mut ModelContext) { + pub fn sync(&mut self, cx: &mut ModelContext) { let term = self.term.clone(); - - let mut terminal = if let Some(term) = term.try_lock_unfair() { - term - } else if self.last_synced.elapsed().as_secs_f32() > 0.25 { - term.lock_unfair() // It's been too long, force block - } else if let None = self.sync_task { - //Skip this frame - let delay = cx.background_executor().timer(Duration::from_millis(16)); - self.sync_task = Some(cx.spawn(|weak_handle, mut cx| async move { - delay.await; - if let Some(handle) = weak_handle.upgrade() { - handle - .update(&mut cx, |terminal, cx| { - terminal.sync_task.take(); - cx.notify(); - }) - .ok(); - } - })); - return; - } else { - //No lock and delayed rendering already scheduled, nothing to do - return; - }; - + let mut terminal = term.lock_unfair(); //Note that the ordering of events matters for event processing while let Some(e) = self.events.pop_front() { self.process_terminal_event(&e, &mut terminal, cx) } self.last_content = Self::make_content(&terminal, &self.last_content); - self.last_synced = Instant::now(); } fn make_content(term: &Term, last_content: &TerminalContent) -> TerminalContent { diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index 6298b4c16a..746a3716b8 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -446,7 +446,7 @@ impl TerminalElement { let last_hovered_word = self.terminal.update(cx, |terminal, cx| { terminal.set_size(dimensions); - terminal.try_sync(cx); + terminal.sync(cx); if self.can_navigate_to_selected_word && terminal.can_navigate_to_selected_word() { terminal.last_content.last_hovered_word.clone() } else {