Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Add backdrop blur for transparent windows via SceneFX
build.rs | 19 ++++++++++++++++++-
src/layer_shell.rs | 5 +++++
src/scene.rs | 9 ++++++---
src/window.rs | 7 ++++++-
src/wlroots_log_wrapper.c | 13 ++++++++++++-
src/xdg_toplevel.rs | 2 ++
wrapper.h | 4 +++-
7 files changed, 52 insertions(+), 7 deletions(-)
diff --git a/build.rs b/build.rs
index ec38264..077c025 100644
--- a/build.rs
+++ b/build.rs
@@ -11,6 +11,11 @@ fn main() {
.probe("wlroots-0.20")
.expect("wlroots-0.20 is required");
+ let scenefx = pkg_config::Config::new()
+ .atleast_version("0.4.0")
+ .probe("scenefx-0.4")
+ .expect("scenefx-0.4 is required");
+
let wl_server = pkg_config::probe_library("wayland-server")
.expect("wayland-server is required");
@@ -115,7 +120,13 @@ fn main() {
build.file(c_file);
}
- // Add include paths for wlroots and wayland-server
+ // Add include paths for scenefx, wlroots, and wayland-server
+ for path in &scenefx.include_paths {
+ if path.to_string_lossy().contains("wlroots-0.19") {
+ continue;
+ }
+ build.include(path);
+ }
for path in &wlroots.include_paths {
build.include(path);
}
@@ -134,6 +145,12 @@ fn main() {
// Pass include paths to bindgen clang argument parser
let mut include_paths = vec![out_dir.clone()];
+ for path in scenefx.include_paths.clone() {
+ if path.to_string_lossy().contains("wlroots-0.19") {
+ continue;
+ }
+ include_paths.push(path);
+ }
include_paths.extend(wlroots.include_paths.clone());
include_paths.extend(wl_server.include_paths.clone());
include_paths.extend(xkb.include_paths.clone());
diff --git a/src/layer_shell.rs b/src/layer_shell.rs
index aa8e837..5264cf6 100644
--- a/src/layer_shell.rs
+++ b/src/layer_shell.rs
@@ -462,6 +462,11 @@ unsafe extern "C" fn handle_layer_surface_commit(listener: *mut ffi::wl_listener
let layer_surface = crate::container_of!(listener, LayerSurface, commit);
let wlr_layer_surface = (*layer_surface).wlr_layer_surface;
+ ffi::river_scene_node_enable_blur(
+ (*(*layer_surface).scene_layer_surface).tree as *mut ffi::wlr_scene_node,
+ true,
+ );
+
assert!(!(*wlr_layer_surface).output.is_null());
let server = (*layer_surface).server;
diff --git a/src/scene.rs b/src/scene.rs
index c7239cb..3f98d19 100644
--- a/src/scene.rs
+++ b/src/scene.rs
@@ -61,9 +61,12 @@ impl Scene {
if !linux_dmabuf.is_null() {
ffi::wlr_scene_set_linux_dmabuf_v1(wlr_scene, linux_dmabuf);
}
- if !color_manager.is_null() {
- ffi::wlr_scene_set_color_manager_v1(wlr_scene, color_manager);
- }
+ // SceneFX 0.4 does not support set_color_manager_v1
+ // if !color_manager.is_null() {
+ // ffi::wlr_scene_set_color_manager_v1(wlr_scene, color_manager);
+ // }
+
+ ffi::wlr_scene_set_blur_data(wlr_scene, 3, 5, 0.0, 1.0, 1.0, 1.0);
let interactive_tree = ffi::wlr_scene_tree_create(&mut (*wlr_scene).tree);
let drag_icons = ffi::wlr_scene_tree_create(&mut (*wlr_scene).tree);
diff --git a/src/window.rs b/src/window.rs
index 41566e2..b73340f 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -236,7 +236,8 @@ impl Window {
ffi::wlr_scene_node_destroy(popup_tree as *mut ffi::wlr_scene_node);
return Err("Failed to create capture_scene");
}
- (*capture_scene).restack_xwayland_surfaces = false;
+ // SceneFX 0.4 does not support restack_xwayland_surfaces
+ // (*capture_scene).restack_xwayland_surfaces = false;
let black_color = [0.0f32, 0.0f32, 0.0f32, 1.0f32];
let fullscreen_background = ffi::wlr_scene_rect_create(tree, 0, 0, black_color.as_ptr());
@@ -1121,6 +1122,10 @@ impl Window {
ffi::wlr_scene_node_set_enabled(self.tree as *mut ffi::wlr_scene_node, enabled);
ffi::wlr_scene_node_set_enabled(self.popup_tree as *mut ffi::wlr_scene_node, enabled);
+ if enabled {
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, true);
+ }
+
self.box_geom.width = self.rendering_sent.width as i32;
self.box_geom.height = self.rendering_sent.height as i32;
diff --git a/src/wlroots_log_wrapper.c b/src/wlroots_log_wrapper.c
index 0e83f5a..0e9c1fd 100644
--- a/src/wlroots_log_wrapper.c
+++ b/src/wlroots_log_wrapper.c
@@ -46,7 +46,7 @@ void river_init_wlroots_log(enum wlr_log_importance importance) {
}
#include <time.h>
-#include <wlr/types/wlr_scene.h>
+#include <scenefx/types/wlr_scene.h>
#include <wlr/types/wlr_output.h>
#include <wlr/types/wlr_compositor.h>
#include <wlr/types/wlr_input_device.h>
@@ -646,5 +646,16 @@ void river_wlr_keyboard_init(struct wlr_keyboard *keyboard,
wlr_keyboard_init(keyboard, &impl, name);
}
+static void enable_blur_iterator(struct wlr_scene_buffer *buffer, int sx, int sy, void *user_data) {
+ bool enabled = *(bool *)user_data;
+ wlr_scene_buffer_set_backdrop_blur(buffer, enabled);
+ wlr_scene_buffer_set_backdrop_blur_optimized(buffer, enabled);
+ wlr_scene_buffer_set_backdrop_blur_ignore_transparent(buffer, enabled);
+}
+
+void river_scene_node_enable_blur(struct wlr_scene_node *node, bool enabled) {
+ wlr_scene_node_for_each_buffer(node, enable_blur_iterator, &enabled);
+}
+
diff --git a/src/xdg_toplevel.rs b/src/xdg_toplevel.rs
index 6cf1231..de98fa6 100644
--- a/src/xdg_toplevel.rs
+++ b/src/xdg_toplevel.rs
@@ -403,6 +403,8 @@ 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);
+ ffi::river_scene_node_enable_blur((*window).surfaces.tree as *mut ffi::wlr_scene_node, true);
+
let capture_node = &mut (*(*window).capture_scene).tree as *mut ffi::wlr_scene_tree as *mut ffi::wlr_scene_node;
let mut geom = std::mem::zeroed();
ffi::river_wlr_xdg_surface_get_geometry(base, &mut geom);
diff --git a/wrapper.h b/wrapper.h
index 412b77b..41cf574 100644
--- a/wrapper.h
+++ b/wrapper.h
@@ -72,7 +72,7 @@
#include <wlr/types/wlr_color_representation_v1.h>
#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
-#include <wlr/types/wlr_scene.h>
+#include <scenefx/types/wlr_scene.h>
#include <wlr/util/addon.h>
#include <wlr/xwayland.h>
@@ -255,4 +255,6 @@ 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);
+
#endif // WRAPPER_H