Reduce tearing when redrawing screen
This commit is contained in:
parent
3b9ffe8715
commit
6eb853e313
2 changed files with 22 additions and 9 deletions
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue