Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
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;