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