From 7cd45d938d92e4f05300d7cf74ff94f8d8f9d3ae Mon Sep 17 00:00:00 2001 From: Carlos de Paula Date: Sun, 9 Nov 2025 20:27:51 -0300 Subject: [PATCH] Make background flat when using transparent terminals --- yazi-binding/src/elements/block.rs | 38 +++++++++++++++++++++++++ yazi-binding/src/elements/elements.rs | 1 + yazi-binding/src/elements/renderable.rs | 7 ++++- yazi-config/preset/theme-dark.toml | 5 ++++ yazi-config/preset/theme-light.toml | 5 ++++ yazi-config/src/theme/theme.rs | 8 ++++++ yazi-fm/src/root.rs | 14 +++++++++ yazi-plugin/src/theme/theme.rs | 7 +++++ 8 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 yazi-binding/src/elements/block.rs diff --git a/yazi-binding/src/elements/block.rs b/yazi-binding/src/elements/block.rs new file mode 100644 index 00000000..b2371189 --- /dev/null +++ b/yazi-binding/src/elements/block.rs @@ -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 { + 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>(methods: &mut M) { + crate::impl_area_method!(methods); + crate::impl_style_method!(methods, style); + crate::impl_style_shorthands!(methods, style); + } +} diff --git a/yazi-binding/src/elements/elements.rs b/yazi-binding/src/elements/elements.rs index 7414c145..6f3c8c7c 100644 --- a/yazi-binding/src/elements/elements.rs +++ b/yazi-binding/src/elements/elements.rs @@ -9,6 +9,7 @@ pub fn compose(p_get: ComposerGet, p_set: ComposerSet) -> Composer 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)?, diff --git a/yazi-binding/src/elements/renderable.rs b/yazi-binding/src/elements/renderable.rs index 8d4b5578..4824dea1 100644 --- a/yazi-binding/src/elements/renderable.rs +++ b/yazi-binding/src/elements/renderable.rs @@ -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), Bar(Bar), + Block(Block), Clear(Clear), Border(Border), Gauge(Box), @@ -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::() => Self::Text(ud.take()?), Some(t) if t == TypeId::of::() => Self::List(Box::new(ud.take()?)), Some(t) if t == TypeId::of::() => Self::Bar(ud.take()?), + Some(t) if t == TypeId::of::() => Self::Block(ud.take()?), Some(t) if t == TypeId::of::() => Self::Clear(ud.take()?), Some(t) if t == TypeId::of::() => Self::Border(ud.take()?), Some(t) if t == TypeId::of::() => Self::Gauge(Box::new(ud.take()?)), diff --git a/yazi-config/preset/theme-dark.toml b/yazi-config/preset/theme-dark.toml index d4bb9230..5d0669a0 100644 --- a/yazi-config/preset/theme-dark.toml +++ b/yazi-config/preset/theme-dark.toml @@ -21,6 +21,11 @@ light = "" [app] overall = {} +[app.panes] +parent = "" +current = "" +preview = "" + # : }}} diff --git a/yazi-config/preset/theme-light.toml b/yazi-config/preset/theme-light.toml index 8bd2c90e..2070c514 100644 --- a/yazi-config/preset/theme-light.toml +++ b/yazi-config/preset/theme-light.toml @@ -21,6 +21,11 @@ light = "" [app] overall = {} +[app.panes] +parent = "" +current = "" +preview = "" + # : }}} diff --git a/yazi-config/src/theme/theme.rs b/yazi-config/src/theme/theme.rs index b607dbb7..c42a2b7a 100644 --- a/yazi-config/src/theme/theme.rs +++ b/yazi-config/src/theme/theme.rs @@ -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)] diff --git a/yazi-fm/src/root.rs b/yazi-fm/src/root.rs index 47073260..c14d9006 100644 --- a/yazi-fm/src/root.rs +++ b/yazi-fm/src/root.rs @@ -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::() { + 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); + } + } + } + } } } diff --git a/yazi-plugin/src/theme/theme.rs b/yazi-plugin/src/theme/theme.rs index dfc5c8d0..5084e1e3 100644 --- a/yazi-plugin/src/theme/theme.rs +++ b/yazi-plugin/src/theme/theme.rs @@ -35,6 +35,13 @@ fn app() -> Composer { 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), } }