From 126b65817e9d7904412e94473cc7fa42ed49bbed Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 27 Feb 2020 16:41:58 +0200 Subject: [PATCH] Forward input on input/rawinput switch Input thread listens on stdin input and forwards the input to the main process. When an embedded terminal is launched within the main process, the input thread is asked to switch to raw input, that is to send the parsed input and the raw bytes to the main process in order to get them forwarded to the embedded terminal. The switch happens by calling get_events and get_events_raw. When the input thread receives an InputCommand::{No,}Raw, it has already received an input event, since the `select!` is within the stdin events for loop. (There's no way to `select` on blocking iterators or raw fds, which is unfortunate.). This commit forwards the input to the next function instead of dropping it. --- src/state.rs | 1 + src/terminal/keys.rs | 27 ++++++++++++++++++--------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/state.rs b/src/state.rs index 6bc04dfdd..aca73e826 100644 --- a/src/state.rs +++ b/src/state.rs @@ -68,6 +68,7 @@ impl InputHandler { tx.send(ThreadEvent::InputRaw(i)).unwrap(); }, &rx, + None, ) }) .unwrap(); diff --git a/src/terminal/keys.rs b/src/terminal/keys.rs index 9b0b9ca5c..433e75e4d 100644 --- a/src/terminal/keys.rs +++ b/src/terminal/keys.rs @@ -24,7 +24,6 @@ use crossbeam::{channel::Receiver, select}; use serde::{Serialize, Serializer}; use termion::event::Event as TermionEvent; use termion::event::Key as TermionKey; -use termion::input::TermRead; #[derive(Debug, PartialEq, Eq, Clone)] pub enum Key { @@ -167,18 +166,23 @@ pub fn get_events( mut closure: impl FnMut(Key), closure_raw: impl FnMut((Key, Vec)), rx: &Receiver, + input: Option<(TermionEvent, Vec)>, ) -> () { let stdin = std::io::stdin(); let mut input_mode = InputMode::Normal; let mut paste_buf = String::with_capacity(256); - for c in stdin.events() { + for c in input + .map(|v| Ok(v)) + .into_iter() + .chain(stdin.events_and_raw()) + { select! { default => {}, recv(rx) -> cmd => { match cmd.unwrap() { InputCommand::Kill => return, InputCommand::Raw => { - get_events_raw(closure, closure_raw, rx); + get_events_raw(closure, closure_raw, rx, c.ok()); return; } InputCommand::NoRaw => unreachable!(), @@ -187,16 +191,16 @@ pub fn get_events( }; match c { - Ok(TermionEvent::Key(k)) if input_mode == InputMode::Normal => { + Ok((TermionEvent::Key(k), _)) if input_mode == InputMode::Normal => { closure(Key::from(k)); } - Ok(TermionEvent::Key(TermionKey::Char(k))) if input_mode == InputMode::Paste => { + Ok((TermionEvent::Key(TermionKey::Char(k)), _)) if input_mode == InputMode::Paste => { paste_buf.push(k); } - Ok(TermionEvent::Unsupported(ref k)) if k.as_slice() == BRACKET_PASTE_START => { + Ok((TermionEvent::Unsupported(ref k), _)) if k.as_slice() == BRACKET_PASTE_START => { input_mode = InputMode::Paste; } - Ok(TermionEvent::Unsupported(ref k)) if k.as_slice() == BRACKET_PASTE_END => { + Ok((TermionEvent::Unsupported(ref k), _)) if k.as_slice() == BRACKET_PASTE_END => { input_mode = InputMode::Normal; let ret = Key::from(&paste_buf); paste_buf.clear(); @@ -212,18 +216,23 @@ pub fn get_events_raw( closure_nonraw: impl FnMut(Key), mut closure: impl FnMut((Key, Vec)), rx: &Receiver, + input: Option<(TermionEvent, Vec)>, ) -> () { let stdin = std::io::stdin(); let mut input_mode = InputMode::Normal; let mut paste_buf = String::with_capacity(256); - for c in stdin.events_and_raw() { + for c in input + .map(|v| Ok(v)) + .into_iter() + .chain(stdin.events_and_raw()) + { select! { default => {}, recv(rx) -> cmd => { match cmd.unwrap() { InputCommand::Kill => return, InputCommand::NoRaw => { - get_events(closure_nonraw, closure, rx); + get_events(closure_nonraw, closure, rx, c.ok()); return; } InputCommand::Raw => unreachable!(),