aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.rs63
-rw-r--r--src/event.rs24
-rw-r--r--src/main.rs36
-rw-r--r--src/term/mod.rs14
-rw-r--r--src/tty.rs20
5 files changed, 79 insertions, 78 deletions
diff --git a/src/display.rs b/src/display.rs
index cfe684c0..b16bf95a 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -30,7 +30,7 @@ use term::{Term, SizeInfo};
use window::{self, Size, Pixels, Window, SetInnerSize};
/// The display wraps a window, font rasterizer, and GPU renderer
-pub struct Display<F> {
+pub struct Display {
window: Window,
renderer: QuadRenderer,
glyph_cache: GlyphCache,
@@ -38,22 +38,24 @@ pub struct Display<F> {
rx: mpsc::Receiver<(u32, u32)>,
tx: mpsc::Sender<(u32, u32)>,
meter: Meter,
- resize_callback: Option<F>,
size_info: SizeInfo,
}
/// Can wakeup the render loop from other threads
pub struct Notifier(window::Proxy);
+/// Types that are interested in when the display is resized
+pub trait OnResize {
+ fn on_resize(&mut self, size: &SizeInfo);
+}
+
impl Notifier {
pub fn notify(&self) {
self.0.wakeup_event_loop();
}
}
-impl<F> Display<F>
- where F: Fn(&SizeInfo)
-{
+impl Display {
pub fn notifier(&self) -> Notifier {
Notifier(self.window.create_window_proxy())
}
@@ -63,11 +65,6 @@ impl<F> Display<F>
self.render_timer = config.render_timer();
}
- /// Provide a callback to be invoked then the display changes size.
- pub fn set_resize_callback(&mut self, callback: F) {
- self.resize_callback = Some(callback);
- }
-
/// Get size info about the display
pub fn size(&self) -> &SizeInfo {
&self.size_info
@@ -76,7 +73,7 @@ impl<F> Display<F>
pub fn new(
config: &Config,
options: &cli::Options,
- ) -> Result<Display<F>, window::Error> {
+ ) -> Result<Display, window::Error> {
// Extract some properties from config
let font = config.font();
let dpi = config.dpi();
@@ -156,7 +153,6 @@ impl<F> Display<F>
tx: tx,
rx: rx,
meter: Meter::new(),
- resize_callback: None,
size_info: size_info,
};
@@ -179,27 +175,14 @@ impl<F> Display<F>
&self.window
}
- /// Draw the screen
- ///
- /// A reference to Term whose state is being drawn must be provided.
- ///
- /// This call may block if vsync is enabled
- pub fn draw(&mut self, mut terminal: MutexGuard<Term>, config: &Config) {
- // This is a hack since sometimes we get stuck waiting for events
- // in the main loop otherwise.
- //
- // TODO figure out why this is necessary
- self.window.clear_wakeup_flag();
-
- // Clear dirty flag
- terminal.dirty = false;
-
+ /// Process pending resize events
+ pub fn handle_resize(&mut self, terminal: &mut MutexGuard<Term>, items: &mut [&mut OnResize]) {
// Resize events new_size and are handled outside the poll_events
// iterator. This has the effect of coalescing multiple resize
// events into one.
let mut new_size = None;
- // Check for any out-of-band resize events (mac only)
+ // Take most recent resize event, if any
while let Ok(sz) = self.rx.try_recv() {
new_size = Some(sz);
}
@@ -209,11 +192,31 @@ impl<F> Display<F>
if let Some((w, h)) = new_size.take() {
terminal.resize(w as f32, h as f32);
let size = terminal.size_info();
- self.resize_callback.as_ref()
- .map(|func| func(&size));
+
+ for mut item in items {
+ item.on_resize(size)
+ }
+
self.renderer.resize(w as i32, h as i32);
}
+ }
+
+ /// Draw the screen
+ ///
+ /// A reference to Term whose state is being drawn must be provided.
+ ///
+ /// This call may block if vsync is enabled
+ pub fn draw(&mut self, mut terminal: MutexGuard<Term>, config: &Config) {
+ // This is a hack since sometimes we get stuck waiting for events
+ // in the main loop otherwise.
+ //
+ // TODO figure out why this is necessary
+ self.window.clear_wakeup_flag();
+
+ // Clear dirty flag
+ terminal.dirty = false;
+
{
let glyph_cache = &mut self.glyph_cache;
// Draw grid
diff --git a/src/event.rs b/src/event.rs
index 4f28649e..b9a8551d 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -6,12 +6,12 @@ use serde_json as json;
use glutin;
-use window::Window;
-
+use config::Config;
+use display::OnResize;
use input;
use sync::FairMutex;
-use term::{self, Term};
-use config::Config;
+use term::{Term, SizeInfo};
+use window::Window;
/// The event processor
pub struct Processor<N> {
@@ -22,6 +22,15 @@ pub struct Processor<N> {
ref_test: bool,
}
+/// Notify that the terminal was resized
+///
+/// Currently this just forwards the notice to the input processor.
+impl<N> OnResize for Processor<N> {
+ fn on_resize(&mut self, size: &SizeInfo) {
+ self.input_processor.resize(size);
+ }
+}
+
impl<N: input::Notify> Processor<N> {
/// Create a new event processor
///
@@ -48,13 +57,6 @@ impl<N: input::Notify> Processor<N> {
}
}
- /// Notify that the terminal was resized
- ///
- /// Currently this just forwards the notice to the input processor.
- pub fn resize(&mut self, size_info: &term::SizeInfo) {
- self.input_processor.resize(size_info);
- }
-
fn handle_event(&mut self, event: glutin::Event, wakeup_request: &mut bool) {
match event {
glutin::Event::Closed => {
diff --git a/src/main.rs b/src/main.rs
index 7ae45787..c917fe43 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -18,9 +18,7 @@
#[macro_use]
extern crate alacritty;
-use std::cell::RefCell;
use std::error::Error;
-use std::rc::Rc;
use std::sync::Arc;
use alacritty::cli;
@@ -86,7 +84,7 @@ fn run(config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// The pty forks a process to run the shell on the slave side of the
// pseudoterminal. A file descriptor for the master side is retained for
// reading/writing to the shell.
- let pty = tty::new(display.size());
+ let mut pty = tty::new(display.size());
// Create the pseudoterminal I/O loop
//
@@ -108,28 +106,13 @@ fn run(config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// Event processor
//
// Need the Rc<RefCell<_>> here since a ref is shared in the resize callback
- let processor = Rc::new(RefCell::new(event::Processor::new(
+ let mut processor = event::Processor::new(
input::LoopNotifier(loop_tx),
terminal.clone(),
display.resize_channel(),
&config,
options.ref_test,
- )));
-
- // Configure the display resize callback
- let processor_ref = processor.clone();
- display.set_resize_callback(move |size| {
- // Resizing the pty lets the child processes know the window changed
- // size.
- pty.resize(size);
-
- // It's a bit funny that the event processor is in this callback since
- // on some platforms it's the first to be aware of a resize event. It
- // appears here since resizes are processed out-of-band from when the
- // events arrive. This way, the processor state is updated at the same
- // time as the rest of the system.
- processor_ref.borrow_mut().resize(size)
- });
+ );
// Create a config monitor when config was loaded from path
//
@@ -144,20 +127,27 @@ fn run(config: Config, options: cli::Options) -> Result<(), Box<Error>> {
// Main display loop
loop {
// Process input and window events
- let wakeup_request = processor.borrow_mut().process_events(display.window());
+ let wakeup_request = processor.process_events(display.window());
// Handle config reloads
let config_updated = config_monitor.as_ref()
.and_then(|monitor| monitor.pending_config())
.map(|config| {
display.update_config(&config);
- processor.borrow_mut().update_config(&config);
+ processor.update_config(&config);
true
}).unwrap_or(false);
// Maybe draw the terminal
- let terminal = terminal.lock();
+ let mut terminal = terminal.lock();
if wakeup_request || config_updated {
+ // Handle pending resize events
+ //
+ // The second argument is a list of types that want to be notified
+ // of display size changes.
+ display.handle_resize(&mut terminal, &mut [&mut pty, &mut processor]);
+
+ // Draw the current state of the terminal
display.draw(terminal, &config);
}
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 523fcb62..fb31af9b 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -23,20 +23,6 @@ use grid::{Grid, ClearRegion};
use index::{Cursor, Column, Line};
use ansi::{Color, NamedColor};
-use tty::ToWinsize;
-use libc::{self, winsize};
-
-impl<'a> ToWinsize for &'a SizeInfo {
- fn to_winsize(&self) -> winsize {
- winsize {
- ws_row: self.lines().0 as libc::c_ushort,
- ws_col: self.cols().0 as libc::c_ushort,
- ws_xpixel: self.width as libc::c_ushort,
- ws_ypixel: self.height as libc::c_ushort,
- }
- }
-}
-
pub mod cell;
pub use self::cell::Cell;
diff --git a/src/tty.rs b/src/tty.rs
index 7071bad3..667daf04 100644
--- a/src/tty.rs
+++ b/src/tty.rs
@@ -23,6 +23,9 @@ use std::ptr;
use libc::{self, winsize, c_int, pid_t, WNOHANG, WIFEXITED, WEXITSTATUS, SIGCHLD};
+use term::SizeInfo;
+use display::OnResize;
+
/// Process ID of child process
///
/// Necessary to put this in static storage for `sigchld` to have access
@@ -326,6 +329,23 @@ pub trait ToWinsize {
fn to_winsize(&self) -> winsize;
}
+impl<'a> ToWinsize for &'a SizeInfo {
+ fn to_winsize(&self) -> winsize {
+ winsize {
+ ws_row: self.lines().0 as libc::c_ushort,
+ ws_col: self.cols().0 as libc::c_ushort,
+ ws_xpixel: self.width as libc::c_ushort,
+ ws_ypixel: self.height as libc::c_ushort,
+ }
+ }
+}
+
+impl OnResize for Pty {
+ fn on_resize(&mut self, size: &SizeInfo) {
+ self.resize(size);
+ }
+}
+
unsafe fn set_nonblocking(fd: c_int) {
use libc::{fcntl, F_SETFL, F_GETFL, O_NONBLOCK};