Reduce tearing when redrawing screen

This commit is contained in:
Joscha 2023-05-10 19:35:56 +02:00
parent 3b9ffe8715
commit 6eb853e313
2 changed files with 22 additions and 9 deletions

View file

@ -5,7 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
async-trait = "0.1.64" async-trait = "0.1.64"
crossterm = "0.26.0" crossterm = "0.26.1"
unicode-linebreak = "0.1.4" unicode-linebreak = "0.1.4"
unicode-segmentation = "1.10.1" unicode-segmentation = "1.10.1"
unicode-width = "0.1.10" unicode-width = "0.1.10"

View file

@ -9,7 +9,10 @@ use crossterm::event::{
PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags, PopKeyboardEnhancementFlags, PushKeyboardEnhancementFlags,
}; };
use crossterm::style::{PrintStyledContent, StyledContent}; use crossterm::style::{PrintStyledContent, StyledContent};
use crossterm::terminal::{Clear, ClearType, EnterAlternateScreen, LeaveAlternateScreen}; use crossterm::terminal::{
BeginSynchronizedUpdate, Clear, ClearType, EndSynchronizedUpdate, EnterAlternateScreen,
LeaveAlternateScreen,
};
use crossterm::{ExecutableCommand, QueueableCommand}; use crossterm::{ExecutableCommand, QueueableCommand};
use crate::buffer::Buffer; use crate::buffer::Buffer;
@ -198,14 +201,11 @@ impl Terminal {
/// After calling this function, the frame returned by [`Self::frame`] will /// After calling this function, the frame returned by [`Self::frame`] will
/// be empty again and have no cursor position. /// be empty again and have no cursor position.
pub fn present(&mut self) -> io::Result<()> { pub fn present(&mut self) -> io::Result<()> {
if self.full_redraw { self.out.queue(BeginSynchronizedUpdate)?;
self.out.queue(Clear(ClearType::All))?; let result = self.draw_to_screen();
self.prev_frame_buffer.reset(); // Because the screen is now empty self.out.queue(EndSynchronizedUpdate)?;
self.full_redraw = false; result?;
}
self.draw_differences()?;
self.update_cursor()?;
self.out.flush()?; self.out.flush()?;
mem::swap(&mut self.prev_frame_buffer, &mut self.frame.buffer); mem::swap(&mut self.prev_frame_buffer, &mut self.frame.buffer);
@ -244,6 +244,19 @@ impl Terminal {
Ok(()) Ok(())
} }
fn draw_to_screen(&mut self) -> io::Result<()> {
if self.full_redraw {
self.out.queue(Clear(ClearType::All))?;
self.prev_frame_buffer.reset(); // Because the screen is now empty
self.full_redraw = false;
}
self.draw_differences()?;
self.update_cursor()?;
Ok(())
}
fn draw_differences(&mut self) -> io::Result<()> { fn draw_differences(&mut self) -> io::Result<()> {
for (x, y, cell) in self.frame.buffer.cells() { for (x, y, cell) in self.frame.buffer.cells() {
if self.prev_frame_buffer.at(x, y) == cell { if self.prev_frame_buffer.at(x, y) == cell {