diff options
author | Joe Wilm <joe@jwilm.com> | 2016-09-01 10:24:20 -0700 |
---|---|---|
committer | Joe Wilm <joe@jwilm.com> | 2016-09-01 10:27:04 -0700 |
commit | 3085b0b1376924c41184490a98eae21d884293d0 (patch) | |
tree | 6f39fbf09d13efb925c67e679af1926972cc3aca /src/event.rs | |
parent | 0517f376be3054ab736006dcfc24b404dcd8626c (diff) | |
download | r-alacritty-3085b0b1376924c41184490a98eae21d884293d0.tar.gz r-alacritty-3085b0b1376924c41184490a98eae21d884293d0.tar.bz2 r-alacritty-3085b0b1376924c41184490a98eae21d884293d0.zip |
Move rendering back to main thread
This is only like the third time I've made this change. The issue of
having a blank screen at startup is due to x11 event loop + glX
interactions. Not sure what the problem is specifically, but
glXMakecurrent was blocking until the x11 event loop advanced.
The input and rendering are able to live on the same thread while still
removing unnecessary renders due to the
glutin::WindowProxy::wakeup_event_loop() method. The PtyReader just
kicks the event loop when there's something to do; otherwise, the event
loop just waits for something to happen and _doesn't_ draw in free run
mode.
Diffstat (limited to 'src/event.rs')
-rw-r--r-- | src/event.rs | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 00000000..85487d3a --- /dev/null +++ b/src/event.rs @@ -0,0 +1,81 @@ +//! Process window events +use std::sync::{Arc, mpsc}; +use std; + +use glutin; + +use input; +use sync::PriorityMutex; +use term::Term; +use tty::process_should_exit; + +/// The event processor +pub struct Processor<'a, W: 'a> { + writer: &'a mut W, + input_processor: input::Processor, + terminal: Arc<PriorityMutex<Term>>, + resize_tx: mpsc::Sender<(u32, u32)>, +} + +impl<'a, W> Processor<'a, W> + where W: std::io::Write +{ + /// Create a new event processor + /// + /// Takes a writer which is expected to be hooked up to the write end of a + /// pty. + pub fn new(writer: &mut W, + terminal: Arc<PriorityMutex<Term>>, + resize_tx: mpsc::Sender<(u32, u32)>) + -> Processor<W> + { + Processor { + writer: writer, + terminal: terminal, + input_processor: input::Processor::new(), + resize_tx: resize_tx, + } + } + + fn handle_event(&mut self, event: glutin::Event) { + match event { + glutin::Event::Closed => panic!("window closed"), // TODO ... + glutin::Event::ReceivedCharacter(c) => { + match c { + // Ignore BACKSPACE and DEL. These are handled specially. + '\u{8}' | '\u{7f}' => (), + // OSX arrow keys send invalid characters; ignore. + '\u{f700}' | '\u{f701}' | '\u{f702}' | '\u{f703}' => (), + _ => { + let encoded = c.encode_utf8(); + self.writer.write(encoded.as_slice()).unwrap(); + } + } + }, + glutin::Event::Resized(w, h) => { + self.resize_tx.send((w, h)).expect("send new size"); + }, + glutin::Event::KeyboardInput(state, _code, key, mods) => { + // Acquire term lock + let terminal = self.terminal.lock_high(); + + self.input_processor.process(state, key, mods, + &mut input::WriteNotifier(self.writer), + *terminal.mode()); + }, + _ => (), + } + } + + /// Process at least one event and handle any additional queued events. + pub fn process_events(&mut self, window: &glutin::Window) { + for event in window.wait_events() { + self.handle_event(event); + break; + } + + for event in window.poll_events() { + self.handle_event(event); + } + } +} |