From 6a5ae52e07308b8ed10d42bd40958b3196d518c3 Mon Sep 17 00:00:00 2001 From: rabite Date: Tue, 7 May 2019 23:27:36 +0200 Subject: fixed terminal resetting (hopefully) --- src/file_browser.rs | 19 +++++++------- src/main.rs | 18 ++++++------- src/term.rs | 73 ++++++++++++++++++++++++++++++++++++++--------------- src/widget.rs | 5 +++- 4 files changed, 73 insertions(+), 42 deletions(-) diff --git a/src/file_browser.rs b/src/file_browser.rs index 200fea7..34ab2a6 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -395,16 +395,16 @@ impl FileBrowser { self.columns.insert_widget(1, main_widget); } else { + self.preview_widget().map(|preview| preview.cancel_animation()).log(); self.core.get_sender().send(Events::InputEnabled(false))?; - self.core.screen.drop_screen(); + self.core.screen.suspend().log(); let status = std::process::Command::new("rifle") .args(file.path.file_name()) .status(); - self.core.screen.reset_screen().log(); + self.core.screen.activate().log(); self.clear().log(); - self.core.screen.cursor_hide().log(); self.core.get_sender().send(Events::InputEnabled(true))?; @@ -886,7 +886,7 @@ impl FileBrowser { .clone(); self.core.get_sender().send(Events::InputEnabled(false))?; - self.core.screen.drop_screen(); + self.core.screen.suspend().log(); self.preview_widget().map(|preview| preview.cancel_animation()).log(); let cmd_result = std::process::Command::new(shell) @@ -897,7 +897,7 @@ impl FileBrowser { .stderr(std::process::Stdio::inherit()) .output(); - self.core.screen.reset_screen().log(); + self.core.screen.activate().log(); self.clear().log(); self.core.get_sender().send(Events::InputEnabled(true))?; @@ -989,7 +989,7 @@ impl FileBrowser { .clone(); self.core.get_sender().send(Events::InputEnabled(false))?; - self.core.screen.drop_screen(); + self.core.screen.suspend().log(); self.preview_widget().map(|preview| preview.cancel_animation()).log(); let cmd_result = std::process::Command::new(shell) @@ -1000,7 +1000,7 @@ impl FileBrowser { .stderr(std::process::Stdio::inherit()) .output(); - self.core.screen.reset_screen().log(); + self.core.screen.activate().log(); self.clear().log(); self.core.get_sender().send(Events::InputEnabled(true))?; @@ -1082,13 +1082,12 @@ impl FileBrowser { self.core.get_sender().send(Events::InputEnabled(false))?; self.preview_widget().map(|preview| preview.cancel_animation()).log(); - self.core.screen.cursor_show().log(); - self.core.screen.drop_screen(); + self.core.screen.suspend().log(); let shell = std::env::var("SHELL").unwrap_or("bash".into()); let status = std::process::Command::new(&shell).status(); - self.core.screen.reset_screen().log(); + self.core.screen.activate().log(); self.core.get_sender().send(Events::InputEnabled(true))?; diff --git a/src/main.rs b/src/main.rs index 837a9ac..355c07d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -64,9 +64,8 @@ use file_browser::FileBrowser; use tabview::TabView; -fn drop_screen(core: &mut WidgetCore) -> HResult<()> { - core.screen.drop_screen(); - Ok(()) +fn reset_screen(core: &mut WidgetCore) -> HResult<()> { + core.screen.suspend() } fn die_gracefully(core: &WidgetCore) { @@ -75,7 +74,7 @@ fn die_gracefully(core: &WidgetCore) { panic::set_hook(Box::new(move |info| { let mut core = core.clone(); - drop_screen(&mut core).ok(); + reset_screen(&mut core).ok(); panic_hook(info); })); } @@ -87,13 +86,12 @@ fn main() -> HResult<()> { let mut core = WidgetCore::new().expect("Can't create WidgetCore!"); // Resets terminal when hunter crashes :( - die_gracefully(&mut core); + die_gracefully(&core); match run(core.clone()) { - Ok(_) => drop_screen(&mut core), - Err(HError::Quit) => drop_screen(&mut core), + Ok(_) | Err(HError::Quit) => reset_screen(&mut core), Err(err) => { - drop_screen(&mut core)?; + reset_screen(&mut core)?; eprintln!("{:?}\n{:?}", err, err.cause()); return Err(err); } @@ -109,8 +107,8 @@ fn run(mut core: WidgetCore) -> HResult<()> { tabview.handle_input()?; - core.screen.cursor_show()?; - core.screen.flush()?; + // core.screen.cursor_show()?; + // core.screen.flush()?; Ok(()) } diff --git a/src/term.rs b/src/term.rs index 35105fd..ba1dee5 100644 --- a/src/term.rs +++ b/src/term.rs @@ -13,7 +13,7 @@ pub type TermMode = AlternateScreen>>; #[derive(Clone)] pub struct Screen { - screen: Arc>>, + screen: Arc>, size: Arc>>, terminal: String } @@ -26,27 +26,12 @@ impl Screen { screen.cursor_hide()?; Ok(Screen { - screen: Arc::new(Mutex::new(Some(screen))), + screen: Arc::new(Mutex::new(screen)), size: Arc::new(RwLock::new(None)), terminal: terminal }) } - pub fn drop_screen(&mut self) { - self.cursor_show().log(); - self.to_main_screen().log(); - self.screen.lock().map(|mut screen| std::mem::drop(screen.take())).ok(); - - // Terminal stays fucked without this. Why? - Ok(std::process::Command::new("reset").arg("-I").spawn()).log(); - } - - pub fn reset_screen(&mut self) -> HResult<()> { - let screen = Screen::new()?.screen.lock()?.take()?; - *self.screen.lock()? = Some(screen); - Ok(()) - } - pub fn set_size(&self, size: (usize, usize)) -> HResult<()> { *self.size.write()? = Some(size); Ok(()) @@ -82,14 +67,34 @@ impl Screen { impl Write for Screen { fn write(&mut self, buf: &[u8]) -> std::io::Result { - self.screen.lock().unwrap().as_mut().unwrap().write(buf) + self.screen + .lock() + .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, + "Screen Mutex poisoned!")) + .and_then(|mut s| s.write(buf)) } fn flush(&mut self) -> std::io::Result<()> { - self.screen.lock().unwrap().as_mut().unwrap().flush() + self.screen + .lock() + .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, + "Screen Mutex poisoned!")) + .and_then(|mut s| s.flush()) } } pub trait ScreenExt: Write { + fn suspend_raw_mode(&mut self) -> HResult<()>; + fn activate_raw_mode(&mut self) -> HResult<()>; + fn suspend(&mut self) -> HResult<()> { + self.cursor_show().log(); + self.to_main_screen().log(); + self.suspend_raw_mode() + } + fn activate(&mut self) -> HResult<()> { + self.cursor_hide().log(); + self.to_alternate_screen().log(); + self.activate_raw_mode() + } fn cursor_hide(&mut self) -> HResult<()> { write!(self, "{}", termion::cursor::Hide)?; self.flush()?; @@ -137,10 +142,36 @@ pub trait ScreenExt: Write { self.flush()?; Ok(()) } + fn to_alternate_screen(&mut self) -> HResult<()> { + write!(self, "{}", termion::screen::ToAlternateScreen)?; + self.flush()?; + Ok(()) + } +} + +impl ScreenExt for Screen { + fn suspend_raw_mode(&mut self) -> HResult<()> { + self.screen + .lock()? + .suspend_raw_mode() + } + + fn activate_raw_mode(&mut self) -> HResult<()> { + self.screen + .lock()? + .activate_raw_mode() + } } -impl ScreenExt for Screen {} -impl ScreenExt for TermMode {} +impl ScreenExt for TermMode { + fn suspend_raw_mode(&mut self) -> HResult<()> { + Ok(RawTerminal::suspend_raw_mode(self)?) + } + + fn activate_raw_mode(&mut self) -> HResult<()> { + Ok(RawTerminal::activate_raw_mode(self)?) + } +} pub fn flush_stdin() { let stdin = std::io::stdin(); diff --git a/src/widget.rs b/src/widget.rs index c106f7e..2f1d54c 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -350,7 +350,10 @@ pub trait Widget { }; self.set_coordinates(&ani_coords).log(); let buffer = self.get_drawlist()?; - self.write_to_screen(&buffer).log(); + + if !animator.as_ref()?.is_stale()? { + self.write_to_screen(&buffer).log(); + } std::thread::sleep(pause); } -- cgit v1.2.3