Make background flat when using transparent terminals

This commit is contained in:
Carlos de Paula 2025-11-09 20:27:51 -03:00
parent 6387ed0098
commit 7cd45d938d
8 changed files with 84 additions and 1 deletions

View file

@ -0,0 +1,38 @@
use mlua::{IntoLua, Lua, MetaMethod, Table, UserData, Value};
use super::Area;
#[derive(Clone, Debug, Default)]
pub struct Block {
pub area: Area,
pub style: ratatui::style::Style,
}
impl Block {
pub fn compose(lua: &Lua) -> mlua::Result<Value> {
let new = lua.create_function(|_, _: Table| Ok(Self::default()))?;
let block = lua.create_table()?;
block.set_metatable(Some(lua.create_table_from([(MetaMethod::Call.name(), new)])?))?;
block.into_lua(lua)
}
pub(super) fn render(self, rect: ratatui::layout::Rect, buf: &mut ratatui::buffer::Buffer) {
// Only render if there's actually a background color set
if let Some(bg) = self.style.bg {
for y in rect.top()..rect.bottom() {
for x in rect.left()..rect.right() {
buf[(x, y)].set_bg(bg);
}
}
}
}
}
impl UserData for Block {
fn add_methods<M: mlua::UserDataMethods<Self>>(methods: &mut M) {
crate::impl_area_method!(methods);
crate::impl_style_method!(methods, style);
crate::impl_style_shorthands!(methods, style);
}
}

View file

@ -9,6 +9,7 @@ pub fn compose(p_get: ComposerGet, p_set: ComposerSet) -> Composer<ComposerGet,
match key {
b"Align" => super::Align::compose(lua)?,
b"Bar" => super::Bar::compose(lua)?,
b"Block" => super::Block::compose(lua)?,
b"Border" => super::Border::compose(lua)?,
b"Clear" => super::Clear::compose(lua)?,
b"Constraint" => super::Constraint::compose(lua)?,

View file

@ -2,7 +2,7 @@ use std::any::TypeId;
use mlua::{AnyUserData, ExternalError};
use super::{Bar, Border, Clear, Gauge, Line, List, Table, Text};
use super::{Bar, Block, Border, Clear, Gauge, Line, List, Table, Text};
use crate::{Error, elements::Area};
#[derive(Clone, Debug)]
@ -11,6 +11,7 @@ pub enum Renderable {
Text(Text),
List(Box<List>),
Bar(Bar),
Block(Block),
Clear(Clear),
Border(Border),
Gauge(Box<Gauge>),
@ -24,6 +25,7 @@ impl Renderable {
Self::Text(text) => text.area,
Self::List(list) => list.area,
Self::Bar(bar) => bar.area,
Self::Block(block) => block.area,
Self::Clear(clear) => clear.area,
Self::Border(border) => border.area,
Self::Gauge(gauge) => gauge.area,
@ -38,6 +40,7 @@ impl Renderable {
Self::Text(text) => text.area = area,
Self::List(list) => list.area = area,
Self::Bar(bar) => bar.area = area,
Self::Block(block) => block.area = area,
Self::Clear(clear) => clear.area = area,
Self::Border(border) => border.area = area,
Self::Gauge(gauge) => gauge.area = area,
@ -52,6 +55,7 @@ impl Renderable {
Self::Text(text) => text.render(rect, buf),
Self::List(list) => list.render(rect, buf),
Self::Bar(bar) => bar.render(rect, buf),
Self::Block(block) => block.render(rect, buf),
Self::Clear(clear) => clear.render(rect, buf),
Self::Border(border) => border.render(rect, buf),
Self::Gauge(gauge) => gauge.render(rect, buf),
@ -77,6 +81,7 @@ impl TryFrom<&AnyUserData> for Renderable {
Some(t) if t == TypeId::of::<Text>() => Self::Text(ud.take()?),
Some(t) if t == TypeId::of::<List>() => Self::List(Box::new(ud.take()?)),
Some(t) if t == TypeId::of::<Bar>() => Self::Bar(ud.take()?),
Some(t) if t == TypeId::of::<Block>() => Self::Block(ud.take()?),
Some(t) if t == TypeId::of::<Clear>() => Self::Clear(ud.take()?),
Some(t) if t == TypeId::of::<Border>() => Self::Border(ud.take()?),
Some(t) if t == TypeId::of::<Gauge>() => Self::Gauge(Box::new(ud.take()?)),

View file

@ -21,6 +21,11 @@ light = ""
[app]
overall = {}
[app.panes]
parent = ""
current = ""
preview = ""
# : }}}

View file

@ -21,6 +21,11 @@ light = ""
[app]
overall = {}
[app.panes]
parent = ""
current = ""
preview = ""
# : }}}

View file

@ -37,6 +37,14 @@ pub struct Theme {
#[derive(Deserialize, DeserializeOver2)]
pub struct App {
pub overall: Style,
pub panes: AppPanes,
}
#[derive(Deserialize, DeserializeOver2)]
pub struct AppPanes {
pub parent: String,
pub current: String,
pub preview: String,
}
#[derive(Deserialize, DeserializeOver2)]

View file

@ -2,6 +2,7 @@ use mlua::{ObjectLike, Table};
use ratatui::{buffer::Buffer, layout::Rect, widgets::Widget};
use tracing::error;
use yazi_binding::elements::render_once;
use yazi_config::THEME;
use yazi_core::Core;
use yazi_plugin::LUA;
@ -68,5 +69,18 @@ impl Widget for Root<'_> {
if self.core.which.visible {
which::Which::new(self.core).render(area, buf);
}
// Fill background on all cells to create an opaque background (like fzf does).
// This is done AFTER all rendering so text/foreground colors are already set.
if !THEME.app.background.is_empty() {
if let Ok(bg_color) = THEME.app.background.parse::<ratatui::style::Color>() {
for y in area.top()..area.bottom() {
for x in area.left()..area.right() {
// Set background on every cell, but don't touch foreground
buf[(x, y)].set_bg(bg_color);
}
}
}
}
}
}

View file

@ -35,6 +35,13 @@ fn app() -> Composer<ComposerGet, ComposerSet> {
match key {
b"overall" => Style::from(a.overall).into_lua(lua),
b"panes" => lua
.create_table_from([
("parent", lua.create_string(&a.panes.parent)?),
("current", lua.create_string(&a.panes.current)?),
("preview", lua.create_string(&a.panes.preview)?),
])?
.into_lua(lua),
_ => Ok(Value::Nil),
}
}