mirror of
https://github.com/alacritty/alacritty.git
synced 2024-11-25 14:05:41 -05:00
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.
This commit is contained in:
parent
4e9b1c590e
commit
5009566ea5
6 changed files with 83 additions and 9 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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[..]
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)?;
|
||||
|
|
Loading…
Reference in a new issue