Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix: resolve expose status updates feedback loop and HiDPI window scale restoration
src/server/status_server.rs | 2 +-
src/server/window.rs | 52 ++++++++++++++++++++------------------------
src/server/window_manager.rs | 9 +++++++-
3 files changed, 33 insertions(+), 30 deletions(-)
diff --git a/src/server/status_server.rs b/src/server/status_server.rs
index a7cf54c..d875656 100644
--- a/src/server/status_server.rs
+++ b/src/server/status_server.rs
@@ -12,7 +12,7 @@ use std::os::unix::net::{UnixListener, UnixStream};
use std::sync::mpsc;
/// A status update sent from the main loop to the server thread.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusUpdate {
/// JSON string for tags module subscribers
pub tags_json: String,
diff --git a/src/server/window.rs b/src/server/window.rs
index 691e82f..7cfbe1c 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -1333,22 +1333,20 @@ impl Window {
let data = &*(user_data as *const ScaleData);
let node = buffer as *mut ffi::wlr_scene_node;
- if data.scale == 1.0 {
+ let surface = ffi::river_scene_node_get_surface(node);
+ if !surface.is_null() {
+ let w = ffi::river_wlr_surface_get_width(surface);
+ let h = ffi::river_wlr_surface_get_height(surface);
+ let dest_w = (w as f64 * data.scale) as i32;
+ let dest_h = (h as f64 * data.scale) as i32;
+ ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
+
+ let dest_x = (sx as f64 * data.scale) as i32;
+ let dest_y = (sy as f64 * data.scale) as i32;
+ ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
+ } else if data.scale == 1.0 {
ffi::river_scene_buffer_set_dest_size_if_changed(buffer, 0, 0);
ffi::river_scene_node_set_position_if_changed(node, sx, sy);
- } else {
- let surface = ffi::river_scene_node_get_surface(node);
- if !surface.is_null() {
- let w = ffi::river_wlr_surface_get_width(surface);
- let h = ffi::river_wlr_surface_get_height(surface);
- let dest_w = (w as f64 * data.scale) as i32;
- let dest_h = (h as f64 * data.scale) as i32;
- ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
-
- let dest_x = (sx as f64 * data.scale) as i32;
- let dest_y = (sy as f64 * data.scale) as i32;
- ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
- }
}
}
@@ -2388,22 +2386,20 @@ impl Decoration {
let data = &*(user_data as *const ScaleData);
let node = buffer as *mut ffi::wlr_scene_node;
- if data.scale == 1.0 {
+ let surface = ffi::river_scene_node_get_surface(node);
+ if !surface.is_null() {
+ let w = ffi::river_wlr_surface_get_width(surface);
+ let h = ffi::river_wlr_surface_get_height(surface);
+ let dest_w = (w as f64 * data.scale) as i32;
+ let dest_h = (h as f64 * data.scale) as i32;
+ ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
+
+ let dest_x = (sx as f64 * data.scale) as i32;
+ let dest_y = (sy as f64 * data.scale) as i32;
+ ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
+ } else if data.scale == 1.0 {
ffi::river_scene_buffer_set_dest_size_if_changed(buffer, 0, 0);
ffi::river_scene_node_set_position_if_changed(node, sx, sy);
- } else {
- let surface = ffi::river_scene_node_get_surface(node);
- if !surface.is_null() {
- let w = ffi::river_wlr_surface_get_width(surface);
- let h = ffi::river_wlr_surface_get_height(surface);
- let dest_w = (w as f64 * data.scale) as i32;
- let dest_h = (h as f64 * data.scale) as i32;
- ffi::river_scene_buffer_set_dest_size_if_changed(buffer, dest_w, dest_h);
-
- let dest_x = (sx as f64 * data.scale) as i32;
- let dest_y = (sy as f64 * data.scale) as i32;
- ffi::river_scene_node_set_position_if_changed(node, dest_x, dest_y);
- }
}
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 2dfda72..27ef147 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -71,6 +71,7 @@ pub struct WindowManager {
pub input_rules: Vec<crate::config::InputDeviceConfigRule>,
pub input_config: crate::config::InputConfig,
pub expose_active: bool,
+ pub last_status_update: std::cell::RefCell<Option<crate::status_server::StatusUpdate>>,
}
impl WindowManager {
@@ -128,6 +129,7 @@ impl WindowManager {
self.input_rules = Vec::new();
self.input_config = crate::config::InputConfig::default();
self.expose_active = false;
+ self.last_status_update = std::cell::RefCell::new(None);
ffi::wl_list_init(&mut self.sent.outputs);
ffi::wl_list_init(&mut self.sent.seats);
@@ -1100,7 +1102,12 @@ impl WindowManager {
pub unsafe fn update_status(&self) {
if let Some(ref sender) = self.status_sender {
- sender.send(crate::status_server::build_status_update(self));
+ let update = crate::status_server::build_status_update(self);
+ let mut last = self.last_status_update.borrow_mut();
+ if last.as_ref() != Some(&update) {
+ sender.send(update.clone());
+ *last = Some(update);
+ }
}
}