Fix terminal issues with alacritty

This commit is contained in:
Dheepak Krishnamurthy 2021-02-14 21:49:26 -07:00
parent 5aca3940d6
commit 39d7b2ba96
3 changed files with 48 additions and 64 deletions

View file

@ -1255,6 +1255,8 @@ impl TTApp {
String::from_utf8_lossy(&output.stderr), String::from_utf8_lossy(&output.stderr),
)) ))
} else { } else {
String::from_utf8_lossy(&output.stdout);
String::from_utf8_lossy(&output.stderr);
Ok(()) Ok(())
} }
} }
@ -1404,7 +1406,6 @@ impl TTApp {
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
events: &Events, events: &Events,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
events.pause_ticker();
match self.mode { match self.mode {
AppMode::TaskReport => match input { AppMode::TaskReport => match input {
Key::Ctrl('c') | Key::Char('q') => self.should_quit = true, Key::Ctrl('c') | Key::Char('q') => self.should_quit = true,
@ -1640,7 +1641,6 @@ impl TTApp {
_ => {} _ => {}
}, },
} }
events.resume_ticker();
Ok(()) Ok(())
} }
} }

View file

@ -71,7 +71,7 @@ fn tui_main(_config: &str) -> Result<(), Box<dyn Error>> {
// Setup event handlers // Setup event handlers
let events = Events::with_config(EventConfig { let events = Events::with_config(EventConfig {
tick_rate: Duration::from_millis(1000), tick_rate: Duration::from_millis(250),
}); });
let maybeapp = TTApp::new(); let maybeapp = TTApp::new();

View file

@ -9,7 +9,7 @@ use tui::{backend::CrosstermBackend, Terminal};
use std::io::{self, Write}; use std::io::{self, Write};
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::{sync::mpsc, thread, time::Duration}; use std::{sync::mpsc, thread, time::Duration, time::Instant};
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum Key { pub enum Key {
@ -63,7 +63,6 @@ pub struct Events {
pub rx: mpsc::Receiver<Event<Key>>, pub rx: mpsc::Receiver<Event<Key>>,
pub tx: mpsc::Sender<Event<Key>>, pub tx: mpsc::Sender<Event<Key>>,
pub pause_stdin: Arc<AtomicBool>, pub pause_stdin: Arc<AtomicBool>,
pub pause_ticker: Arc<AtomicBool>,
} }
impl Events { impl Events {
@ -72,70 +71,61 @@ impl Events {
use crossterm::event::{KeyCode::*, KeyModifiers}; use crossterm::event::{KeyCode::*, KeyModifiers};
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
let pause_stdin = Arc::new(AtomicBool::new(false)); let pause_stdin = Arc::new(AtomicBool::new(false));
let pause_ticker = Arc::new(AtomicBool::new(false)); let tick_rate = config.tick_rate;
let _input_handle = { let _input_handle = {
let tx = tx.clone(); let tx = tx.clone();
let pause_stdin = pause_stdin.clone(); let pause_stdin = pause_stdin.clone();
thread::spawn(move || { thread::spawn(move || {
let mut last_tick = Instant::now();
loop { loop {
let timeout = tick_rate
.checked_sub(last_tick.elapsed())
.unwrap_or_else(|| Duration::from_secs(0));
if pause_stdin.load(Ordering::SeqCst) { if pause_stdin.load(Ordering::SeqCst) {
thread::sleep(Duration::from_millis(250)); thread::sleep(Duration::from_millis(250));
continue; continue;
} }
// poll for tick rate duration, if no event, sent tick event. // poll for tick rate duration, if no event, sent tick event.
if let event::Event::Key(key) = event::read().unwrap() { if event::poll(timeout).unwrap() {
let key = match key.code { if let event::Event::Key(key) = event::read().unwrap() {
Backspace => Key::Backspace, let key = match key.code {
Enter => Key::Char('\n'), Backspace => Key::Backspace,
Left => Key::Left, Enter => Key::Char('\n'),
Right => Key::Right, Left => Key::Left,
Up => Key::Up, Right => Key::Right,
Down => Key::Down, Up => Key::Up,
Home => Key::Home, Down => Key::Down,
End => Key::End, Home => Key::Home,
PageUp => Key::PageUp, End => Key::End,
PageDown => Key::PageDown, PageUp => Key::PageUp,
Tab => Key::Char('\t'), PageDown => Key::PageDown,
BackTab => Key::BackTab, Tab => Key::Char('\t'),
Delete => Key::Delete, BackTab => Key::BackTab,
Insert => Key::Insert, Delete => Key::Delete,
F(k) => Key::F(k), Insert => Key::Insert,
Null => Key::Null, F(k) => Key::F(k),
Esc => Key::Esc, Null => Key::Null,
Char(c) => match key.modifiers { Esc => Key::Esc,
KeyModifiers::NONE | KeyModifiers::SHIFT => Key::Char(c), Char(c) => match key.modifiers {
KeyModifiers::CONTROL => Key::Ctrl(c), KeyModifiers::NONE | KeyModifiers::SHIFT => Key::Char(c),
KeyModifiers::ALT => Key::Alt(c), KeyModifiers::CONTROL => Key::Ctrl(c),
_ => Key::Null, KeyModifiers::ALT => Key::Alt(c),
}, _ => Key::Null,
}; },
tx.send(Event::Input(key)).unwrap(); };
tx.send(Event::Input(key)).unwrap();
}
}
if last_tick.elapsed() >= tick_rate && tx.send(Event::Tick).is_ok() {
last_tick = Instant::now();
} }
} }
}) })
}; };
let _tick_handle = { Events { rx, tx, pause_stdin }
let tx = tx.clone();
let pause_ticker = pause_ticker.clone();
thread::spawn(move || loop {
// print!("\r\n");
// dbg!(*pause_ticker.lock().unwrap());
while pause_ticker.load(Ordering::SeqCst) {
thread::sleep(Duration::from_millis(250));
}
if tx.send(Event::Tick).is_err() {
break;
}
thread::sleep(config.tick_rate);
})
};
Events {
rx,
tx,
pause_stdin,
pause_ticker,
}
} }
/// Attempts to read an event. /// Attempts to read an event.
@ -144,14 +134,6 @@ impl Events {
self.rx.recv() self.rx.recv()
} }
pub fn pause_ticker(&self) {
self.pause_ticker.swap(true, Ordering::SeqCst);
}
pub fn resume_ticker(&self) {
self.pause_ticker.swap(false, Ordering::SeqCst);
}
pub fn pause_event_loop(&self) { pub fn pause_event_loop(&self) {
self.pause_stdin.swap(true, Ordering::SeqCst); self.pause_stdin.swap(true, Ordering::SeqCst);
} }
@ -162,14 +144,16 @@ impl Events {
pub fn pause_key_capture(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) { pub fn pause_key_capture(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) {
self.pause_event_loop(); self.pause_event_loop();
thread::sleep(Duration::from_millis(250));
disable_raw_mode().unwrap(); disable_raw_mode().unwrap();
execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap(); execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap();
terminal.show_cursor().unwrap(); terminal.show_cursor().unwrap();
} }
pub fn resume_key_capture(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) { pub fn resume_key_capture(&self, terminal: &mut Terminal<CrosstermBackend<io::Stdout>>) {
enable_raw_mode().unwrap();
execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture).unwrap(); execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture).unwrap();
enable_raw_mode().unwrap();
thread::sleep(Duration::from_millis(250));
self.resume_event_loop(); self.resume_event_loop();
terminal.resize(terminal.size().unwrap()).unwrap(); terminal.resize(terminal.size().unwrap()).unwrap();
} }