feat: restore the cursor state on terminal drop

This commit is contained in:
Florian Dehau 2018-09-24 07:54:33 +02:00
parent a99fc115f8
commit 7b4d35d224
14 changed files with 32 additions and 22 deletions

View file

@ -132,6 +132,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -105,6 +105,5 @@ fn main() -> Result<(), failure::Error> {
_ => {}
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -176,6 +176,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -129,6 +129,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -55,6 +55,5 @@ fn main() -> Result<(), failure::Error> {
_ => {}
};
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -249,7 +249,6 @@ fn main() -> Result<(), failure::Error> {
}
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -125,6 +125,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -85,6 +85,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -174,6 +174,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -102,6 +102,5 @@ fn main() -> Result<(), failure::Error> {
_ => {}
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -128,6 +128,5 @@ fn main() -> Result<(), failure::Error> {
}
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -108,6 +108,5 @@ fn main() -> Result<(), failure::Error> {
};
}
terminal.show_cursor()?;
Ok(())
}

View file

@ -57,6 +57,7 @@ fn main() -> Result<(), failure::Error> {
let stdout = AlternateScreen::from(stdout);
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
terminal.hide_cursor()?;
// Setup event handlers
let events = Events::new();

View file

@ -17,6 +17,8 @@ where
buffers: [Buffer; 2],
/// Index of the current buffer in the previous array
current: usize,
/// Whether the cursor is currently hidden
hidden_cursor: bool,
}
pub struct Frame<'a, B: 'a>
@ -39,18 +41,33 @@ where
}
}
impl<B> Drop for Terminal<B>
where
B: Backend,
{
fn drop(&mut self) {
// Attempt to restore the cursor state
if self.hidden_cursor {
if let Err(_) = self.show_cursor() {
error!("Failed to show the cursor");
}
}
}
}
impl<B> Terminal<B>
where
B: Backend,
{
/// Wrapper around Termion initialization. Each buffer is initialized with a blank string and
/// default colors for the foreground and the background
pub fn new(backend: B) -> Result<Terminal<B>, io::Error> {
pub fn new(backend: B) -> io::Result<Terminal<B>> {
let size = backend.size()?;
Ok(Terminal {
backend,
buffers: [Buffer::empty(size), Buffer::empty(size)],
current: 0,
hidden_cursor: false,
})
}
@ -72,7 +89,7 @@ where
/// Builds a string representing the minimal escape sequences and characters set necessary to
/// update the UI and writes it to stdout.
pub fn flush(&mut self) -> Result<(), io::Error> {
pub fn flush(&mut self) -> io::Result<()> {
let width = self.buffers[self.current].area.width;
let content = self.buffers[self.current]
.content
@ -94,7 +111,7 @@ where
/// Updates the interface so that internal buffers matches the current size of the terminal.
/// This leads to a full redraw of the screen.
pub fn resize(&mut self, area: Rect) -> Result<(), io::Error> {
pub fn resize(&mut self, area: Rect) -> io::Result<()> {
self.buffers[self.current].resize(area);
self.buffers[1 - self.current].reset();
self.buffers[1 - self.current].resize(area);
@ -102,7 +119,7 @@ where
}
/// Flushes the current internal state and prepares the interface for the next draw call
pub fn draw<F>(&mut self, f: F) -> Result<(), io::Error>
pub fn draw<F>(&mut self, f: F) -> io::Result<()>
where
F: FnOnce(Frame<B>),
{
@ -120,16 +137,20 @@ where
Ok(())
}
pub fn hide_cursor(&mut self) -> Result<(), io::Error> {
self.backend.hide_cursor()
pub fn hide_cursor(&mut self) -> io::Result<()> {
self.backend.hide_cursor()?;
self.hidden_cursor = true;
Ok(())
}
pub fn show_cursor(&mut self) -> Result<(), io::Error> {
self.backend.show_cursor()
pub fn show_cursor(&mut self) -> io::Result<()> {
self.backend.show_cursor()?;
self.hidden_cursor = false;
Ok(())
}
pub fn clear(&mut self) -> Result<(), io::Error> {
pub fn clear(&mut self) -> io::Result<()> {
self.backend.clear()
}
pub fn size(&self) -> Result<Rect, io::Error> {
pub fn size(&self) -> io::Result<Rect> {
self.backend.size()
}
}