From 9316771f64842533181cfb04a27aa9ae809cc435 Mon Sep 17 00:00:00 2001 From: Tuomas Siipola Date: Sat, 6 May 2017 08:45:23 -0700 Subject: [PATCH] Add window padding option Padding can be configured by using the `padding` field in the config file, like so: padding: x: 2 y: 2 which would result in a 2px padding within each side of the window. --- alacritty.yml | 7 +++ alacritty_macos.yml | 7 +++ src/config.rs | 13 ++++++ src/display.rs | 18 +++++--- src/input.rs | 2 + src/renderer/mod.rs | 41 +++++++++++++---- src/term/mod.rs | 48 ++++++++++++++++---- src/window.rs | 4 +- tests/ref/fish_cc/size.json | 2 +- tests/ref/indexed_256_colors/size.json | 2 +- tests/ref/ll/size.json | 2 +- tests/ref/tab_rendering/size.json | 2 +- tests/ref/tmux_git_log/size.json | 2 +- tests/ref/tmux_htop/size.json | 2 +- tests/ref/vim_large_window_scroll/size.json | 2 +- tests/ref/vim_simple_edit/size.json | 2 +- tests/ref/vttest_cursor_movement_1/size.json | 2 +- tests/ref/vttest_insert/size.json | 2 +- tests/ref/vttest_origin_mode_1/size.json | 2 +- tests/ref/vttest_origin_mode_2/size.json | 2 +- tests/ref/vttest_scroll/size.json | 2 +- tests/ref/vttest_tab_clear_set/size.json | 2 +- tests/ref/zsh_tab_completion/size.json | 2 +- 23 files changed, 129 insertions(+), 41 deletions(-) diff --git a/alacritty.yml b/alacritty.yml index f37e6ccb..5b6b5e63 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -20,6 +20,13 @@ dimensions: columns: 80 lines: 24 +# Adds this many blank pixels of padding around the window +# Units are physical pixels; this is not DPI aware. +# (change requires restart) +padding: + x: 2 + y: 2 + # The FreeType rasterizer needs to know the device DPI for best results # (changes require restart) dpi: diff --git a/alacritty_macos.yml b/alacritty_macos.yml index fce6d4b5..54a00b38 100644 --- a/alacritty_macos.yml +++ b/alacritty_macos.yml @@ -19,6 +19,13 @@ dimensions: columns: 80 lines: 24 +# Adds this many blank pixels of padding around the window +# Units are physical pixels; this is not DPI aware. +# (change requires restart) +padding: + x: 2 + y: 2 + # The FreeType rasterizer needs to know the device DPI for best results # (changes require restart) dpi: diff --git a/src/config.rs b/src/config.rs index 2b46b324..62e0ba49 100644 --- a/src/config.rs +++ b/src/config.rs @@ -182,6 +182,10 @@ pub struct Config { #[serde(default)] dimensions: Dimensions, + /// Pixel padding + #[serde(default="default_padding")] + padding: Delta, + /// Pixels per inch #[serde(default)] dpi: Dpi, @@ -235,6 +239,10 @@ pub struct Config { hide_cursor_when_typing: bool, } +fn default_padding() -> Delta { + Delta { x: 2., y: 2. } +} + #[cfg(not(target_os="macos"))] static DEFAULT_ALACRITTY_CONFIG: &'static str = include_str!("../alacritty.yml"); #[cfg(target_os="macos")] @@ -280,6 +288,7 @@ impl Default for Config { visual_bell: Default::default(), env: Default::default(), hide_cursor_when_typing: Default::default(), + padding: default_padding(), } } } @@ -1008,6 +1017,10 @@ impl Config { &self.selection } + pub fn padding(&self) -> &Delta { + &self.padding + } + #[inline] pub fn draw_bold_text_with_bright_colors(&self) -> bool { self.draw_bold_text_with_bright_colors diff --git a/src/display.rs b/src/display.rs index c2636e7e..73bb0fce 100644 --- a/src/display.rs +++ b/src/display.rs @@ -149,7 +149,7 @@ impl Display { let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr, config.use_thin_strokes())?; // Create renderer - let mut renderer = QuadRenderer::new(size)?; + let mut renderer = QuadRenderer::new(&config, size)?; // Initialize glyph cache let glyph_cache = { @@ -182,15 +182,21 @@ impl Display { let size = Size { width: Pixels(width), height: Pixels(height) }; info!("set_inner_size: {}", size); - window.set_inner_size(size); - renderer.resize(*size.width as _, *size.height as _); + let viewport_size = Size { + width: Pixels(width + 2 * config.padding().x as u32), + height: Pixels(width + 2 * config.padding().y as u32), + }; + window.set_inner_size(&viewport_size); + renderer.resize(viewport_size.width.0 as _, viewport_size.height.0 as _); info!("Cell Size: ({} x {})", cell_width, cell_height); let size_info = SizeInfo { - width: *size.width as f32, - height: *size.height as f32, + width: viewport_size.width.0 as f32, + height: viewport_size.height.0 as f32, cell_width: cell_width as f32, - cell_height: cell_height as f32 + cell_height: cell_height as f32, + padding_x: config.padding().x.floor(), + padding_y: config.padding().y.floor(), }; // Channel for resize events diff --git a/src/input.rs b/src/input.rs index e2b96c60..a1bd5c9a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -546,6 +546,8 @@ mod tests { height: 51.0, cell_width: 3.0, cell_height: 3.0, + padding_x: 0.0, + padding_y: 0.0, }; let mut terminal = Term::new(&config, size); diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 60d83287..016518e5 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -116,6 +116,9 @@ pub struct ShaderProgram { /// /// Rendering is split into two passes; 1 for backgrounds, and one for text u_background: GLint, + + padding_x: f32, + padding_y: f32, } @@ -276,7 +279,6 @@ impl GlyphCache { let mut rasterized = rasterizer.get_glyph(&glyph_key) .unwrap_or_else(|_| Default::default()); - // Apply offsets so they aren't computed every draw rasterized.left += glyph_offset.x as i32; rasterized.top += glyph_offset.y as i32; rasterized.top -= metrics.descent as i32; @@ -434,8 +436,8 @@ const ATLAS_SIZE: i32 = 1024; impl QuadRenderer { // TODO should probably hand this a transform instead of width/height - pub fn new(size: Size>) -> Result { - let program = ShaderProgram::new(size)?; + pub fn new(config: &Config, size: Size>) -> Result { + let program = ShaderProgram::new(config, size)?; let mut vao: GLuint = 0; let mut vbo: GLuint = 0; @@ -600,7 +602,7 @@ impl QuadRenderer { while let Ok(msg) = self.rx.try_recv() { match msg { Msg::ShaderReload => { - self.reload_shaders(Size { + self.reload_shaders(&config, Size { width: Pixels(props.width as u32), height: Pixels(props.height as u32) }); @@ -652,8 +654,9 @@ impl QuadRenderer { }) } - pub fn reload_shaders(&mut self, size: Size>) { - let program = match ShaderProgram::new(size) { + pub fn reload_shaders(&mut self, config: &Config, size: Size>) { + info!("Reloading shaders"); + let program = match ShaderProgram::new(config, size) { Ok(program) => program, Err(err) => { match err { @@ -675,9 +678,12 @@ impl QuadRenderer { } pub fn resize(&mut self, width: i32, height: i32) { + let padding_x = self.program.padding_x as i32; + let padding_y = self.program.padding_y as i32; + // viewport unsafe { - gl::Viewport(0, 0, width, height); + gl::Viewport(padding_x, padding_y, width - 2 * padding_x, height - 2 * padding_y); } // update projection @@ -874,7 +880,10 @@ impl ShaderProgram { } } - pub fn new(size: Size>) -> Result { + pub fn new( + config: &Config, + size: Size> + ) -> Result { let vertex_source = if cfg!(feature = "live-shader-reload") { None } else { @@ -937,6 +946,8 @@ impl ShaderProgram { u_cell_dim: cell_dim, u_visual_bell: visual_bell, u_background: background, + padding_x: config.padding().x.floor(), + padding_y: config.padding().y.floor(), }; shader.update_projection(*size.width as f32, *size.height as f32); @@ -947,8 +958,20 @@ impl ShaderProgram { } fn update_projection(&self, width: f32, height: f32) { + // Bounds check + if (width as u32) < (2 * self.padding_x as u32) || + (height as u32) < (2 * self.padding_y as u32) + { + return; + } + // set projection uniform - let ortho = cgmath::ortho(0., width, 0., height, -1., 1.); + // + // NB Not sure why padding change only requires changing the vertical + // translation in the projection, but this makes everything work + // correctly. + let ortho = cgmath::ortho(0., width - 2. * self.padding_x, 2. * self.padding_y, height, + -1., 1.); let projection: [[f32; 4]; 4] = ortho.into(); info!("width: {}, height: {}", width, height); diff --git a/src/term/mod.rs b/src/term/mod.rs index 4891e794..e7352ae7 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -551,26 +551,39 @@ pub struct SizeInfo { /// Height of individual cell pub cell_height: f32, + + /// Horizontal window padding + pub padding_x: f32, + + /// Horizontal window padding + pub padding_y: f32, } impl SizeInfo { #[inline] pub fn lines(&self) -> Line { - Line(((self.height - 4.0) / self.cell_height) as usize) + Line(((self.height - 2. * self.padding_y) / self.cell_height) as usize) } #[inline] pub fn cols(&self) -> Column { - Column(((self.width - 4.0) / self.cell_width) as usize) + Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize) + } + + fn contains_point(&self, x: usize, y:usize) -> bool { + x <= (self.width - self.padding_x) as usize || + x >= self.padding_x as usize || + y <= (self.height - self.padding_y) as usize || + y >= self.padding_y as usize } pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option { - if x > self.width as usize || y > self.height as usize { + if !self.contains_point(x, y) { return None; } - let col = Column(x / (self.cell_width as usize)); - let line = Line(y / (self.cell_height as usize)); + let col = Column((x - self.padding_x as usize) / (self.cell_width as usize)); + let line = Line((y - self.padding_y as usize) / (self.cell_height as usize)); Some(Point { line: min(line, self.lines() - 1), @@ -857,21 +870,32 @@ impl Term { /// Resize terminal to new dimensions pub fn resize(&mut self, width: f32, height: f32) { + 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 + { + 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.size_info.cols(); - let old_lines = self.size_info.lines(); + 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; if old_cols == num_cols && old_lines == num_lines { + debug!("Term::resize dimensions unchanged"); return; } @@ -1600,7 +1624,7 @@ impl ansi::Handler for Term { ansi::Mode::DECCOLM => self.deccolm(), ansi::Mode::Insert => self.mode.insert(mode::INSERT), // heh _ => { - debug!(".. ignoring set_mode"); + trace!(".. ignoring set_mode"); } } } @@ -1626,7 +1650,7 @@ impl ansi::Handler for Term { ansi::Mode::DECCOLM => self.deccolm(), ansi::Mode::Insert => self.mode.remove(mode::INSERT), _ => { - debug!(".. ignoring unset_mode"); + trace!(".. ignoring unset_mode"); } } } @@ -1684,6 +1708,8 @@ mod tests { height: 51.0, cell_width: 3.0, cell_height: 3.0, + padding_x: 0.0, + padding_y: 0.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid = Grid::new(Line(3), Column(5), &Cell::default()); @@ -1728,6 +1754,8 @@ mod tests { height: 51.0, cell_width: 3.0, cell_height: 3.0, + padding_x: 0.0, + padding_y: 0.0, }; let mut term = Term::new(&Default::default(), size); let mut grid: Grid = Grid::new(Line(1), Column(5), &Cell::default()); @@ -1771,6 +1799,8 @@ mod tests { height: 51.0, cell_width: 3.0, cell_height: 3.0, + padding_x: 0.0, + padding_y: 0.0, }; let mut term = Term::new(&Default::default(), size); let cursor = Point::new(Line(0), Column(0)); diff --git a/src/window.rs b/src/window.rs index b821c77b..00f60c38 100644 --- a/src/window.rs +++ b/src/window.rs @@ -360,11 +360,11 @@ impl Proxy { } pub trait SetInnerSize { - fn set_inner_size(&mut self, size: S); + fn set_inner_size(&mut self, size: &S); } impl SetInnerSize> for Window { - fn set_inner_size(&mut self, size: T) { + fn set_inner_size(&mut self, size: &T) { let size = size.to_points(self.hidpi_factor()); self.glutin_window.set_inner_size(*size.width as _, *size.height as _); } diff --git a/tests/ref/fish_cc/size.json b/tests/ref/fish_cc/size.json index 7dd55586..ae4135f0 100644 --- a/tests/ref/fish_cc/size.json +++ b/tests/ref/fish_cc/size.json @@ -1 +1 @@ -{"width":804.0,"height":604.0,"cell_width":10.0,"cell_height":25.0} \ No newline at end of file +{"width":804.0,"height":604.0,"cell_width":10.0,"cell_height":25.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/indexed_256_colors/size.json b/tests/ref/indexed_256_colors/size.json index 5464c394..3ee01660 100644 --- a/tests/ref/indexed_256_colors/size.json +++ b/tests/ref/indexed_256_colors/size.json @@ -1 +1 @@ -{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} \ No newline at end of file +{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/ll/size.json b/tests/ref/ll/size.json index 5464c394..3ee01660 100644 --- a/tests/ref/ll/size.json +++ b/tests/ref/ll/size.json @@ -1 +1 @@ -{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} \ No newline at end of file +{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/tab_rendering/size.json b/tests/ref/tab_rendering/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/tab_rendering/size.json +++ b/tests/ref/tab_rendering/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/tmux_git_log/size.json b/tests/ref/tmux_git_log/size.json index 5464c394..3ee01660 100644 --- a/tests/ref/tmux_git_log/size.json +++ b/tests/ref/tmux_git_log/size.json @@ -1 +1 @@ -{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} \ No newline at end of file +{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/tmux_htop/size.json b/tests/ref/tmux_htop/size.json index 5464c394..3ee01660 100644 --- a/tests/ref/tmux_htop/size.json +++ b/tests/ref/tmux_htop/size.json @@ -1 +1 @@ -{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} \ No newline at end of file +{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vim_large_window_scroll/size.json b/tests/ref/vim_large_window_scroll/size.json index ef03d128..ad3e054d 100644 --- a/tests/ref/vim_large_window_scroll/size.json +++ b/tests/ref/vim_large_window_scroll/size.json @@ -1 +1 @@ -{"width":1028.0,"height":769.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":1028.0,"height":769.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vim_simple_edit/size.json b/tests/ref/vim_simple_edit/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/vim_simple_edit/size.json +++ b/tests/ref/vim_simple_edit/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_cursor_movement_1/size.json b/tests/ref/vttest_cursor_movement_1/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/vttest_cursor_movement_1/size.json +++ b/tests/ref/vttest_cursor_movement_1/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_insert/size.json b/tests/ref/vttest_insert/size.json index 72f708f4..e3217b77 100644 --- a/tests/ref/vttest_insert/size.json +++ b/tests/ref/vttest_insert/size.json @@ -1 +1 @@ -{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0} \ No newline at end of file +{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_origin_mode_1/size.json b/tests/ref/vttest_origin_mode_1/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/vttest_origin_mode_1/size.json +++ b/tests/ref/vttest_origin_mode_1/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_origin_mode_2/size.json b/tests/ref/vttest_origin_mode_2/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/vttest_origin_mode_2/size.json +++ b/tests/ref/vttest_origin_mode_2/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_scroll/size.json b/tests/ref/vttest_scroll/size.json index 553273a2..eb12da0f 100644 --- a/tests/ref/vttest_scroll/size.json +++ b/tests/ref/vttest_scroll/size.json @@ -1 +1 @@ -{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} \ No newline at end of file +{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/vttest_tab_clear_set/size.json b/tests/ref/vttest_tab_clear_set/size.json index 72f708f4..e3217b77 100644 --- a/tests/ref/vttest_tab_clear_set/size.json +++ b/tests/ref/vttest_tab_clear_set/size.json @@ -1 +1 @@ -{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0} \ No newline at end of file +{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file diff --git a/tests/ref/zsh_tab_completion/size.json b/tests/ref/zsh_tab_completion/size.json index 061294c5..958c4a24 100644 --- a/tests/ref/zsh_tab_completion/size.json +++ b/tests/ref/zsh_tab_completion/size.json @@ -1 +1 @@ -{"width":1204.0,"height":676.0,"cell_width":15.0,"cell_height":28.0} \ No newline at end of file +{"width":1204.0,"height":676.0,"cell_width":15.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0} \ No newline at end of file