Hopefully fix read not triggering draw
The terminal mutex is no longer released between event processing and doing a draw. This may fix the race condition with data arriving but not being displayed until a subsequent event. cc #29
This commit is contained in:
parent
689e0f4ad7
commit
d06360216d
112
src/event.rs
112
src/event.rs
|
@ -2,14 +2,15 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::{Arc, mpsc};
|
use std::sync::mpsc;
|
||||||
use serde_json as json;
|
|
||||||
|
|
||||||
|
use serde_json as json;
|
||||||
|
use parking_lot::MutexGuard;
|
||||||
use glutin::{self, ElementState};
|
use glutin::{self, ElementState};
|
||||||
use index::{Line, Column, Side};
|
|
||||||
|
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use display::OnResize;
|
use display::OnResize;
|
||||||
|
use index::{Line, Column, Side};
|
||||||
use input::{self, ActionContext, MouseBinding, KeyBinding};
|
use input::{self, ActionContext, MouseBinding, KeyBinding};
|
||||||
use selection::Selection;
|
use selection::Selection;
|
||||||
use sync::FairMutex;
|
use sync::FairMutex;
|
||||||
|
@ -58,7 +59,6 @@ pub struct Processor<N> {
|
||||||
mouse_bindings: Vec<MouseBinding>,
|
mouse_bindings: Vec<MouseBinding>,
|
||||||
notifier: N,
|
notifier: N,
|
||||||
mouse: Mouse,
|
mouse: Mouse,
|
||||||
terminal: Arc<FairMutex<Term>>,
|
|
||||||
resize_tx: mpsc::Sender<(u32, u32)>,
|
resize_tx: mpsc::Sender<(u32, u32)>,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
size_info: SizeInfo,
|
size_info: SizeInfo,
|
||||||
|
@ -81,21 +81,15 @@ impl<N: Notify> Processor<N> {
|
||||||
/// pty.
|
/// pty.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
notifier: N,
|
notifier: N,
|
||||||
terminal: Arc<FairMutex<Term>>,
|
|
||||||
resize_tx: mpsc::Sender<(u32, u32)>,
|
resize_tx: mpsc::Sender<(u32, u32)>,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
ref_test: bool,
|
ref_test: bool,
|
||||||
|
size_info: SizeInfo,
|
||||||
) -> Processor<N> {
|
) -> Processor<N> {
|
||||||
let size_info = {
|
|
||||||
let terminal = terminal.lock();
|
|
||||||
terminal.size_info().to_owned()
|
|
||||||
};
|
|
||||||
|
|
||||||
Processor {
|
Processor {
|
||||||
key_bindings: config.key_bindings().to_vec(),
|
key_bindings: config.key_bindings().to_vec(),
|
||||||
mouse_bindings: config.mouse_bindings().to_vec(),
|
mouse_bindings: config.mouse_bindings().to_vec(),
|
||||||
notifier: notifier,
|
notifier: notifier,
|
||||||
terminal: terminal,
|
|
||||||
resize_tx: resize_tx,
|
resize_tx: resize_tx,
|
||||||
ref_test: ref_test,
|
ref_test: ref_test,
|
||||||
mouse: Default::default(),
|
mouse: Default::default(),
|
||||||
|
@ -176,57 +170,65 @@ impl<N: Notify> Processor<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Process at least one event and handle any additional queued events.
|
/// Process at least one event and handle any additional queued events.
|
||||||
pub fn process_events(&mut self, window: &Window) -> bool {
|
pub fn process_events<'a>(
|
||||||
|
&mut self,
|
||||||
|
term: &'a FairMutex<Term>,
|
||||||
|
window: &Window
|
||||||
|
) -> (MutexGuard<'a, Term>, bool) {
|
||||||
let mut wakeup_request = false;
|
let mut wakeup_request = false;
|
||||||
|
|
||||||
// These are lazily initialized the first time an event is returned
|
// Terminal is lazily initialized the first time an event is returned
|
||||||
// from the blocking WaitEventsIterator. Otherwise, the pty reader
|
// from the blocking WaitEventsIterator. Otherwise, the pty reader would
|
||||||
// would be blocked the entire time we wait for input!
|
// be blocked the entire time we wait for input!
|
||||||
let terminal;
|
let terminal;
|
||||||
let context;
|
|
||||||
let mut processor: input::Processor<N>;
|
|
||||||
|
|
||||||
// Convenience macro which curries most arguments to handle_event.
|
{
|
||||||
macro_rules! process {
|
// Ditto on lazy initialization for context and processor.
|
||||||
($event:expr) => {
|
let context;
|
||||||
Processor::handle_event(
|
let mut processor: input::Processor<N>;
|
||||||
&mut processor,
|
|
||||||
$event,
|
// Convenience macro which curries most arguments to handle_event.
|
||||||
&mut wakeup_request,
|
macro_rules! process {
|
||||||
self.ref_test,
|
($event:expr) => {
|
||||||
&self.resize_tx,
|
Processor::handle_event(
|
||||||
)
|
&mut processor,
|
||||||
|
$event,
|
||||||
|
&mut wakeup_request,
|
||||||
|
self.ref_test,
|
||||||
|
&self.resize_tx,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match window.wait_events().next() {
|
||||||
|
Some(event) => {
|
||||||
|
terminal = term.lock();
|
||||||
|
context = ActionContext {
|
||||||
|
terminal: &terminal,
|
||||||
|
notifier: &mut self.notifier,
|
||||||
|
selection: &mut self.selection,
|
||||||
|
mouse: &mut self.mouse,
|
||||||
|
size_info: &self.size_info,
|
||||||
|
};
|
||||||
|
|
||||||
|
processor = input::Processor {
|
||||||
|
ctx: context,
|
||||||
|
key_bindings: &self.key_bindings[..],
|
||||||
|
mouse_bindings: &self.mouse_bindings[..]
|
||||||
|
};
|
||||||
|
|
||||||
|
process!(event);
|
||||||
|
},
|
||||||
|
// Glutin guarantees the WaitEventsIterator never returns None.
|
||||||
|
None => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
|
for event in window.poll_events() {
|
||||||
|
process!(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match window.wait_events().next() {
|
(terminal, wakeup_request)
|
||||||
Some(event) => {
|
|
||||||
terminal = self.terminal.lock();
|
|
||||||
context = ActionContext {
|
|
||||||
terminal: &terminal,
|
|
||||||
notifier: &mut self.notifier,
|
|
||||||
selection: &mut self.selection,
|
|
||||||
mouse: &mut self.mouse,
|
|
||||||
size_info: &self.size_info,
|
|
||||||
};
|
|
||||||
|
|
||||||
processor = input::Processor {
|
|
||||||
ctx: context,
|
|
||||||
key_bindings: &self.key_bindings[..],
|
|
||||||
mouse_bindings: &self.mouse_bindings[..]
|
|
||||||
};
|
|
||||||
|
|
||||||
process!(event);
|
|
||||||
},
|
|
||||||
// Glutin guarantees the WaitEventsIterator never returns None.
|
|
||||||
None => unreachable!(),
|
|
||||||
}
|
|
||||||
|
|
||||||
for event in window.poll_events() {
|
|
||||||
process!(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
wakeup_request
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_config(&mut self, config: &Config) {
|
pub fn update_config(&mut self, config: &Config) {
|
||||||
|
|
|
@ -104,10 +104,10 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
|
||||||
// Need the Rc<RefCell<_>> here since a ref is shared in the resize callback
|
// Need the Rc<RefCell<_>> here since a ref is shared in the resize callback
|
||||||
let mut processor = event::Processor::new(
|
let mut processor = event::Processor::new(
|
||||||
event_loop::Notifier(loop_tx),
|
event_loop::Notifier(loop_tx),
|
||||||
terminal.clone(),
|
|
||||||
display.resize_channel(),
|
display.resize_channel(),
|
||||||
&config,
|
&config,
|
||||||
options.ref_test,
|
options.ref_test,
|
||||||
|
display.size().to_owned(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Create a config monitor when config was loaded from path
|
// Create a config monitor when config was loaded from path
|
||||||
|
@ -123,7 +123,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
|
||||||
// Main display loop
|
// Main display loop
|
||||||
loop {
|
loop {
|
||||||
// Process input and window events
|
// Process input and window events
|
||||||
let wakeup_request = processor.process_events(display.window());
|
let (mut terminal, wakeup_request) = processor.process_events(&terminal, display.window());
|
||||||
|
|
||||||
// Handle config reloads
|
// Handle config reloads
|
||||||
let config_updated = config_monitor.as_ref()
|
let config_updated = config_monitor.as_ref()
|
||||||
|
@ -136,7 +136,6 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
|
||||||
}).unwrap_or(false);
|
}).unwrap_or(false);
|
||||||
|
|
||||||
// Maybe draw the terminal
|
// Maybe draw the terminal
|
||||||
let mut terminal = terminal.lock();
|
|
||||||
if wakeup_request || config_updated {
|
if wakeup_request || config_updated {
|
||||||
// Handle pending resize events
|
// Handle pending resize events
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue