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

commitc61e4beec372b69f718fe719de370dfd4da13fb6
parent9cb160d8d4
authorLucas Galante <[email protected]>
date2026-06-22 14:20
fix: ensure side panel is stacked above other tiling mode windows when behavior is above

 src/server/process.rs        | 4 ++++
 src/server/tiling.rs         | 2 +-
 src/server/window_manager.rs | 5 +++++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/src/server/process.rs b/src/server/process.rs
index def8814..244fb62 100644
--- a/src/server/process.rs
+++ b/src/server/process.rs
@@ -9,8 +9,11 @@ static ORIGINAL_RLIMIT: Mutex<Option<libc::rlimit>> = Mutex::new(None);
 pub fn setup() {
     // Ignore SIGPIPE so we don't get killed when writing to a socket that
     // has had its read end closed by another process.
+    // Also ignore SIGCHLD to automatically reap terminated child processes
+    // and prevent them from becoming zombies.
     unsafe {
         libc::signal(libc::SIGPIPE, libc::SIG_IGN);
+        libc::signal(libc::SIGCHLD, libc::SIG_IGN);
     }
 
     // Most unix systems have a default limit of 1024 file descriptors.
@@ -44,6 +47,7 @@ pub fn cleanup_child() {
         libc::sigprocmask(libc::SIG_SETMASK, &empty_mask, std::ptr::null_mut());
 
         libc::signal(libc::SIGPIPE, libc::SIG_DFL);
+        libc::signal(libc::SIGCHLD, libc::SIG_DFL);
     }
 
     let orig = ORIGINAL_RLIMIT.lock().unwrap();
diff --git a/src/server/tiling.rs b/src/server/tiling.rs
index 74f4339..be49df9 100644
--- a/src/server/tiling.rs
+++ b/src/server/tiling.rs
@@ -1,6 +1,6 @@
 // Tiling formulas ported from cce-client
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum TilingMode {
     Floating,
     Cascade,
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 806fcfe..4dd7c9a 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -453,6 +453,7 @@ impl WindowManager {
         self.keep_status_bar_on_top();
 
         let mut hasher = std::collections::hash_map::DefaultHasher::new();
+        self.layout.side_panel_behavior.hash(&mut hasher);
         let render_list = &mut self.rendering_requested.list as *mut ffi::wl_list as *mut WlList;
         let mut curr = (*render_list).next;
         while curr != render_list {
@@ -464,6 +465,7 @@ impl WindowManager {
                     rendered_fullscreen(window).hash(&mut hasher);
                     (*window).rendering_requested.circular.hash(&mut hasher);
                     (*window).rendering_requested.hidden.hash(&mut hasher);
+                    (*window).tiling_mode.hash(&mut hasher);
                 }
                 crate::wm_node::WmNodeType::ShellSurface(shell_surface) => {
                     (shell_surface as usize).hash(&mut hasher);
@@ -496,6 +498,9 @@ impl WindowManager {
                             } else if (*window).rendering_requested.circular {
                                 ffi::wlr_scene_node_reparent((*window).tree as *mut _, (*self.server).scene.layers.top);
                                 ffi::wlr_scene_node_raise_to_top((*window).tree as *mut _);
+                            } else if (*window).tiling_mode == crate::tiling::TilingMode::SidePanel && self.layout.side_panel_behavior == "above" {
+                                ffi::wlr_scene_node_reparent((*window).tree as *mut _, (*self.server).scene.layers.top);
+                                ffi::wlr_scene_node_raise_to_top((*window).tree as *mut _);
                             } else {
                                 ffi::wlr_scene_node_reparent((*window).tree as *mut _, (*self.server).scene.layers.wm);
                                 ffi::wlr_scene_node_raise_to_top((*window).tree as *mut _);