fixed terminal resetting (hopefully)

This commit is contained in:
rabite 2019-05-07 23:27:36 +02:00
parent 54e0a4246f
commit 6a5ae52e07
4 changed files with 73 additions and 42 deletions

View File

@ -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))?;

View File

@ -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(())
}

View File

@ -13,7 +13,7 @@ pub type TermMode = AlternateScreen<RawTerminal<BufWriter<Stdout>>>;
#[derive(Clone)]
pub struct Screen {
screen: Arc<Mutex<Option<TermMode>>>,
screen: Arc<Mutex<TermMode>>,
size: Arc<RwLock<Option<(usize, usize)>>>,
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<usize> {
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 {}
impl ScreenExt for TermMode {}
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 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();

View File

@ -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);
}