git.lucas.co / cce-compositor
Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git

commit4cee354138346b2cd7ce9617222ce5181da25af0
parent3d648f89c9
authorLucas Galante <[email protected]>
date2026-06-20 10:40
Workaround CSD window buffer-size bug for Electron/Chromium apps

 src/server/window.rs         |  2 ++
 src/server/window_manager.rs |  7 +++++--
 src/server/xdg_toplevel.rs   | 10 ++++++++++
 3 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/src/server/window.rs b/src/server/window.rs
index 983a4e2..1e1552a 100644
--- a/src/server/window.rs
+++ b/src/server/window.rs
@@ -238,6 +238,7 @@ pub struct Window {
     pub last_decor_h: i32,
     pub foreign_toplevel_handle: *mut ffi::wlr_ext_foreign_toplevel_handle_v1,
     pub wlr_toplevel_handle: *mut ffi::wlr_foreign_toplevel_handle_v1,
+    pub csd_buffer_size_bug: bool,
 }
 
 impl Window {
@@ -434,6 +435,7 @@ impl Window {
             last_decor_h: 0,
             foreign_toplevel_handle: std::ptr::null_mut(),
             wlr_toplevel_handle: std::ptr::null_mut(),
+            csd_buffer_size_bug: false,
         });
 
         ffi::wl_list_init(&mut window.decorations_below);
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 7fe5c57..5fb70e0 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -918,11 +918,14 @@ impl WindowManager {
                     let mut target_w = w;
                     let mut target_h = h;
                     if !(*win_ptr).wm_requested.ssd {
+                        let (dec_w, dec_h) = (*win_ptr).get_decorations_size();
                         let is_tiled = current_layout != crate::tiling::TilingMode::Floating &&
                                        current_layout != crate::tiling::TilingMode::Popup &&
                                        current_layout != crate::tiling::TilingMode::Status;
-                        if !is_tiled {
-                            let (dec_w, dec_h) = (*win_ptr).get_decorations_size();
+                        if (*win_ptr).csd_buffer_size_bug {
+                            target_w = w + dec_w;
+                            target_h = h + dec_h;
+                        } else if !is_tiled {
                             target_w = (w - dec_w).max(1);
                             target_h = (h - dec_h).max(1);
                         }
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index a3f5ce4..429eea2 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -491,6 +491,16 @@ unsafe extern "C" fn handle_commit(listener: *mut ffi::wl_listener, _data: *mut
                 (*(*window).server).wm.dirty_windowing();
             }
 
+            if let Some(sent_w) = (*window).configure_sent.width {
+                if !(*window).wm_requested.ssd && dec_w > 0 && new_geometry.width as u32 == sent_w.saturating_sub(dec_w as u32) {
+                    if !(*window).csd_buffer_size_bug {
+                        (*window).csd_buffer_size_bug = true;
+                        log::info!("Detected CSD buffer size bug for window '{}'. Activating workaround.", (*window).get_title_string().unwrap_or_default());
+                        (*(*window).server).wm.dirty_windowing();
+                    }
+                }
+            }
+
             match (*toplevel).configure_state {
                 ConfigureState::Acked => {
                     (*toplevel).configure_state = ConfigureState::Committed;