1
0
Fork 0
mirror of https://github.com/alacritty/alacritty.git synced 2024-11-25 14:05:41 -05:00

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.
This commit is contained in:
Tuomas Siipola 2017-05-06 08:45:23 -07:00 committed by Joe Wilm
parent 149fbaef09
commit 9316771f64
23 changed files with 129 additions and 41 deletions

View file

@ -20,6 +20,13 @@ dimensions:
columns: 80 columns: 80
lines: 24 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 # The FreeType rasterizer needs to know the device DPI for best results
# (changes require restart) # (changes require restart)
dpi: dpi:

View file

@ -19,6 +19,13 @@ dimensions:
columns: 80 columns: 80
lines: 24 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 # The FreeType rasterizer needs to know the device DPI for best results
# (changes require restart) # (changes require restart)
dpi: dpi:

View file

@ -182,6 +182,10 @@ pub struct Config {
#[serde(default)] #[serde(default)]
dimensions: Dimensions, dimensions: Dimensions,
/// Pixel padding
#[serde(default="default_padding")]
padding: Delta,
/// Pixels per inch /// Pixels per inch
#[serde(default)] #[serde(default)]
dpi: Dpi, dpi: Dpi,
@ -235,6 +239,10 @@ pub struct Config {
hide_cursor_when_typing: bool, hide_cursor_when_typing: bool,
} }
fn default_padding() -> Delta {
Delta { x: 2., y: 2. }
}
#[cfg(not(target_os="macos"))] #[cfg(not(target_os="macos"))]
static DEFAULT_ALACRITTY_CONFIG: &'static str = include_str!("../alacritty.yml"); static DEFAULT_ALACRITTY_CONFIG: &'static str = include_str!("../alacritty.yml");
#[cfg(target_os="macos")] #[cfg(target_os="macos")]
@ -280,6 +288,7 @@ impl Default for Config {
visual_bell: Default::default(), visual_bell: Default::default(),
env: Default::default(), env: Default::default(),
hide_cursor_when_typing: Default::default(), hide_cursor_when_typing: Default::default(),
padding: default_padding(),
} }
} }
} }
@ -1008,6 +1017,10 @@ impl Config {
&self.selection &self.selection
} }
pub fn padding(&self) -> &Delta {
&self.padding
}
#[inline] #[inline]
pub fn draw_bold_text_with_bright_colors(&self) -> bool { pub fn draw_bold_text_with_bright_colors(&self) -> bool {
self.draw_bold_text_with_bright_colors self.draw_bold_text_with_bright_colors

View file

@ -149,7 +149,7 @@ impl Display {
let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr, config.use_thin_strokes())?; let rasterizer = font::Rasterizer::new(dpi.x(), dpi.y(), dpr, config.use_thin_strokes())?;
// Create renderer // Create renderer
let mut renderer = QuadRenderer::new(size)?; let mut renderer = QuadRenderer::new(&config, size)?;
// Initialize glyph cache // Initialize glyph cache
let glyph_cache = { let glyph_cache = {
@ -182,15 +182,21 @@ impl Display {
let size = Size { width: Pixels(width), height: Pixels(height) }; let size = Size { width: Pixels(width), height: Pixels(height) };
info!("set_inner_size: {}", size); info!("set_inner_size: {}", size);
window.set_inner_size(size); let viewport_size = Size {
renderer.resize(*size.width as _, *size.height as _); 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); info!("Cell Size: ({} x {})", cell_width, cell_height);
let size_info = SizeInfo { let size_info = SizeInfo {
width: *size.width as f32, width: viewport_size.width.0 as f32,
height: *size.height as f32, height: viewport_size.height.0 as f32,
cell_width: cell_width 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 // Channel for resize events

View file

@ -546,6 +546,8 @@ mod tests {
height: 51.0, height: 51.0,
cell_width: 3.0, cell_width: 3.0,
cell_height: 3.0, cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
}; };
let mut terminal = Term::new(&config, size); let mut terminal = Term::new(&config, size);

View file

@ -116,6 +116,9 @@ pub struct ShaderProgram {
/// ///
/// Rendering is split into two passes; 1 for backgrounds, and one for text /// Rendering is split into two passes; 1 for backgrounds, and one for text
u_background: GLint, u_background: GLint,
padding_x: f32,
padding_y: f32,
} }
@ -276,7 +279,6 @@ impl GlyphCache {
let mut rasterized = rasterizer.get_glyph(&glyph_key) let mut rasterized = rasterizer.get_glyph(&glyph_key)
.unwrap_or_else(|_| Default::default()); .unwrap_or_else(|_| Default::default());
// Apply offsets so they aren't computed every draw
rasterized.left += glyph_offset.x as i32; rasterized.left += glyph_offset.x as i32;
rasterized.top += glyph_offset.y as i32; rasterized.top += glyph_offset.y as i32;
rasterized.top -= metrics.descent as i32; rasterized.top -= metrics.descent as i32;
@ -434,8 +436,8 @@ const ATLAS_SIZE: i32 = 1024;
impl QuadRenderer { impl QuadRenderer {
// TODO should probably hand this a transform instead of width/height // TODO should probably hand this a transform instead of width/height
pub fn new(size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> { pub fn new(config: &Config, size: Size<Pixels<u32>>) -> Result<QuadRenderer, Error> {
let program = ShaderProgram::new(size)?; let program = ShaderProgram::new(config, size)?;
let mut vao: GLuint = 0; let mut vao: GLuint = 0;
let mut vbo: GLuint = 0; let mut vbo: GLuint = 0;
@ -600,7 +602,7 @@ impl QuadRenderer {
while let Ok(msg) = self.rx.try_recv() { while let Ok(msg) = self.rx.try_recv() {
match msg { match msg {
Msg::ShaderReload => { Msg::ShaderReload => {
self.reload_shaders(Size { self.reload_shaders(&config, Size {
width: Pixels(props.width as u32), width: Pixels(props.width as u32),
height: Pixels(props.height as u32) height: Pixels(props.height as u32)
}); });
@ -652,8 +654,9 @@ impl QuadRenderer {
}) })
} }
pub fn reload_shaders(&mut self, size: Size<Pixels<u32>>) { pub fn reload_shaders(&mut self, config: &Config, size: Size<Pixels<u32>>) {
let program = match ShaderProgram::new(size) { info!("Reloading shaders");
let program = match ShaderProgram::new(config, size) {
Ok(program) => program, Ok(program) => program,
Err(err) => { Err(err) => {
match err { match err {
@ -675,9 +678,12 @@ impl QuadRenderer {
} }
pub fn resize(&mut self, width: i32, height: i32) { 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 // viewport
unsafe { unsafe {
gl::Viewport(0, 0, width, height); gl::Viewport(padding_x, padding_y, width - 2 * padding_x, height - 2 * padding_y);
} }
// update projection // update projection
@ -874,7 +880,10 @@ impl ShaderProgram {
} }
} }
pub fn new(size: Size<Pixels<u32>>) -> Result<ShaderProgram, ShaderCreationError> { pub fn new(
config: &Config,
size: Size<Pixels<u32>>
) -> Result<ShaderProgram, ShaderCreationError> {
let vertex_source = if cfg!(feature = "live-shader-reload") { let vertex_source = if cfg!(feature = "live-shader-reload") {
None None
} else { } else {
@ -937,6 +946,8 @@ impl ShaderProgram {
u_cell_dim: cell_dim, u_cell_dim: cell_dim,
u_visual_bell: visual_bell, u_visual_bell: visual_bell,
u_background: background, 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); 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) { 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 // 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(); let projection: [[f32; 4]; 4] = ortho.into();
info!("width: {}, height: {}", width, height); info!("width: {}, height: {}", width, height);

View file

@ -551,26 +551,39 @@ pub struct SizeInfo {
/// Height of individual cell /// Height of individual cell
pub cell_height: f32, pub cell_height: f32,
/// Horizontal window padding
pub padding_x: f32,
/// Horizontal window padding
pub padding_y: f32,
} }
impl SizeInfo { impl SizeInfo {
#[inline] #[inline]
pub fn lines(&self) -> Line { 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] #[inline]
pub fn cols(&self) -> Column { 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<Point> { pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {
if x > self.width as usize || y > self.height as usize { if !self.contains_point(x, y) {
return None; return None;
} }
let col = Column(x / (self.cell_width as usize)); let col = Column((x - self.padding_x as usize) / (self.cell_width as usize));
let line = Line(y / (self.cell_height as usize)); let line = Line((y - self.padding_y as usize) / (self.cell_height as usize));
Some(Point { Some(Point {
line: min(line, self.lines() - 1), line: min(line, self.lines() - 1),
@ -857,21 +870,32 @@ impl Term {
/// Resize terminal to new dimensions /// Resize terminal to new dimensions
pub fn resize(&mut self, width: f32, height: f32) { 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 { let size = SizeInfo {
width: width, width: width,
height: height, height: height,
cell_width: self.size_info.cell_width, cell_width: self.size_info.cell_width,
cell_height: self.size_info.cell_height, 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_cols = self.grid.num_cols();
let old_lines = self.size_info.lines(); let old_lines = self.grid.num_lines();
let mut num_cols = size.cols(); let mut num_cols = size.cols();
let mut num_lines = size.lines(); let mut num_lines = size.lines();
self.size_info = size; self.size_info = size;
if old_cols == num_cols && old_lines == num_lines { if old_cols == num_cols && old_lines == num_lines {
debug!("Term::resize dimensions unchanged");
return; return;
} }
@ -1600,7 +1624,7 @@ impl ansi::Handler for Term {
ansi::Mode::DECCOLM => self.deccolm(), ansi::Mode::DECCOLM => self.deccolm(),
ansi::Mode::Insert => self.mode.insert(mode::INSERT), // heh 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::DECCOLM => self.deccolm(),
ansi::Mode::Insert => self.mode.remove(mode::INSERT), 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, height: 51.0,
cell_width: 3.0, cell_width: 3.0,
cell_height: 3.0, cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
}; };
let mut term = Term::new(&Default::default(), size); let mut term = Term::new(&Default::default(), size);
let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), &Cell::default()); let mut grid: Grid<Cell> = Grid::new(Line(3), Column(5), &Cell::default());
@ -1728,6 +1754,8 @@ mod tests {
height: 51.0, height: 51.0,
cell_width: 3.0, cell_width: 3.0,
cell_height: 3.0, cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
}; };
let mut term = Term::new(&Default::default(), size); let mut term = Term::new(&Default::default(), size);
let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), &Cell::default()); let mut grid: Grid<Cell> = Grid::new(Line(1), Column(5), &Cell::default());
@ -1771,6 +1799,8 @@ mod tests {
height: 51.0, height: 51.0,
cell_width: 3.0, cell_width: 3.0,
cell_height: 3.0, cell_height: 3.0,
padding_x: 0.0,
padding_y: 0.0,
}; };
let mut term = Term::new(&Default::default(), size); let mut term = Term::new(&Default::default(), size);
let cursor = Point::new(Line(0), Column(0)); let cursor = Point::new(Line(0), Column(0));

View file

@ -360,11 +360,11 @@ impl Proxy {
} }
pub trait SetInnerSize<T> { pub trait SetInnerSize<T> {
fn set_inner_size<S: ToPoints>(&mut self, size: S); fn set_inner_size<S: ToPoints>(&mut self, size: &S);
} }
impl SetInnerSize<Pixels<u32>> for Window { impl SetInnerSize<Pixels<u32>> for Window {
fn set_inner_size<T: ToPoints>(&mut self, size: T) { fn set_inner_size<T: ToPoints>(&mut self, size: &T) {
let size = size.to_points(self.hidpi_factor()); let size = size.to_points(self.hidpi_factor());
self.glutin_window.set_inner_size(*size.width as _, *size.height as _); self.glutin_window.set_inner_size(*size.width as _, *size.height as _);
} }

View file

@ -1 +1 @@
{"width":804.0,"height":604.0,"cell_width":10.0,"cell_height":25.0} {"width":804.0,"height":604.0,"cell_width":10.0,"cell_height":25.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} {"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} {"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} {"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0} {"width":1124.0,"height":628.0,"cell_width":14.0,"cell_height":26.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1028.0,"height":769.0,"cell_width":8.0,"cell_height":17.0} {"width":1028.0,"height":769.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0} {"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0} {"width":644.0,"height":412.0,"cell_width":8.0,"cell_height":17.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0} {"width":1124.0,"height":676.0,"cell_width":14.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0}

View file

@ -1 +1 @@
{"width":1204.0,"height":676.0,"cell_width":15.0,"cell_height":28.0} {"width":1204.0,"height":676.0,"cell_width":15.0,"cell_height":28.0,"padding_x":0.0,"padding_y":0.0}