Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
Dynamically disable window backdrop blur and grid fade layers during active zoom/pan
src/server/output.rs | 3 ++-
src/server/window.rs | 3 +++
src/server/window_manager.rs | 35 ++++++++++++++++++++++++++++++++---
3 files changed, 37 insertions(+), 4 deletions(-)
diff --git a/src/server/output.rs b/src/server/output.rs
index 61db63c..43f0233 100644
--- a/src/server/output.rs
+++ b/src/server/output.rs
@@ -636,7 +636,8 @@ impl Output {
continue;
}
- if cell_fade_inset <= 0 {
+ let draw_fade = cell_fade_inset > 0 && !draw_low_res;
+ if !draw_fade {
let cell_rect = ffi::wlr_scene_rect_create(
self.grid_tree,
rw,
diff --git a/src/server/window.rs b/src/server/window.rs
index 01ee937..733426b 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1844,6 +1844,9 @@ impl Window {
ffi::river_scene_node_set_position_if_changed(self.tree as *mut ffi::wlr_scene_node, self.box_geom.x, self.box_geom.y);
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);
+
self.scale_only_render_finish();
self.draw_borders();
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 0a08107..5bfd7b6 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -113,6 +113,10 @@ pub struct WindowManager {
pub animation_timer: *mut ffi::wl_event_source,
pub has_restored_focused_window: bool,
pub restored_focused_window_mapped: bool,
+ pub last_viewport_zoom: f64,
+ pub last_viewport_pan_x: f64,
+ pub last_viewport_pan_y: f64,
+ pub viewport_is_active: bool,
}
impl WindowManager {
@@ -1389,14 +1393,39 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
}
pub unsafe fn update_viewport_local(&mut self) {
+ let zoom_changed = self.desk_zoom != self.last_viewport_zoom;
+ let pan_changed = self.desk_pan_x != self.last_viewport_pan_x || self.desk_pan_y != self.last_viewport_pan_y;
+ let active = zoom_changed || pan_changed;
+
+ self.last_viewport_zoom = self.desk_zoom;
+ self.last_viewport_pan_x = self.desk_pan_x;
+ self.last_viewport_pan_y = self.desk_pan_y;
+
+ let was_active = self.viewport_is_active;
+ self.viewport_is_active = active;
+
self.arrange_views();
// Clear rendering dirty flag so we don't trigger the idle callback's IPC handshake
self.rendering_scheduled.dirty = false;
self.remove_dirty_idle();
- for &window in self.windows.iter() {
- if !window.is_null() {
- (*window).render_viewport_update();
+ if active {
+ for &window in self.windows.iter() {
+ if !window.is_null() {
+ (*window).render_viewport_update();
+ }
+ }
+ } else if was_active {
+ for &window in self.windows.iter() {
+ if !window.is_null() {
+ (*window).render_finish();
+ }
+ }
+ } else {
+ for &window in self.windows.iter() {
+ if !window.is_null() {
+ (*window).render_viewport_update();
+ }
}
}