summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-03-17 23:14:09 +0100
committerrabite <rabite@posteo.de>2019-03-17 23:14:09 +0100
commit6bb16d2638a48ebaad3ebe475df6587c29cb774c (patch)
treeb93033673550e76c5a875e3771cf1ed6f8151459
parentcc8020ee8c6060de86280b76a8bf5f7018ea6226 (diff)
don't steal input from foreground subprocs
-rw-r--r--src/file_browser.rs7
-rw-r--r--src/widget.rs56
2 files changed, 46 insertions, 17 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 1d9933d..abf144f 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -237,10 +237,17 @@ impl FileBrowser {
if file.is_dir() {
self.main_widget_goto(&file).log();
} else {
+ self.core.get_sender().send(Events::InputEnabled(false))?;
+
let status = std::process::Command::new("rifle")
.args(file.path.file_name())
.status();
+ self.clear().log();
+ self.core.screen.cursor_hide().log();
+
+ self.core.get_sender().send(Events::InputEnabled(true))?;
+
match status {
Ok(status) =>
self.show_status(&format!("\"{}\" exited with {}",
diff --git a/src/widget.rs b/src/widget.rs
index 09a5d0a..1d48bdf 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -19,6 +19,8 @@ pub enum Events {
InputEvent(Event),
WidgetReady,
ExclusiveEvent(Option<Sender<Events>>),
+ InputEnabled(bool),
+ RequestInput,
Status(String)
}
@@ -233,6 +235,7 @@ pub trait Widget {
fn run_widget(&mut self) -> HResult<()> {
let (tx_event, rx_event) = channel();
self.get_core()?.get_sender().send(Events::ExclusiveEvent(Some(tx_event)))?;
+ self.get_core()?.get_sender().send(Events::RequestInput)?;
self.clear()?;
self.refresh().log();
@@ -248,10 +251,14 @@ pub trait Widget {
err @ Err(_) => err.log(),
Ok(_) => {}
}
+ self.get_core()?.get_sender().send(Events::RequestInput)?;
}
Events::WidgetReady => {
self.refresh().log();
}
+ Events::Status(status) => {
+ self.show_status(&status).log();
+ }
_ => {}
}
self.refresh().log();
@@ -303,13 +310,10 @@ pub trait Widget {
}
fn handle_input(&mut self) -> HResult<()> {
- let (tx_event, rx_event) = channel();
let (tx_internal_event, rx_internal_event) = channel();
let rx_global_event = self.get_core()?.event_receiver.lock()?.take()?;
- input_thread(tx_event.clone());
- global_event_thread(rx_global_event, tx_event.clone());
- dispatch_events(rx_event, tx_internal_event);
+ dispatch_events(tx_internal_event, rx_global_event);
for event in rx_internal_event.iter() {
match event {
@@ -318,16 +322,15 @@ pub trait Widget {
Err(HError::Quit) => { HError::quit()?; },
_ => {}
}
- self.draw().ok();
- },
+ self.get_core()?.get_sender().send(Events::RequestInput)?;
+ }
Events::Status(status) => {
self.show_status(&status).log();
}
- _ => {
- self.refresh().ok();
- self.draw().ok();
- },
+ _ => {}
}
+ self.refresh().ok();
+ self.draw().ok();
}
Ok(())
}
@@ -386,26 +389,44 @@ pub trait Widget {
}
}
-fn dispatch_events(rx: Receiver<Events>, tx: Sender<Events>) {
+fn dispatch_events(tx_internal: Sender<Events>, rx_global: Receiver<Events>) {
+ let (tx_event, rx_event) = channel();
+ let (tx_input_req, rx_input_req) = channel();
+
+ input_thread(tx_event.clone(), rx_input_req);
+ event_thread(rx_global, tx_event.clone());
+
std::thread::spawn(move || {
let mut tx_exclusive_event: Option<Sender<Events>> = None;
- for event in rx.iter() {
+ let mut input_enabled = true;
+
+ for event in rx_event.iter() {
match &event {
Events::ExclusiveEvent(tx_event) => {
tx_exclusive_event = tx_event.clone();
}
+ Events::InputEnabled(state) => {
+ input_enabled = *state;
+ continue;
+ }
+ Events::RequestInput => {
+ if input_enabled {
+ tx_input_req.send(()).unwrap();
+ }
+ continue;
+ }
_ => {}
}
- if let Some(tx_event) = &tx_exclusive_event {
- tx_event.send(event).ok();
+ if let Some(tx_exclusive) = &tx_exclusive_event {
+ tx_exclusive.send(event).unwrap();
} else {
- tx.send(event).ok();
+ tx_internal.send(event).unwrap();
}
}
});
}
-fn global_event_thread(rx_global: Receiver<Events>,
+fn event_thread(rx_global: Receiver<Events>,
tx: Sender<Events>) {
std::thread::spawn(move || {
for event in rx_global.iter() {
@@ -414,11 +435,12 @@ fn global_event_thread(rx_global: Receiver<Events>,
});
}
-fn input_thread(tx: Sender<Events>) {
+fn input_thread(tx: Sender<Events>, rx_input_request: Receiver<()>) {
std::thread::spawn(move || {
for input in stdin().events() {
let input = input.unwrap();
tx.send(Events::InputEvent(input)).unwrap();
+ rx_input_request.recv().unwrap();
}
});
}