aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Aloni <alonid@gmail.com>2017-10-14 20:35:56 +0300
committerJoe Wilm <jwilm@users.noreply.github.com>2017-10-14 10:35:56 -0700
commit8a0b1d9c3f5a9ddb98469a340bbcd06374d4a24e (patch)
tree80768003f9a2f3c99b0238dc68f4c9b119cc77d6
parentfd410f9ec8bc53e35d46cc213244c978ef7c5816 (diff)
downloadalacritty-8a0b1d9c3f5a9ddb98469a340bbcd06374d4a24e.tar.gz
alacritty-8a0b1d9c3f5a9ddb98469a340bbcd06374d4a24e.zip
Implement user actions for font resize (#625)
Adds support for font resizing at run-time. Three new actions are introduced: * IncreaseFontSize - Increases current font size by 1.0 * DecreaseFontSize - Decreases current font size by 1.0 * ResetFontSize - Resets font size to that specified in the configuration. The stock config files have example configuration for each which should match gnome-terminal. For convenience, the config entries are: - { key: Key0, mods: Control, action: ResetFontSize } - { key: Equals, mods: Control, action: IncreaseFontSize } - { key: Subtract, mods: Control, action: DecreaseFontSize }
-rw-r--r--alacritty.yml3
-rw-r--r--alacritty_macos.yml3
-rw-r--r--src/config.rs21
-rw-r--r--src/display.rs98
-rw-r--r--src/event.rs8
-rw-r--r--src/input.rs24
-rw-r--r--src/main.rs2
-rw-r--r--src/renderer/mod.rs5
-rw-r--r--src/term/mod.rs34
9 files changed, 149 insertions, 49 deletions
diff --git a/alacritty.yml b/alacritty.yml
index c5684397..f69640da 100644
--- a/alacritty.yml
+++ b/alacritty.yml
@@ -215,6 +215,9 @@ key_bindings:
- { key: Q, mods: Command, action: Quit }
- { key: W, mods: Command, action: Quit }
- { key: Insert, mods: Shift, action: PasteSelection }
+ - { key: Key0, mods: Control, action: ResetFontSize }
+ - { key: Equals, mods: Control, action: IncreaseFontSize }
+ - { key: Subtract, mods: Control, action: DecreaseFontSize }
- { key: Home, chars: "\x1bOH", mode: AppCursor }
- { key: Home, chars: "\x1b[H", mode: ~AppCursor }
- { key: End, chars: "\x1bOF", mode: AppCursor }
diff --git a/alacritty_macos.yml b/alacritty_macos.yml
index 1a16a8c9..61f53868 100644
--- a/alacritty_macos.yml
+++ b/alacritty_macos.yml
@@ -196,6 +196,9 @@ key_bindings:
- { key: Home, chars: "\x1b[H", mode: ~AppCursor }
- { key: End, chars: "\x1bOF", mode: AppCursor }
- { key: End, chars: "\x1b[F", mode: ~AppCursor }
+ - { key: Key0, mods: Control, action: ResetFontSize }
+ - { key: Equals, mods: Control, action: IncreaseFontSize }
+ - { key: Subtract, mods: Control, action: DecreaseFontSize }
- { key: PageUp, mods: Shift, chars: "\x1b[5;2~" }
- { key: PageUp, mods: Control, chars: "\x1b[5;5~" }
- { key: PageUp, chars: "\x1b[5~" }
diff --git a/src/config.rs b/src/config.rs
index 4dffa70a..a310ff81 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -409,6 +409,9 @@ impl<'a> de::Deserialize<'a> for ActionWrapper {
"Paste" => Action::Paste,
"Copy" => Action::Copy,
"PasteSelection" => Action::PasteSelection,
+ "IncreaseFontSize" => Action::IncreaseFontSize,
+ "DecreaseFontSize" => Action::DecreaseFontSize,
+ "ResetFontSize" => Action::ResetFontSize,
"Quit" => Action::Quit,
_ => return Err(E::invalid_value(Unexpected::Str(value), &self)),
}))
@@ -1298,7 +1301,7 @@ impl DeserializeFromF32 for Size {
/// field in this struct. It might be nice in the future to have defaults for
/// each value independently. Alternatively, maybe erroring when the user
/// doesn't provide complete config is Ok.
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct Font {
/// Font family
pub normal: FontDescription,
@@ -1311,7 +1314,7 @@ pub struct Font {
// Font size in points
#[serde(deserialize_with="DeserializeFromF32::deserialize_from_f32")]
- size: Size,
+ pub size: Size,
/// Extra spacing per character
offset: Delta,
@@ -1333,7 +1336,7 @@ fn default_italic_desc() -> FontDescription {
}
/// Description of a single font
-#[derive(Debug, Deserialize)]
+#[derive(Debug, Deserialize, Clone)]
pub struct FontDescription {
pub family: String,
pub style: Option<String>,
@@ -1366,6 +1369,18 @@ impl Font {
pub fn glyph_offset(&self) -> &Delta {
&self.glyph_offset
}
+
+ /// Get a font clone with a size modification
+ pub fn with_size_delta(self, delta: f32) -> Font {
+ let mut new_size = self.size.as_f32_pts() + delta;
+ if new_size < 1.0 {
+ new_size = 1.0;
+ }
+ Font {
+ size : Size::new(new_size),
+ .. self
+ }
+ }
}
#[cfg(target_os = "macos")]
diff --git a/src/display.rs b/src/display.rs
index cb5cf8c9..25318f0e 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -96,6 +96,7 @@ pub struct Display {
rx: mpsc::Receiver<(u32, u32)>,
tx: mpsc::Sender<(u32, u32)>,
meter: Meter,
+ font_size_modifier: i8,
size_info: SizeInfo,
last_background_color: Rgb,
}
@@ -133,7 +134,6 @@ impl Display {
options: &cli::Options,
) -> Result<Display, Error> {
// Extract some properties from config
- let font = config.font();
let render_timer = config.render_timer();
// Create the window where Alacritty will be displayed
@@ -146,39 +146,17 @@ impl Display {
info!("device_pixel_ratio: {}", dpr);
- let rasterizer = font::Rasterizer::new(dpr, config.use_thin_strokes())?;
-
// Create renderer
let mut renderer = QuadRenderer::new(&config, size)?;
- // Initialize glyph cache
- let glyph_cache = {
- info!("Initializing glyph cache");
- let init_start = ::std::time::Instant::now();
-
- let cache = renderer.with_loader(|mut api| {
- GlyphCache::new(rasterizer, config, &mut api)
- })?;
-
- let stop = init_start.elapsed();
- let stop_f = stop.as_secs() as f64 + stop.subsec_nanos() as f64 / 1_000_000_000f64;
- info!("Finished initializing glyph cache in {}", stop_f);
-
- cache
- };
-
- // Need font metrics to resize the window properly. This suggests to me the
- // font metrics should be computed before creating the window in the first
- // place so that a resize is not needed.
- let metrics = glyph_cache.font_metrics();
- let cell_width = (metrics.average_advance + font.offset().x as f64) as u32;
- let cell_height = (metrics.line_height + font.offset().y as f64) as u32;
+ let (glyph_cache, cell_width, cell_height) =
+ Self::new_glyph_cache(&window, &mut renderer, config, 0)?;
// Resize window to specified dimensions
let dimensions = options.dimensions()
.unwrap_or_else(|| config.dimensions());
- let width = cell_width * dimensions.columns_u32();
- let height = cell_height * dimensions.lines_u32();
+ let width = cell_width as u32 * dimensions.columns_u32();
+ let height = cell_height as u32 * dimensions.lines_u32();
let size = Size { width: Pixels(width), height: Pixels(height) };
info!("set_inner_size: {}", size);
@@ -222,11 +200,56 @@ impl Display {
tx: tx,
rx: rx,
meter: Meter::new(),
+ font_size_modifier: 0,
size_info: size_info,
last_background_color: background_color,
})
}
+ fn new_glyph_cache(window : &Window, renderer : &mut QuadRenderer,
+ config: &Config, font_size_delta: i8)
+ -> Result<(GlyphCache, f32, f32), Error>
+ {
+ let font = config.font().clone().with_size_delta(font_size_delta as f32);
+ let dpr = window.hidpi_factor();
+ let rasterizer = font::Rasterizer::new(dpr, config.use_thin_strokes())?;
+
+ // Initialize glyph cache
+ let glyph_cache = {
+ info!("Initializing glyph cache");
+ let init_start = ::std::time::Instant::now();
+
+ let cache = renderer.with_loader(|mut api| {
+ GlyphCache::new(rasterizer, &font, &mut api)
+ })?;
+
+ let stop = init_start.elapsed();
+ let stop_f = stop.as_secs() as f64 + stop.subsec_nanos() as f64 / 1_000_000_000f64;
+ info!("Finished initializing glyph cache in {}", stop_f);
+
+ cache
+ };
+
+ // Need font metrics to resize the window properly. This suggests to me the
+ // font metrics should be computed before creating the window in the first
+ // place so that a resize is not needed.
+ let metrics = glyph_cache.font_metrics();
+ let cell_width = (metrics.average_advance + font.offset().x as f64) as u32;
+ let cell_height = (metrics.line_height + font.offset().y as f64) as u32;
+
+ return Ok((glyph_cache, cell_width as f32, cell_height as f32));
+ }
+
+ pub fn update_glyph_cache(&mut self, config: &Config, font_size_delta: i8)
+ {
+ let (glyph_cache, cell_width, cell_height) =
+ Self::new_glyph_cache(&self.window,
+ &mut self.renderer, config, font_size_delta).unwrap();
+ self.glyph_cache = glyph_cache;
+ self.size_info.cell_width = cell_width;
+ self.size_info.cell_height = cell_height;
+ }
+
#[inline]
pub fn resize_channel(&self) -> mpsc::Sender<(u32, u32)> {
self.tx.clone()
@@ -240,6 +263,7 @@ impl Display {
pub fn handle_resize(
&mut self,
terminal: &mut MutexGuard<Term>,
+ config: &Config,
items: &mut [&mut OnResize]
) {
// Resize events new_size and are handled outside the poll_events
@@ -252,11 +276,27 @@ impl Display {
new_size = Some(sz);
}
+ if terminal.font_size_modifier != self.font_size_modifier {
+ // Font size modification detected
+
+ self.font_size_modifier = terminal.font_size_modifier;
+ self.update_glyph_cache(config, terminal.font_size_modifier);
+
+ if new_size == None {
+ // Force a resize to refresh things
+ new_size = Some((self.size_info.width as u32,
+ self.size_info.height as u32));
+ }
+ }
+
// Receive any resize events; only call gl::Viewport on last
// available
if let Some((w, h)) = new_size.take() {
- terminal.resize(w as f32, h as f32);
- let size = terminal.size_info();
+ self.size_info.width = w as f32;
+ self.size_info.height = h as f32;
+
+ let size = &self.size_info;
+ terminal.resize(size);
for item in items {
item.on_resize(size)
diff --git a/src/event.rs b/src/event.rs
index 95685001..dda18652 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -107,6 +107,14 @@ impl<'a, N: Notify + 'a> input::ActionContext for ActionContext<'a, N> {
self.terminal.pixels_to_coords(self.mouse.x as usize, self.mouse.y as usize)
}
+ fn change_font_size(&mut self, delta: i8) {
+ self.terminal.change_font_size(delta);
+ }
+
+ fn reset_font_size(&mut self) {
+ self.terminal.reset_font_size();
+ }
+
#[inline]
fn mouse_mut(&mut self) -> &mut Mouse {
self.mouse
diff --git a/src/input.rs b/src/input.rs
index 4be7dac5..7378e8dc 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -62,6 +62,8 @@ pub trait ActionContext {
fn received_count(&mut self) -> &mut usize;
fn suppress_chars(&mut self) -> &mut bool;
fn last_modifiers(&mut self) -> &mut ModifiersState;
+ fn change_font_size(&mut self, delta: i8);
+ fn reset_font_size(&mut self);
}
/// Describes a state and action to take in that state
@@ -154,6 +156,15 @@ pub enum Action {
/// Paste contents of selection buffer
PasteSelection,
+ /// Increase font size
+ IncreaseFontSize,
+
+ /// Decrease font size
+ DecreaseFontSize,
+
+ /// Reset font size to the config value
+ ResetFontSize,
+
/// Run given command
Command(String, Vec<String>),
@@ -202,6 +213,15 @@ impl Action {
// FIXME should do a more graceful shutdown
::std::process::exit(0);
},
+ Action::IncreaseFontSize => {
+ ctx.change_font_size(1);
+ },
+ Action::DecreaseFontSize => {
+ ctx.change_font_size(-1);
+ }
+ Action::ResetFontSize => {
+ ctx.reset_font_size();
+ }
}
}
@@ -593,6 +613,10 @@ mod tests {
fn last_modifiers(&mut self) -> &mut ModifiersState {
&mut self.last_modifiers
}
+ fn change_font_size(&mut self, _delta: i8) {
+ }
+ fn reset_font_size(&mut self) {
+ }
}
macro_rules! test_clickstate {
diff --git a/src/main.rs b/src/main.rs
index ec327009..ca7a40c6 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -188,7 +188,7 @@ fn run(mut config: Config, options: cli::Options) -> Result<(), Box<Error>> {
//
// 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]);
+ display.handle_resize(&mut terminal, &config, &mut [&mut pty, &mut processor]);
// Draw the current state of the terminal
display.draw(terminal, &config, processor.selection.as_ref());
diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs
index 9ce690ca..9e6036d4 100644
--- a/src/renderer/mod.rs
+++ b/src/renderer/mod.rs
@@ -29,7 +29,7 @@ use gl;
use index::{Line, Column, RangeInclusive};
use notify::{Watcher, watcher, RecursiveMode, DebouncedEvent};
-use config::{self, Config, Delta};
+use config::{self, Config, Font, Delta};
use term::{self, cell, RenderableCell};
use window::{Size, Pixels};
@@ -170,12 +170,11 @@ pub struct GlyphCache {
impl GlyphCache {
pub fn new<L>(
mut rasterizer: Rasterizer,
- config: &Config,
+ font: &Font,
loader: &mut L
) -> Result<GlyphCache, font::Error>
where L: LoadGlyph
{
- let font = config.font();
let size = font.size();
let glyph_offset = *font.glyph_offset();
diff --git a/src/term/mod.rs b/src/term/mod.rs
index f9bd5541..a16971b5 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -655,6 +655,9 @@ pub struct Term {
/// Scroll region
scroll_region: Range<Line>,
+ /// Font size modifier
+ pub font_size_modifier: i8,
+
/// Size
size_info: SizeInfo,
@@ -767,6 +770,7 @@ impl Term {
grid: grid,
alt_grid: alt,
alt: false,
+ font_size_modifier: 0,
active_charset: Default::default(),
cursor: Default::default(),
cursor_save: Default::default(),
@@ -783,6 +787,18 @@ impl Term {
}
}
+ pub fn change_font_size(&mut self, delta: i8) {
+ if let Some(sum) = self.font_size_modifier.checked_add(delta) {
+ self.font_size_modifier = sum;
+ self.dirty = true;
+ }
+ }
+
+ pub fn reset_font_size(&mut self) {
+ self.font_size_modifier = 0;
+ self.dirty = true;
+ }
+
pub fn update_config(&mut self, config: &Config) {
self.semantic_escape_chars = config.selection().semantic_escape_chars.clone();
self.original_colors.fill_named(config.colors());
@@ -965,30 +981,22 @@ impl Term {
}
/// Resize terminal to new dimensions
- pub fn resize(&mut self, width: f32, height: f32) {
+ pub fn resize(&mut self, size : &SizeInfo) {
debug!("Term::resize");
+
// Bounds check; lots of math assumes width and height are > 0
- if width as usize <= 2 * self.size_info.padding_x as usize ||
- height as usize <= 2 * self.size_info.padding_y as usize
+ if size.width as usize <= 2 * self.size_info.padding_x as usize ||
+ size.height as usize <= 2 * self.size_info.padding_y as usize
{
return;
}
- let size = SizeInfo {
- width: width,
- height: height,
- cell_width: self.size_info.cell_width,
- cell_height: self.size_info.cell_height,
- padding_x: self.size_info.padding_x,
- padding_y: self.size_info.padding_y,
- };
-
let old_cols = self.grid.num_cols();
let old_lines = self.grid.num_lines();
let mut num_cols = size.cols();
let mut num_lines = size.lines();
- self.size_info = size;
+ self.size_info = *size;
if old_cols == num_cols && old_lines == num_lines {
debug!("Term::resize dimensions unchanged");