Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
feat: implement set_blur request for window and decoration interfaces
Makefile | 14 ++++++++++
build.rs | 1 +
protocol/river-window-management-v1.xml | 20 +++++++++++++++
src/window.rs | 45 ++++++++++++++++++++++++++++++++-
4 files changed, 79 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..88ebfc3
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+.PHONY: build install run clean
+
+build:
+ cargo build --release
+
+install: build
+ mkdir -p ~/.local/bin
+ install -m 755 target/release/clear-computing-environment-server ~/.local/bin/clear-computing-environment-server
+
+run:
+ cargo run
+
+clean:
+ cargo clean
diff --git a/build.rs b/build.rs
index 81003c0..5c94b3f 100644
--- a/build.rs
+++ b/build.rs
@@ -4,6 +4,7 @@ use std::path::PathBuf;
fn main() {
println!("cargo:rerun-if-changed=src/wlroots_log_wrapper.c");
println!("cargo:rerun-if-changed=wrapper.h");
+ println!("cargo:rerun-if-changed=protocol/river-window-management-v1.xml");
// Probe system libraries
let scenefx = pkg_config::Config::new()
diff --git a/protocol/river-window-management-v1.xml b/protocol/river-window-management-v1.xml
index 60040b2..cbc1015 100644
--- a/protocol/river-window-management-v1.xml
+++ b/protocol/river-window-management-v1.xml
@@ -1139,6 +1139,16 @@
</description>
<arg name="circular" type="uint" summary="1 if circular, 0 otherwise"/>
</request>
+
+ <request name="set_blur" since="4">
+ <description summary="set whether backdrop blur is enabled">
+ Set whether backdrop blur should be enabled for this window.
+ 1 to enable, 0 to disable.
+ This request modifies rendering state and may only be made as part of a
+ render sequence, see the river_window_manager_v1 description.
+ </description>
+ <arg name="blur" type="uint" summary="1 to enable, 0 to disable"/>
+ </request>
</interface>
<interface name="river_decoration_v1" version="4">
@@ -1195,6 +1205,16 @@
render sequence, see the river_window_manager_v1 description.
</description>
</request>
+
+ <request name="set_blur" since="4">
+ <description summary="set whether backdrop blur is enabled">
+ Set whether backdrop blur should be enabled for this decoration.
+ 1 to enable, 0 to disable.
+ This request modifies rendering state and may only be made as part of a
+ render sequence, see the river_window_manager_v1 description.
+ </description>
+ <arg name="blur" type="uint" summary="1 to enable, 0 to disable"/>
+ </request>
</interface>
<interface name="river_shell_surface_v1" version="4">
diff --git a/src/window.rs b/src/window.rs
index c40ea0b..35d28f0 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -183,6 +183,7 @@ pub struct WindowRenderingRequested {
pub content_clip: ffi::wlr_box,
pub opacity: f32,
pub circular: bool,
+ pub blur: bool,
}
pub struct Window {
@@ -343,6 +344,7 @@ impl Window {
content_clip: ffi::wlr_box { x: 0, y: 0, width: 0, height: 0 },
opacity: 1.0f32,
circular: false,
+ blur: false,
},
box_geom: ffi::wlr_box { x: 0, y: 0, width: 0, height: 0 },
foreign_toplevel_handle: std::ptr::null_mut(),
@@ -688,6 +690,7 @@ impl Window {
content_clip: ffi::wlr_box { x: 0, y: 0, width: 0, height: 0 },
opacity: 1.0f32,
circular: false,
+ blur: false,
};
wl_list_remove(&mut self.node.link as *mut ffi::wl_list as *mut WlList);
@@ -1138,7 +1141,7 @@ impl Window {
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);
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, requested.blur);
ffi::river_scene_node_set_opacity(self.tree as *mut ffi::wlr_scene_node, requested.opacity);
let radius = if requested.circular {
@@ -1841,6 +1844,22 @@ unsafe extern "C" fn window_set_circular(
(*window).rendering_requested.circular = circular != 0;
}
+unsafe extern "C" fn window_set_blur(
+ _client: *mut ffi::wl_client,
+ resource: *mut ffi::wl_resource,
+ blur: u32,
+) {
+ let window = ffi::wl_resource_get_user_data(resource) as *mut Window;
+ if window.is_null() {
+ return;
+ }
+ let server = (*window).server;
+ if !(*server).wm.ensure_rendering() {
+ return;
+ }
+ (*window).rendering_requested.blur = blur != 0;
+}
+
// river_window_v1 implementation
static WINDOW_INTERFACE: ffi::river_window_v1_interface = ffi::river_window_v1_interface {
destroy: Some(window_destroy),
@@ -1869,6 +1888,7 @@ static WINDOW_INTERFACE: ffi::river_window_v1_interface = ffi::river_window_v1_i
set_dimension_bounds: Some(window_set_dimension_bounds),
set_opacity: Some(window_set_opacity),
set_circular: Some(window_set_circular),
+ set_blur: Some(window_set_blur),
};
static INERT_WINDOW_INTERFACE: ffi::river_window_v1_interface = ffi::river_window_v1_interface {
@@ -1898,6 +1918,7 @@ static INERT_WINDOW_INTERFACE: ffi::river_window_v1_interface = ffi::river_windo
set_dimension_bounds: None,
set_opacity: None,
set_circular: None,
+ set_blur: None,
};
unsafe extern "C" fn handle_destroy_resource(resource: *mut ffi::wl_resource) {
@@ -1927,6 +1948,7 @@ pub struct DecorationRenderingRequested {
pub offset_x: i32,
pub offset_y: i32,
pub sync_next_commit: bool,
+ pub blur: bool,
}
pub struct Decoration {
@@ -1987,6 +2009,7 @@ impl Decoration {
offset_x: 0,
offset_y: 0,
sync_next_commit: false,
+ blur: false,
},
});
let raw = Box::into_raw(dec);
@@ -2041,6 +2064,8 @@ impl Decoration {
self.surfaces.drop_saved();
+ ffi::river_scene_node_enable_blur(self.surfaces.tree as *mut ffi::wlr_scene_node, self.rendering_requested.blur);
+
ffi::wlr_scene_node_set_position(self.tree as *mut ffi::wlr_scene_node, self.rendering_requested.offset_x, self.rendering_requested.offset_y);
let children_head = ffi::river_scene_tree_get_children(self.surfaces.tree) as *mut WlList;
@@ -2121,16 +2146,34 @@ unsafe extern "C" fn dec_sync_next_commit(
(*dec).rendering_requested.sync_next_commit = true;
}
+unsafe extern "C" fn dec_set_blur(
+ _client: *mut ffi::wl_client,
+ resource: *mut ffi::wl_resource,
+ blur: u32,
+) {
+ let dec = ffi::wl_resource_get_user_data(resource) as *mut Decoration;
+ if dec.is_null() {
+ return;
+ }
+ let server = (*(*dec).window).server;
+ if !(*server).wm.ensure_rendering() {
+ return;
+ }
+ (*dec).rendering_requested.blur = blur != 0;
+}
+
static DECORATION_INTERFACE: ffi::river_decoration_v1_interface = ffi::river_decoration_v1_interface {
destroy: Some(dec_destroy),
set_offset: Some(dec_set_offset),
sync_next_commit: Some(dec_sync_next_commit),
+ set_blur: Some(dec_set_blur),
};
static INERT_DECORATION_INTERFACE: ffi::river_decoration_v1_interface = ffi::river_decoration_v1_interface {
destroy: Some(dec_destroy),
set_offset: None,
sync_next_commit: None,
+ set_blur: None,
};
unsafe extern "C" fn handle_dec_destroy_resource(resource: *mut ffi::wl_resource) {