Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Add backdrop_blur_ignore_transparent configuration support to decouple status background color and blur opacity
src/server/config.rs | 16 ++++++++++++++++
src/server/layer_shell.rs | 3 +++
src/server/window.rs | 14 ++++++++++++--
src/server/wlroots_log_wrapper.c | 10 ++++++----
src/server/xdg_toplevel.rs | 6 ++++++
wrapper.h | 2 +-
6 files changed, 44 insertions(+), 7 deletions(-)
diff --git a/src/server/config.rs b/src/server/config.rs
index 396726b..b56c293 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -45,6 +45,8 @@ pub struct Layout {
pub desktop_grid_scale: f64,
pub desktop_line_width: i32,
pub scenefx_optimized_blur: bool,
+ pub status_backdrop_blur_ignore_transparent: bool,
+ pub window_backdrop_blur_ignore_transparent: bool,
}
impl Default for Layout {
@@ -88,6 +90,8 @@ impl Default for Layout {
desktop_grid_scale: 100.0,
desktop_line_width: 1,
scenefx_optimized_blur: true,
+ status_backdrop_blur_ignore_transparent: true,
+ window_backdrop_blur_ignore_transparent: true,
}
}
}
@@ -355,6 +359,10 @@ pub struct LayoutConfig {
pub status_background_blur: f64,
#[serde(default = "default_window_opacity")]
pub window_opacity: bool,
+ #[serde(default = "default_status_backdrop_blur_ignore_transparent")]
+ pub status_backdrop_blur_ignore_transparent: bool,
+ #[serde(default = "default_window_backdrop_blur_ignore_transparent")]
+ pub window_backdrop_blur_ignore_transparent: bool,
}
impl Default for LayoutConfig {
@@ -377,6 +385,8 @@ impl Default for LayoutConfig {
status_normal_color: default_status_normal_color(),
status_background_blur: default_status_background_blur(),
window_opacity: default_window_opacity(),
+ status_backdrop_blur_ignore_transparent: default_status_backdrop_blur_ignore_transparent(),
+ window_backdrop_blur_ignore_transparent: default_window_backdrop_blur_ignore_transparent(),
}
}
}
@@ -398,6 +408,8 @@ fn default_overlay_border_gap() -> i64 { 0 }
fn default_status_normal_color() -> String { "#ccccd8".to_string() }
fn default_status_background_blur() -> f64 { 0.8 }
fn default_window_opacity() -> bool { true }
+fn default_status_backdrop_blur_ignore_transparent() -> bool { true }
+fn default_window_backdrop_blur_ignore_transparent() -> bool { true }
#[derive(Debug, Deserialize)]
pub struct ModeRuleConfig {
@@ -943,6 +955,7 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
layout.transition_duration = get_nested_prop_i64(node, "window", "transition_duration", default_transition_duration());
layout.window_blur = get_nested_prop_bool(node, "window", "blur", default_window_blur());
layout.window_opacity = get_nested_prop_bool(node, "window", "opacity", default_window_opacity());
+ layout.window_backdrop_blur_ignore_transparent = get_nested_prop_bool(node, "window", "backdrop_blur_ignore_transparent", default_window_backdrop_blur_ignore_transparent());
layout.overlay_behavior = get_nested_prop_string(node, "overlay", "behavior", &default_overlay_behavior());
layout.overlay_width = get_nested_prop_i64(node, "overlay", "width", default_overlay_width());
@@ -951,6 +964,7 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
layout.status_normal_color = get_nested_prop_string(node, "status", "normal_color", &default_status_normal_color());
layout.status_background_blur = get_nested_prop_f64(node, "status", "background_blur", default_status_background_blur());
+ layout.status_backdrop_blur_ignore_transparent = get_nested_prop_bool(node, "status", "backdrop_blur_ignore_transparent", default_status_backdrop_blur_ignore_transparent());
}
// 2. env
@@ -1212,6 +1226,8 @@ pub fn parse_config(path: &str, state: &mut crate::window_manager::WindowManager
state.layout.transparency_opacity = config.transparency.as_ref().and_then(|t| t.opacity).unwrap_or(0.9) as f32;
state.layout.window_opacity = config.layout.window_opacity;
state.layout.scenefx_optimized_blur = config.output.as_ref().map(|o| o.scenefx_optimized_blur).unwrap_or(true);
+ state.layout.status_backdrop_blur_ignore_transparent = config.layout.status_backdrop_blur_ignore_transparent;
+ state.layout.window_backdrop_blur_ignore_transparent = config.layout.window_backdrop_blur_ignore_transparent;
for (key, val) in &config.env {
let expanded = expand_env_vars(val);
diff --git a/src/server/layer_shell.rs b/src/server/layer_shell.rs
index 4133111..9f7fe55 100644
--- a/src/server/layer_shell.rs
+++ b/src/server/layer_shell.rs
@@ -585,16 +585,19 @@ unsafe extern "C" fn handle_layer_surface_commit(listener: *mut ffi::wl_listener
if (*wlr_layer_surface).current.layer != ffi::zwlr_layer_shell_v1_layer_ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND {
let server = (*layer_surface).server;
let mut blur_enabled = true;
+ let mut ignore_transparent = (*server).wm.layout.window_backdrop_blur_ignore_transparent;
if !(*wlr_layer_surface).namespace.is_null() {
let ns = std::ffi::CStr::from_ptr((*wlr_layer_surface).namespace).to_string_lossy();
if ns == "cce-status" {
blur_enabled = (*server).wm.layout.status_background_blur > 0.001;
+ ignore_transparent = (*server).wm.layout.status_backdrop_blur_ignore_transparent;
}
}
ffi::river_scene_node_enable_blur(
(*(*layer_surface).scene_layer_surface).tree as *mut ffi::wlr_scene_node,
blur_enabled,
(*server).wm.layout.scenefx_optimized_blur,
+ ignore_transparent,
);
}
diff --git a/src/server/window.rs b/src/server/window.rs
index e4770f7..b5c99f3 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1538,7 +1538,12 @@ impl Window {
blur_enabled = false;
}
}
- ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, blur_enabled, (*self.server).wm.layout.scenefx_optimized_blur);
+ let app_id = self.get_app_id_string().unwrap_or_default();
+ let mut ignore_transparent = (*self.server).wm.layout.window_backdrop_blur_ignore_transparent;
+ if app_id.starts_with("cce-status") {
+ ignore_transparent = (*self.server).wm.layout.status_backdrop_blur_ignore_transparent;
+ }
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, blur_enabled, (*self.server).wm.layout.scenefx_optimized_blur, ignore_transparent);
ffi::river_scene_node_set_opacity(self.tree as *mut ffi::wlr_scene_node, requested.opacity);
let radius = if requested.circular {
@@ -2744,7 +2749,12 @@ impl Decoration {
self.surfaces.drop_saved();
let server = (*self.window).server;
- ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, self.rendering_requested.blur, (*server).wm.layout.scenefx_optimized_blur);
+ let app_id = (*self.window).get_app_id_string().unwrap_or_default();
+ let mut ignore_transparent = (*server).wm.layout.window_backdrop_blur_ignore_transparent;
+ if app_id.starts_with("cce-status") {
+ ignore_transparent = (*server).wm.layout.status_backdrop_blur_ignore_transparent;
+ }
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, self.rendering_requested.blur, (*server).wm.layout.scenefx_optimized_blur, ignore_transparent);
let scale = (*self.window).scale;
let scaled_x = (self.rendering_requested.offset_x as f64 * scale) as i32;
diff --git a/src/server/wlroots_log_wrapper.c b/src/server/wlroots_log_wrapper.c
index bb059c9..401aafa 100644
--- a/src/server/wlroots_log_wrapper.c
+++ b/src/server/wlroots_log_wrapper.c
@@ -655,6 +655,7 @@ void river_wlr_keyboard_init(struct wlr_keyboard *keyboard,
struct river_blur_data {
bool enabled;
bool optimized;
+ bool ignore_transparent;
};
static void enable_blur_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
@@ -667,17 +668,18 @@ static void enable_blur_iterator(struct wlr_scene_buffer *buffer, int sx, int sy
struct river_blur_data *data = (struct river_blur_data *)user_data;
bool enabled = data->enabled;
bool optimized = data->optimized && enabled;
+ bool ignore_transparent = data->ignore_transparent && enabled;
if (buffer->backdrop_blur != enabled ||
buffer->backdrop_blur_optimized != optimized ||
- buffer->backdrop_blur_ignore_transparent != enabled) {
+ buffer->backdrop_blur_ignore_transparent != ignore_transparent) {
wlr_scene_buffer_set_backdrop_blur(buffer, enabled);
wlr_scene_buffer_set_backdrop_blur_optimized(buffer, optimized);
- wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, enabled);
+ wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, ignore_transparent);
}
}
-void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized) {
- struct river_blur_data data = { .enabled = enabled, .optimized = optimized };
+void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent) {
+ struct river_blur_data data = { .enabled = enabled, .optimized = optimized, .ignore_transparent = ignore_transparent };
wlr_scene_node_for_each_buffer(node, enable_blur_iterator, &data);
}
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index bf2a48b..709f578 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -408,10 +408,16 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
let window = (*toplevel).window;
let base = ffi::river_wlr_xdg_toplevel_get_base((*toplevel).wlr_toplevel);
+ let app_id = (*window).get_app_id_string().unwrap_or_default();
+ let mut ignore_transparent = (*(*window).server).wm.layout.window_backdrop_blur_ignore_transparent;
+ if app_id.starts_with("cce-status") {
+ ignore_transparent = (*(*window).server).wm.layout.status_backdrop_blur_ignore_transparent;
+ }
ffi::river_scene_node_enable_blur(
(*window).surfaces.tree as *mut ffi::wlr_scene_node,
(*window).rendering_requested.blur,
(*(*window).server).wm.layout.scenefx_optimized_blur,
+ ignore_transparent,
);
let capture_node = &mut (*(*window).capture_scene).tree as *mut ffi::wlr_scene_tree as *mut ffi::wlr_scene_node;
diff --git a/wrapper.h b/wrapper.h
index 6027d53..51b4c01 100644
--- a/wrapper.h
+++ b/wrapper.h
@@ -257,7 +257,7 @@ struct wlr_seat_client *river_wlr_drag_get_seat_client(struct wlr_drag *drag);
void river_wlr_keyboard_init(struct wlr_keyboard *keyboard, void (*led_update)(struct wlr_keyboard *keyboard, uint32_t leds), const char *name);
-void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized);
+void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent);
void river_scene_node_set_opacity(struct wlr_scene_node *node, float opacity);