Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Pass explicit geometry bounds to river_scene_node_enable_blur to match window content
src/server/layer_shell.rs | 4 ++++
src/server/window.rs | 19 ++++++++++++++++---
src/server/wlroots_log_wrapper.c | 19 +++++++++++++------
src/server/xdg_toplevel.rs | 8 ++++++++
wrapper.h | 2 +-
5 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/src/server/layer_shell.rs b/src/server/layer_shell.rs
index 9f7fe55..acd75b5 100644
--- a/src/server/layer_shell.rs
+++ b/src/server/layer_shell.rs
@@ -598,6 +598,10 @@ unsafe extern "C" fn handle_layer_surface_commit(listener: *mut ffi::wl_listener
blur_enabled,
(*server).wm.layout.scenefx_optimized_blur,
ignore_transparent,
+ 0,
+ 0,
+ 0,
+ 0,
);
}
diff --git a/src/server/window.rs b/src/server/window.rs
index 733426b..c52c8b9 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1539,7 +1539,20 @@ impl Window {
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);
+ let geom_x = self.rendering_requested.x;
+ let geom_y = self.rendering_requested.y;
+ let geom_w = self.rendering_sent.width as i32;
+ let geom_h = self.rendering_sent.height as i32;
+ 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,
+ geom_x,
+ geom_y,
+ geom_w,
+ geom_h,
+ );
ffi::river_scene_node_set_opacity(self.tree as *mut ffi::wlr_scene_node, requested.opacity);
let radius = if requested.circular {
@@ -1845,7 +1858,7 @@ impl Window {
ffi::river_scene_node_set_position_if_changed(self.popup_tree as *mut ffi::wlr_scene_node, self.box_geom.x, self.box_geom.y);
// Disable backdrop blur during active viewport zoom/pan for maximum performance
- ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, false, (*self.server).wm.layout.scenefx_optimized_blur, true);
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, false, (*self.server).wm.layout.scenefx_optimized_blur, true, 0, 0, 0, 0);
self.scale_only_render_finish();
self.draw_borders();
@@ -2779,7 +2792,7 @@ impl Decoration {
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);
+ 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, 0, 0, 0, 0);
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 15e605e..90e5734 100644
--- a/src/server/wlroots_log_wrapper.c
+++ b/src/server/wlroots_log_wrapper.c
@@ -670,7 +670,7 @@ static void get_size_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, v
if (buffer->dst_height > size[1]) size[1] = buffer->dst_height;
}
-void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent) {
+void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent, int x, int y, int width, int height) {
(void)ignore_transparent;
if (node->type != WLR_SCENE_NODE_TREE) {
return;
@@ -685,11 +685,14 @@ void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, boo
return;
}
- int width = 0, height = 0;
- int size[2] = {0, 0};
- wlr_scene_node_for_each_buffer(node, get_size_iterator, size);
- width = size[0];
- height = size[1];
+ if (width <= 0 || height <= 0) {
+ int size[2] = {0, 0};
+ wlr_scene_node_for_each_buffer(node, get_size_iterator, size);
+ width = size[0];
+ height = size[1];
+ x = 0;
+ y = 0;
+ }
if (width <= 0 || height <= 0) {
width = 1920; // Fallback defaults
@@ -725,6 +728,10 @@ void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, boo
wlr_scene_blur_set_size((struct wlr_scene_blur *)blur_node, width, height);
}
}
+
+ if (blur_node) {
+ wlr_scene_node_set_position(blur_node, x, y);
+ }
}
static void set_opacity_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index b8b7101..e6f8246 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -413,11 +413,19 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
if app_id.starts_with("cce-status") {
ignore_transparent = (*(*window).server).wm.layout.status_backdrop_blur_ignore_transparent;
}
+ let geom_x = (*window).rendering_requested.x;
+ let geom_y = (*window).rendering_requested.y;
+ let geom_w = (*window).rendering_sent.width as i32;
+ let geom_h = (*window).rendering_sent.height as i32;
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,
+ geom_x,
+ geom_y,
+ geom_w,
+ geom_h,
);
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 4e6d132..7288e93 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, bool ignore_transparent);
+void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled, bool optimized, bool ignore_transparent, int x, int y, int width, int height);
void river_scene_node_set_opacity(struct wlr_scene_node *node, float opacity);