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

commite1adb17ec9f33f20c6dc8947ae5bec47247e8b42
parent5a78fba696
authorLucas Galante <[email protected]>
date2026-07-21 20:56
feat: restart-compositor IPC command

Writes /tmp/cce-restart-requested-<user> and exits cleanly (window
state saved, as with 'exit'). cce-display-manager's daemon checks the
flag after the session worker ends and relaunches the same session
greeter-free — a full compositor restart that comes back into the
restored session. Requires cce-display-manager with the relaunch loop.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/cce_ctl.rs               |  1 +
 src/server/window_manager.rs | 15 +++++++++++++++
 2 files changed, 16 insertions(+)

diff --git a/src/cce_ctl.rs b/src/cce_ctl.rs
index e658ca5..fa4fc38 100644
--- a/src/cce_ctl.rs
+++ b/src/cce_ctl.rs
@@ -59,6 +59,7 @@ fn usage(name: &str, to_stderr: bool) {
     print("  adjust-position-mode [true|false|query]");
     print("  exit");
     print("  restart");
+    print("  restart-compositor        # exit cleanly; cce-display-manager relaunches the session");
     print("  reload");
     print("  repeat <rate> <delay>");
     print("  input <device_name|*> scroll-factor <value>");
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index c9ff49f..33bbec4 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -2928,6 +2928,21 @@ impl WindowManager {
                 self.execute_action(&crate::config::Action::Exit, None);
                 "ok\n".to_string()
             }
+            "restart-compositor" => {
+                // Leave the restart flag for cce-display-manager's daemon (it
+                // checks after the session worker exits, verifies the file is
+                // owned by the session user, and relaunches this same session
+                // greeter-free), then exit cleanly — which saves window state,
+                // so the restored compositor brings the session back.
+                let user = std::env::var("USER")
+                    .unwrap_or_else(|_| format!("uid{}", unsafe { libc::getuid() }));
+                let flag = format!("/tmp/cce-restart-requested-{}", user);
+                if let Err(e) = std::fs::write(&flag, b"restart\n") {
+                    return format!("error: cannot write {}: {}\n", flag, e);
+                }
+                self.execute_action(&crate::config::Action::Exit, None);
+                "ok restarting\n".to_string()
+            }
             "reload" => {
                 unsafe {
                     match self.reload_config() {