diff options
author | Gabriel Martinez <reitaka@gmail.com> | 2017-08-20 09:55:45 -0700 |
---|---|---|
committer | Joe Wilm <jwilm@users.noreply.github.com> | 2017-08-20 09:55:45 -0700 |
commit | 5009566ea5c46a85fa243b18ce4b7fe8e0b89b62 (patch) | |
tree | cc14c0de9686a52f0732a4a7ec29b5c23ea86efb | |
parent | 4e9b1c590e8b0990f5f43fa9d7c53a31a92840a8 (diff) | |
download | alacritty-5009566ea5c46a85fa243b18ce4b7fe8e0b89b62.tar.gz alacritty-5009566ea5c46a85fa243b18ce4b7fe8e0b89b62.zip |
Add background_opacity option to set terminal transparency (#331)
The option is an Alpha struct that ensures that the contained float is
between 0.0 and 1.0. Background colors are multiplied by the opacity
to properly alpha blend them.
-rw-r--r-- | alacritty.yml | 3 | ||||
-rw-r--r-- | alacritty_macos.yml | 3 | ||||
-rw-r--r-- | res/text.f.glsl | 8 | ||||
-rw-r--r-- | src/config.rs | 53 | ||||
-rw-r--r-- | src/renderer/mod.rs | 22 | ||||
-rw-r--r-- | src/window.rs | 3 |
6 files changed, 83 insertions, 9 deletions
diff --git a/alacritty.yml b/alacritty.yml index 686cb387..2e9ad785 100644 --- a/alacritty.yml +++ b/alacritty.yml @@ -158,6 +158,9 @@ visual_bell: animation: EaseOutExpo duration: 0 +# Background opacity +background_opacity: 1.0 + # Key bindings # # Each binding is defined as an object with some properties. Most of the diff --git a/alacritty_macos.yml b/alacritty_macos.yml index 007d3b42..956cedf8 100644 --- a/alacritty_macos.yml +++ b/alacritty_macos.yml @@ -158,6 +158,9 @@ visual_bell: animation: EaseOutExpo duration: 0 +# Background opacity +background_opacity: 1.0 + # Key bindings # # Each binding is defined as an object with some properties. Most of the diff --git a/res/text.f.glsl b/res/text.f.glsl index 70d50b38..dd60333c 100644 --- a/res/text.f.glsl +++ b/res/text.f.glsl @@ -21,15 +21,17 @@ flat in int background; layout(location = 0, index = 0) out vec4 color; layout(location = 0, index = 1) out vec4 alphaMask; +uniform float bgOpacity; uniform sampler2D mask; void main() { if (background != 0) { - alphaMask = vec4(1.0, 1.0, 1.0, 1.0); - color = vec4(bg + vb, 1.0); + alphaMask = vec4(1.0); + color = vec4(bg + vb, 1.0) * bgOpacity; } else { - alphaMask = vec4(texture(mask, TexCoords).rgb, 1.0); + vec3 textColor = texture(mask, TexCoords).rgb; + alphaMask = vec4(textColor, textColor.r); color = vec4(fg, 1.0); } } diff --git a/src/config.rs b/src/config.rs index 59c675cd..450ab09e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -173,6 +173,40 @@ impl<'a> Shell<'a> { } } +/// Wrapper around f32 that represents an alpha value between 0.0 and 1.0 +#[derive(Clone, Copy, Debug)] +pub struct Alpha(f32); + +impl Alpha { + pub fn new(value: f32) -> Self { + Alpha(Self::clamp_to_valid_range(value)) + } + + pub fn set(&mut self, value: f32) { + self.0 = Self::clamp_to_valid_range(value); + } + + pub fn get(&self) -> f32 { + self.0 + } + + fn clamp_to_valid_range(value: f32) -> f32 { + if value < 0.0 { + 0.0 + } else if value > 1.0 { + 1.0 + } else { + value + } + } +} + +impl Default for Alpha { + fn default() -> Self { + Alpha(1.0) + } +} + /// Top-level config type #[derive(Debug, Deserialize)] pub struct Config { @@ -211,6 +245,10 @@ pub struct Config { #[serde(default)] colors: Colors, + /// Background opacity from 0.0 to 1.0 + #[serde(default)] + background_opacity: Alpha, + /// Keybindings #[serde(default="default_key_bindings")] key_bindings: Vec<KeyBinding>, @@ -281,6 +319,7 @@ impl Default for Config { render_timer: Default::default(), custom_cursor_colors: false, colors: Default::default(), + background_opacity: Default::default(), key_bindings: Vec::new(), mouse_bindings: Vec::new(), selection: Default::default(), @@ -696,6 +735,16 @@ impl de::Deserialize for RawBinding { } } + +impl de::Deserialize for Alpha { + fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> + where D: de::Deserializer + { + let value = f32::deserialize(deserializer)?; + Ok(Alpha::new(value)) + } +} + impl de::Deserialize for MouseBinding { fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error> where D: de::Deserializer @@ -1038,6 +1087,10 @@ impl Config { &self.colors } + pub fn background_opacity(&self) -> Alpha { + self.background_opacity + } + pub fn key_bindings(&self) -> &[KeyBinding] { &self.key_bindings[..] } diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 3cad4a01..0dad716e 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -119,6 +119,8 @@ pub struct ShaderProgram { padding_x: f32, padding_y: f32, + + u_bg_opacity: GLint, } @@ -604,6 +606,7 @@ impl QuadRenderer { self.program.activate(); self.program.set_term_uniforms(props); self.program.set_visual_bell(visual_bell_intensity as _); + self.program.set_bg_opacity(config.background_opacity().get()); gl::BindVertexArray(self.vao); gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, self.ebo); @@ -685,12 +688,13 @@ impl QuadRenderer { impl<'a> RenderApi<'a> { pub fn clear(&self, color: Rgb) { + let alpha = self.config.background_opacity().get(); unsafe { gl::ClearColor( - (self.visual_bell_intensity + color.r as f32 / 255.0).min(1.0), - (self.visual_bell_intensity + color.g as f32 / 255.0).min(1.0), - (self.visual_bell_intensity + color.b as f32 / 255.0).min(1.0), - 1.0 + (self.visual_bell_intensity + color.r as f32 / 255.0).min(1.0) * alpha, + (self.visual_bell_intensity + color.g as f32 / 255.0).min(1.0) * alpha, + (self.visual_bell_intensity + color.b as f32 / 255.0).min(1.0) * alpha, + alpha ); gl::Clear(gl::COLOR_BUFFER_BIT); } @@ -916,13 +920,14 @@ impl ShaderProgram { } // get uniform locations - let (projection, term_dim, cell_dim, visual_bell, background) = unsafe { + let (projection, term_dim, cell_dim, visual_bell, background, bg_opacity) = unsafe { ( gl::GetUniformLocation(program, cptr!(b"projection\0")), gl::GetUniformLocation(program, cptr!(b"termDim\0")), gl::GetUniformLocation(program, cptr!(b"cellDim\0")), gl::GetUniformLocation(program, cptr!(b"visualBell\0")), gl::GetUniformLocation(program, cptr!(b"backgroundPass\0")), + gl::GetUniformLocation(program, cptr!(b"bgOpacity\0")), ) }; @@ -937,6 +942,7 @@ impl ShaderProgram { u_background: background, padding_x: config.padding().x.floor(), padding_y: config.padding().y.floor(), + u_bg_opacity: bg_opacity, }; shader.update_projection(*size.width as f32, *size.height as f32); @@ -997,6 +1003,12 @@ impl ShaderProgram { } } + fn set_bg_opacity(&self, bg_opacity: f32) { + unsafe { + gl::Uniform1f(self.u_bg_opacity, bg_opacity); + } + } + fn create_program(vertex: GLuint, fragment: GLuint) -> GLuint { unsafe { let program = gl::CreateProgram(); diff --git a/src/window.rs b/src/window.rs index 83274f83..d5d35b8e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -186,7 +186,8 @@ impl Window { Window::platform_window_init(); let window = WindowBuilder::new() - .with_title(title); + .with_title(title) + .with_transparency(true); let context = ContextBuilder::new() .with_vsync(true); let window = ::glutin::GlWindow::new(window, context, &event_loop)?; |