Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix: resolve compositor window border issue and add decoration mode checks
src/server/window_manager.rs | 36 ++++++++++++++++++++++++++++++------
src/server/xdg_toplevel.rs | 14 ++++++++++++++
2 files changed, 44 insertions(+), 6 deletions(-)
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index b065c50..333747a 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -366,12 +366,35 @@ impl WindowManager {
pub unsafe fn spawn_restored_windows(&mut self) {
log::info!("Spawning restored windows. Total: {}", self.restore_queue.len());
let restored = self.restore_queue.clone();
- for w in restored {
- if !w.cmdline.is_empty() {
- log::info!("Spawning restored window command: {}", w.cmdline);
- self.execute_action(&crate::config::Action::Spawn, Some(&w.cmdline));
+ std::thread::spawn(move || {
+ for (i, w) in restored.into_iter().enumerate() {
+ if !w.cmdline.is_empty() {
+ let delay = 1000 + i as u64 * 500;
+ std::thread::sleep(std::time::Duration::from_millis(delay));
+ log::info!("Deferred spawning restored window command: {}", w.cmdline);
+ let cmd = w.cmdline;
+ match nix::unistd::fork() {
+ Ok(nix::unistd::ForkResult::Child) => {
+ crate::process::cleanup_child();
+ let env: Vec<std::ffi::CString> = std::env::vars()
+ .map(|(k, v)| std::ffi::CString::new(format!("{}={}", k, v)).unwrap())
+ .collect();
+ let env_ptrs: Vec<&std::ffi::CStr> = env.iter().map(|s| s.as_c_str()).collect();
+ let sh_c = std::ffi::CString::new("/bin/sh").unwrap();
+ let c_c = std::ffi::CString::new("-c").unwrap();
+ let cmd_c = std::ffi::CString::new(cmd).unwrap();
+ let args = [sh_c.as_c_str(), c_c.as_c_str(), cmd_c.as_c_str()];
+ let _ = nix::unistd::execve(&sh_c, &args, &env_ptrs);
+ std::process::exit(1);
+ }
+ Ok(_) => {}
+ Err(e) => {
+ log::error!("failed to fork child process: {}", e);
+ }
+ }
+ }
}
- }
+ });
}
pub fn start_ipc(&mut self, display_socket: Option<String>) {
@@ -2097,7 +2120,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
let app_id = (*w).get_app_id_string().unwrap_or_default();
let title = (*w).get_title_string().unwrap_or_default();
out.push_str(&format!(
- "window id={} app_id={} title=\"{}\" mode={} x={} y={} w={} h={} vx={:.1} vy={:.1} minimized={} has_parent={} focused={}\n",
+ "window id={} app_id={} title=\"{}\" mode={} x={} y={} w={} h={} vx={:.1} vy={:.1} minimized={} has_parent={} focused={} ssd={}\n",
(*w).ref_key.index,
app_id,
title,
@@ -2111,6 +2134,7 @@ fn get_closest_tag(x: f64, y: f64) -> i32 {
(*w).minimized,
(*w).has_parent,
w == focused_window,
+ (*w).wm_requested.ssd,
));
}
}
diff --git a/src/server/xdg_toplevel.rs b/src/server/xdg_toplevel.rs
index 7168ec9..4c671da 100644
--- a/src/server/xdg_toplevel.rs
+++ b/src/server/xdg_toplevel.rs
@@ -792,6 +792,20 @@ unsafe extern "C" fn handle_decoration_request_mode(listener: *mut ffi::wl_liste
_ => ffi::zcce_window_v1_decoration_hint_ZCCE_WINDOW_V1_DECORATION_HINT_NO_PREFERENCE,
};
(*window).set_decoration_hint(hint);
+
+ if ffi::river_wlr_xdg_surface_get_initialized(base) {
+ let scheduled_ssd = (*window).configure_scheduled.ssd;
+ let mode = if scheduled_ssd {
+ if (*(*decoration).wlr_decoration).requested_mode == ffi::wlr_xdg_toplevel_decoration_v1_mode_WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE {
+ ffi::wlr_xdg_toplevel_decoration_v1_mode_WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE
+ } else {
+ ffi::wlr_xdg_toplevel_decoration_v1_mode_WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
+ }
+ } else {
+ ffi::wlr_xdg_toplevel_decoration_v1_mode_WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE
+ };
+ ffi::wlr_xdg_toplevel_decoration_v1_set_mode((*decoration).wlr_decoration, mode);
+ }
}
impl XdgDecoration {