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

commit5c731261c907deb57f93705dd7bef15e37f36c7a
parente2e9fb63c0
authorLucas Galante <[email protected]>
date2026-06-09 10:08
Refactor and adapt widgets to use UiContext and scale factor

 Cargo.lock           |   2 +-
 Cargo.toml           |   4 +-
 Makefile             |   4 +-
 src/borders.rs       |   6 +--
 src/clearctl.rs      |  12 +++---
 src/config.rs        |  40 +++++++++---------
 src/decorations.rs   |  14 +++----
 src/inspector_cli.rs |   8 ++--
 src/ipc.rs           | 114 +++++++++++++++++++++++++++++----------------------
 src/ipc_server.rs    |   2 +-
 src/lib.rs           |   2 +-
 src/main.rs          |  44 ++++++++++----------
 src/paths.rs         |  68 +++++++++++++++---------------
 src/restart.rs       |  30 +++++++-------
 src/state.rs         |  14 +++----
 src/status.rs        |   8 ++--
 src/status_server.rs |  10 ++---
 src/tiling.rs        |   2 +-
 src/types.rs         |   4 +-
 src/wayland.rs       |  65 ++++++++++++++++-------------
 src/wm.rs            |  67 ++++++++++++++++++++----------
 start-river.sh       |  30 +++++++-------
 22 files changed, 302 insertions(+), 248 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 83920d2..9f7ae0e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -31,7 +31,7 @@ dependencies = [
 ]
 
 [[package]]
-name = "ccec"
+name = "cce-client"
 version = "0.1.0"
 dependencies = [
  "bitflags",
diff --git a/Cargo.toml b/Cargo.toml
index 5b2aa02..2a1be1b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,10 +1,10 @@
 [package]
-name = "ccec"
+name = "cce-client"
 version = "0.1.0"
 edition = "2021"
 
 [[bin]]
-name = "ccec"
+name = "cce-client"
 path = "src/main.rs"
 
 [[bin]]
diff --git a/Makefile b/Makefile
index 48eb940..0e6c952 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,9 @@ build:
 
 install: build
 	mkdir -p ~/.local/bin
-	install -m 755 target/release/ccec ~/.local/bin/ccec
+	install -m 755 target/release/cce-client ~/.local/bin/cce-client
+	install -m 755 target/release/clearctl ~/.local/bin/clearctl
+	install -m 755 target/release/clear-inspector ~/.local/bin/clear-inspector
 
 run:
 	cargo run
diff --git a/src/borders.rs b/src/borders.rs
index ec5cf72..f08bd75 100644
--- a/src/borders.rs
+++ b/src/borders.rs
@@ -124,12 +124,12 @@ pub fn compute_border_colors(state: &WindowManager) -> Vec<WindowBorders> {
                 TilingMode::Fullscreen => state.layout.fullscreen_border_width,
                 TilingMode::Grid => state.layout.grid_border_width,
                 TilingMode::Floating => state.layout.floating_border_width,
-                TilingMode::Popup => state.layout.border_width,
+                TilingMode::Popup => 0,
                 TilingMode::SidePanel => state.layout.cascade_border_width,
             }
         };
 
-        if win.app_id.as_deref() == Some("clear-status-interface")
+        if win.app_id.as_deref() == Some("cce-status-interface")
             || win.app_id.as_deref().map_or(false, |aid| aid.contains("noborder"))
         {
             width = 0;
@@ -137,7 +137,7 @@ pub fn compute_border_colors(state: &WindowManager) -> Vec<WindowBorders> {
 
         let has_titlebar = !win.closed
             && !win.minimized
-            && win.app_id.as_deref() != Some("clear-status-interface")
+            && win.app_id.as_deref() != Some("cce-status-interface")
             && !win.app_id.as_deref().map_or(false, |aid| aid.contains("noborder"))
             && win.tiling_mode != TilingMode::Popup
             && win.tiling_mode != TilingMode::Fullscreen
diff --git a/src/clearctl.rs b/src/clearctl.rs
index 6adcabb..25bb34e 100644
--- a/src/clearctl.rs
+++ b/src/clearctl.rs
@@ -1,4 +1,4 @@
-// clearctl — IPC client for ccec
+// clearctl — IPC client for cce-client
 
 use std::env;
 use std::fs;
@@ -8,15 +8,15 @@ use std::process;
 
 fn get_socket_path() -> String {
     match env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/ccec-{}.sock", display),
-        Err(_) => "/tmp/ccec.sock".to_string(),
+        Ok(display) => format!("/tmp/cce-client-{}.sock", display),
+        Err(_) => "/tmp/cce-client.sock".to_string(),
     }
 }
 
 fn get_windows_path() -> String {
     match env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/ccec-windows-{}", display),
-        Err(_) => "/tmp/ccec-windows".to_string(),
+        Ok(display) => format!("/tmp/cce-client-windows-{}", display),
+        Err(_) => "/tmp/cce-client-windows".to_string(),
     }
 }
 
@@ -80,7 +80,7 @@ fn main() {
     if args[1] == "windows" {
         match fs::read_to_string(get_windows_path()) {
             Ok(content) => print!("{}", content),
-            Err(_) => eprintln!("No windows info (ccec may not be running)"),
+            Err(_) => eprintln!("No windows info (cce-client may not be running)"),
         }
         return;
     }
diff --git a/src/config.rs b/src/config.rs
index dcd933b..abb41be 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -1,4 +1,4 @@
-// TOML config parsing for ccec
+// TOML config parsing for cce-client
 
 use serde::Deserialize;
 use std::collections::HashMap;
@@ -615,9 +615,9 @@ pub fn parse_keysym(key_str: &str) -> u32 {
 ///
 /// Closes all inherited FDs > 2 in the child via pre_exec so that
 /// spawned Wayland clients (fuzzel, foot, etc.) never accidentally
-/// read from ccec's Wayland socket fd. Also redirects stdout/stderr
-/// to /dev/null so child output doesn't pollute ccec's log, and
-/// calls setsid() to detach from ccec's process group.
+/// read from cce-client's Wayland socket fd. Also redirects stdout/stderr
+/// to /dev/null so child output doesn't pollute cce-client's log, and
+/// calls setsid() to detach from cce-client's process group.
 pub fn spawn_command_bg(cmd: &str) {
     use std::os::unix::process::CommandExt;
     let cmd = cmd.to_string();
@@ -625,7 +625,7 @@ pub fn spawn_command_bg(cmd: &str) {
     let stdout_cfg = if let Ok(f) = std::fs::OpenOptions::new()
         .create(true)
         .append(true)
-        .open("/tmp/ccec-spawned-apps.log")
+        .open("/tmp/cce-client-spawned-apps.log")
     {
         std::process::Stdio::from(f)
     } else {
@@ -635,7 +635,7 @@ pub fn spawn_command_bg(cmd: &str) {
     let stderr_cfg = if let Ok(f) = std::fs::OpenOptions::new()
         .create(true)
         .append(true)
-        .open("/tmp/ccec-spawned-apps.log")
+        .open("/tmp/cce-client-spawned-apps.log")
     {
         std::process::Stdio::from(f)
     } else {
@@ -651,7 +651,7 @@ pub fn spawn_command_bg(cmd: &str) {
             .stderr(stderr_cfg)
             .pre_exec(|| {
                 // Close all inherited FDs > 2 to prevent the child from
-                // accidentally reading ccec's Wayland socket or status
+                // accidentally reading cce-client's Wayland socket or status
                 // socket FDs. close() and setsid() are async-signal-safe.
                 let max_fd = libc::sysconf(libc::_SC_OPEN_MAX) as libc::c_int;
                 for fd in 3..max_fd {
@@ -680,7 +680,7 @@ pub fn process_running(name: &str) -> bool {
 pub fn show_notification(title: &str, body: &str) {
     let title_escaped = title.replace('\'', "'\\''");
     let body_escaped = body.replace('\'', "'\\''");
-    let cmd = format!("notify-send -a ccec '{}' '{}'", title_escaped, body_escaped);
+    let cmd = format!("notify-send -a cce-client '{}' '{}'", title_escaped, body_escaped);
     spawn_command_bg(&cmd);
 }
 
@@ -720,31 +720,31 @@ mod tests {
 
     #[test]
     fn test_expand_env_vars_simple() {
-        std::env::set_var("CCEC_TEST_VAR_SIMPLE", "hello");
-        assert_eq!(expand_env_vars("$CCEC_TEST_VAR_SIMPLE"), "hello");
-        std::env::remove_var("CCEC_TEST_VAR_SIMPLE");
+        std::env::set_var("CCE_CLIENT_TEST_VAR_SIMPLE", "hello");
+        assert_eq!(expand_env_vars("$CCE_CLIENT_TEST_VAR_SIMPLE"), "hello");
+        std::env::remove_var("CCE_CLIENT_TEST_VAR_SIMPLE");
     }
 
     #[test]
     fn test_expand_env_vars_braces() {
-        std::env::set_var("CCEC_TEST_VAR_BRACES", "world");
-        assert_eq!(expand_env_vars("${CCEC_TEST_VAR_BRACES}!"), "world!");
-        std::env::remove_var("CCEC_TEST_VAR_BRACES");
+        std::env::set_var("CCE_CLIENT_TEST_VAR_BRACES", "world");
+        assert_eq!(expand_env_vars("${CCE_CLIENT_TEST_VAR_BRACES}!"), "world!");
+        std::env::remove_var("CCE_CLIENT_TEST_VAR_BRACES");
     }
 
     #[test]
     fn test_expand_env_vars_mid_string() {
-        std::env::set_var("CCEC_TEST_HOME", "/home/user");
+        std::env::set_var("CCE_CLIENT_TEST_HOME", "/home/user");
         assert_eq!(
-            expand_env_vars("$CCEC_TEST_HOME/.local/bin:$CCEC_TEST_HOME/bin"),
+            expand_env_vars("$CCE_CLIENT_TEST_HOME/.local/bin:$CCE_CLIENT_TEST_HOME/bin"),
             "/home/user/.local/bin:/home/user/bin"
         );
-        std::env::remove_var("CCEC_TEST_HOME");
+        std::env::remove_var("CCE_CLIENT_TEST_HOME");
     }
 
     #[test]
     fn test_expand_env_vars_unset() {
-        assert_eq!(expand_env_vars("$CCEC_NONEXISTENT_VAR"), "");
+        assert_eq!(expand_env_vars("$CCE_CLIENT_NONEXISTENT_VAR"), "");
     }
 
     #[test]
@@ -808,7 +808,7 @@ exec = "fuzzel"
 once = true
 
 [[startup]]
-exec = "clear-system-interface"
+exec = "cce-system-interface"
 once = true
 restart = true
 "#;
@@ -818,7 +818,7 @@ restart = true
         assert!(!config.startup[0].once);
         assert_eq!(config.startup[1].exec, "fuzzel");
         assert!(config.startup[1].once);
-        assert_eq!(config.startup[2].exec, "clear-system-interface");
+        assert_eq!(config.startup[2].exec, "cce-system-interface");
         assert!(config.startup[2].once);
         assert_eq!(config.startup[2].restart, Some(true));
         assert_eq!(config.env.get("XDG_CURRENT_DESKTOP").unwrap(), "river");
diff --git a/src/decorations.rs b/src/decorations.rs
index bcb08d8..6dd4e7e 100644
--- a/src/decorations.rs
+++ b/src/decorations.rs
@@ -1,4 +1,4 @@
-// Wayland decoration surface drawing and management for ccec
+// Wayland decoration surface drawing and management for cce-client
 
 use std::ffi::CString;
 use std::os::fd::RawFd;
@@ -188,7 +188,7 @@ fn draw_char(
 
 /// Create a temporary shared memory file descriptor.
 fn create_memfd(size: usize) -> Option<RawFd> {
-    let name = CString::new("ccec-decoration").ok()?;
+    let name = CString::new("cce-client-decoration").ok()?;
     let fd = unsafe { libc::memfd_create(name.as_ptr(), libc::MFD_CLOEXEC) };
     if fd < 0 {
         return None;
@@ -561,7 +561,7 @@ pub fn update_decorations(state: &mut AppState, qhandle: &QueueHandle<AppState>)
         if let Some(w) = state.wm.windows.iter().find(|win| win.id == *wid) {
             let is_minimized = w.minimized;
             let should_not_decorate = w.closed
-                || w.app_id.as_deref() == Some("clear-status-interface")
+                || w.app_id.as_deref() == Some("cce-status-interface")
                 || w.app_id.as_deref().map_or(false, |aid| aid.contains("noborder"))
                 || w.tiling_mode == crate::types::TilingMode::Popup
                 || w.tiling_mode == crate::types::TilingMode::Fullscreen
@@ -616,14 +616,14 @@ pub fn update_decorations(state: &mut AppState, qhandle: &QueueHandle<AppState>)
         .windows
         .iter()
         .enumerate()
-        .filter(|(_, w)| !w.closed && w.app_id.as_deref() != Some("clear-status-interface") && !w.circular && !w.app_id.as_deref().map_or(false, |aid| aid.contains("noborder")) && (w.minimized || (w.tiling_mode != crate::types::TilingMode::Popup && w.tiling_mode != crate::types::TilingMode::Fullscreen)))
+        .filter(|(_, w)| !w.closed && w.app_id.as_deref() != Some("cce-status-interface") && !w.circular && !w.app_id.as_deref().map_or(false, |aid| aid.contains("noborder")) && (w.minimized || (w.tiling_mode != crate::types::TilingMode::Popup && w.tiling_mode != crate::types::TilingMode::Fullscreen)))
         .filter(|(_, w)| (w.tags & active_tags) != 0)
         .map(|(idx, w)| {
             let is_minimized = w.minimized;
             let minimized_idx = if is_minimized {
                 state.wm.windows
                     .iter()
-                    .filter(|win| !win.closed && win.minimized && (win.tags & active_tags) != 0 && win.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|win| !win.closed && win.minimized && (win.tags & active_tags) != 0 && win.app_id.as_deref() != Some("cce-status-interface"))
                     .position(|win| win.id == w.id)
             } else {
                 None
@@ -634,7 +634,7 @@ pub fn update_decorations(state: &mut AppState, qhandle: &QueueHandle<AppState>)
             let mode_idx = if state.wm.expose_visual_active && w.tiling_mode != crate::types::TilingMode::Popup {
                 let list: Vec<_> = state.wm.windows
                     .iter()
-                    .filter(|win| !win.closed && win.app_id.as_deref() != Some("clear-status-interface") && win.tiling_mode != crate::types::TilingMode::Popup && (win.tags & active_tags) != 0)
+                    .filter(|win| !win.closed && win.app_id.as_deref() != Some("cce-status-interface") && win.tiling_mode != crate::types::TilingMode::Popup && (win.tags & active_tags) != 0)
                     .collect();
                 let len = list.len();
                 let pos = list.iter().position(|win| win.id == w.id).unwrap_or(0);
@@ -642,7 +642,7 @@ pub fn update_decorations(state: &mut AppState, qhandle: &QueueHandle<AppState>)
             } else {
                 let list: Vec<_> = state.wm.windows
                     .iter()
-                    .filter(|win| !win.closed && win.app_id.as_deref() != Some("clear-status-interface") && (win.tags & active_tags) != 0 && win.tiling_mode == w.tiling_mode)
+                    .filter(|win| !win.closed && win.app_id.as_deref() != Some("cce-status-interface") && (win.tags & active_tags) != 0 && win.tiling_mode == w.tiling_mode)
                     .collect();
                 let len = list.len();
                 let pos = list.iter().position(|win| win.id == w.id).unwrap_or(0);
diff --git a/src/inspector_cli.rs b/src/inspector_cli.rs
index da24454..3711f57 100644
--- a/src/inspector_cli.rs
+++ b/src/inspector_cli.rs
@@ -5,7 +5,7 @@ use wayland_client::{
 };
 use serde_json::Value;
 
-// Import generated client protocols from ccec crate
+// Import generated client protocols from cce-client crate
 mod protocol;
 use protocol::clear_inspector::client::zclear_inspector_v1::{self, ZclearInspectorV1};
 
@@ -79,8 +79,8 @@ impl Dispatch<ZclearInspectorV1, ()> for InspectorState {
 
 fn get_socket_path() -> String {
     match std::env::var("WAYLAND_DISPLAY") {
-        Ok(display) => format!("/tmp/ccec-{}.sock", display),
-        Err(_) => "/tmp/ccec.sock".to_string(),
+        Ok(display) => format!("/tmp/cce-client-{}.sock", display),
+        Err(_) => "/tmp/cce-client.sock".to_string(),
     }
 }
 
@@ -316,7 +316,7 @@ fn main() {
                             }
                         }
                         Err(e) => {
-                            eprintln!("Error sending IPC commands to ccec socket: {:?}", e);
+                            eprintln!("Error sending IPC commands to cce-client socket: {:?}", e);
                             std::process::exit(1);
                         }
                     }
diff --git a/src/ipc.rs b/src/ipc.rs
index 274d695..2c35ac5 100644
--- a/src/ipc.rs
+++ b/src/ipc.rs
@@ -1,5 +1,5 @@
-// IPC command parser for ccec
-// Ported from handle_ipc_command in ccec.c
+// IPC command parser for cce-client
+// Ported from handle_ipc_command in cce-client.c
 
 use crate::config::{parse_keysym, spawn_command_bg};
 use crate::types::{
@@ -27,7 +27,7 @@ fn get_window_under_pointer(state: &WindowManager) -> Option<u64> {
     for win in &state.windows {
         if win.closed
             || (win.tags & active_tags) == 0
-            || win.app_id.as_deref() == Some("clear-status-interface")
+            || win.app_id.as_deref() == Some("cce-status-interface")
             || win.tiling_mode == TilingMode::Popup
         {
             continue;
@@ -89,7 +89,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                     let visible_ids: Vec<u64> = state
                         .windows
                         .iter()
-                        .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("clear-status-interface"))
+                        .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("cce-status-interface"))
                         .map(|w| w.id)
                         .collect();
                     let next_id = visible_ids.last().copied();
@@ -113,7 +113,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 let visible_ids: Vec<u64> = state
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 if visible_ids.len() > 1 {
@@ -141,7 +141,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 let visible_ids: Vec<u64> = state
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 if visible_ids.len() > 1 {
@@ -202,6 +202,8 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 }
                 state.needs_render = true;
                 state.needs_status_update = true;
+            } else {
+                spawn_command_bg("clear-cloud --apps");
             }
         }
         "view-next" => {
@@ -213,7 +215,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 let visible_ids: Vec<u64> = state
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 seat.focused_window_id = visible_ids.last().copied();
@@ -231,7 +233,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 let visible_ids: Vec<u64> = state
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 seat.focused_window_id = visible_ids.last().copied();
@@ -251,7 +253,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                         let visible_ids: Vec<u64> = state
                             .windows
                             .iter()
-                            .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                            .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                             .map(|w| w.id)
                             .collect();
                         seat.focused_window_id = visible_ids.last().copied();
@@ -283,7 +285,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                         let visible_ids: Vec<u64> = state
                             .windows
                             .iter()
-                            .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                            .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                             .map(|w| w.id)
                             .collect();
                         if let Some(seat) = state.seats.iter_mut().find(|s| !s.removed) {
@@ -338,7 +340,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                     let mut updated_count = 0;
                     for win in &mut state.windows {
                         if !win.closed
-                            && win.app_id.as_deref() != Some("clear-status-interface")
+                            && win.app_id.as_deref() != Some("cce-status-interface")
                             && (win.tags & active_tags) != 0
                             && win.tiling_mode == old_mode
                         {
@@ -350,7 +352,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
 
                     if notifications_enable && updated_count > 0 {
                         crate::config::show_notification(
-                            "ccec",
+                            "cce-client",
                             &format!(
                                 "Tiling mode set to {} for all {} windows on active tag",
                                 next.as_str(),
@@ -393,7 +395,7 @@ pub fn handle_ipc_command(cmd: &str, state: &mut WindowManager) -> String {
                 }
             } else if parts.len() == 1 && !parts[0].is_empty() {
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", parts[0]);
+                    crate::config::show_notification("cce-client", parts[0]);
                 }
             }
         }
@@ -568,7 +570,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.gap = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Gap set to {}px", value));
                 }
             }
         }
@@ -576,7 +578,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.gap_top = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Top gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Top gap set to {}px", value));
                 }
             }
         }
@@ -584,7 +586,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.gap_left = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Left gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Left gap set to {}px", value));
                 }
             }
         }
@@ -592,7 +594,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.gap_right = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Right gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Right gap set to {}px", value));
                 }
             }
         }
@@ -600,7 +602,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.gap_bottom = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Bottom gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Bottom gap set to {}px", value));
                 }
             }
         }
@@ -608,7 +610,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.cascade_offset = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Cascade offset set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Cascade offset set to {}px", value));
                 }
             }
         }
@@ -616,7 +618,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.bar_height = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Bar height set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Bar height set to {}px", value));
                 }
             }
         }
@@ -624,7 +626,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.border_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Border width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Border width set to {}px", value));
                 }
             }
         }
@@ -632,7 +634,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.border_font_size = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Border font size set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Border font size set to {}px", value));
                 }
             }
         }
@@ -640,7 +642,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.transition_duration = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Transition duration set to {}ms", value));
+                    crate::config::show_notification("cce-client", &format!("Transition duration set to {}ms", value));
                 }
             }
         }
@@ -648,7 +650,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.fullscreen_border_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Fullscreen border width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Fullscreen border width set to {}px", value));
                 }
             }
         }
@@ -656,7 +658,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.cascade_border_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Cascade border width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Cascade border width set to {}px", value));
                 }
             }
         }
@@ -664,7 +666,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.grid_gap = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Grid gap set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Grid gap set to {}px", value));
                 }
             }
         }
@@ -672,7 +674,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.grid_border_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Grid border width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Grid border width set to {}px", value));
                 }
             }
         }
@@ -680,7 +682,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.floating_border_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Floating border width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Floating border width set to {}px", value));
                 }
             }
         }
@@ -691,7 +693,7 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
                 state.layout.border_b = b;
                 state.layout.border_a = a;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Border color set to {}", value_str));
+                    crate::config::show_notification("cce-client", &format!("Border color set to {}", value_str));
                 }
             }
         }
@@ -702,21 +704,21 @@ fn handle_layout_command(rest: &str, state: &mut WindowManager) {
                 state.layout.background_b = b;
                 state.layout.background_a = a;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Background color set to {}", value_str));
+                    crate::config::show_notification("cce-client", &format!("Background color set to {}", value_str));
                 }
             }
         }
         "side_panel_behavior" | "side-panel-behavior" => {
             state.layout.side_panel_behavior = value_str.to_string();
             if state.notifications_enable {
-                crate::config::show_notification("ccec", &format!("Side panel behavior set to {}", value_str));
+                crate::config::show_notification("cce-client", &format!("Side panel behavior set to {}", value_str));
             }
         }
         "side_panel_width" | "side-panel-width" => {
             if let Ok(value) = value_str.parse::<i32>() {
                 state.layout.side_panel_width = value;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Side panel width set to {}px", value));
+                    crate::config::show_notification("cce-client", &format!("Side panel width set to {}px", value));
                 }
             }
         }
@@ -785,11 +787,19 @@ fn handle_set_mode_command(rest: &str, state: &mut WindowManager) {
     let mode = parse_tiling_mode(mode_str);
     let notifications_enable = state.notifications_enable;
     if let Some(window) = state.focused_window_mut() {
+        let old_mode = window.tiling_mode;
         window.tiling_mode = mode;
         window.mode_locked = true;
+        if (mode == TilingMode::Floating || mode == TilingMode::Popup)
+            && old_mode != TilingMode::Floating
+            && old_mode != TilingMode::Popup
+        {
+            window.width = 0;
+            window.height = 0;
+        }
         if notifications_enable {
             let win_title = window.title.as_deref().unwrap_or("Window");
-            crate::config::show_notification("ccec", &format!("Tiling mode set to {} for: {}", mode.as_str(), win_title));
+            crate::config::show_notification("cce-client", &format!("Tiling mode set to {} for: {}", mode.as_str(), win_title));
         }
         state.needs_render = true;
         state.needs_status_update = true;
@@ -816,13 +826,21 @@ fn handle_apply_mode_sharing_command(rest: &str, state: &mut WindowManager) {
     // Iterate over all windows and update tiling mode for matching windows
     for window in &mut state.windows {
         if !window.closed && window.tiling_mode == old_mode {
+            let win_old_mode = window.tiling_mode;
             window.tiling_mode = new_mode;
             window.mode_locked = true;
+            if (new_mode == TilingMode::Floating || new_mode == TilingMode::Popup)
+                && win_old_mode != TilingMode::Floating
+                && win_old_mode != TilingMode::Popup
+            {
+                window.width = 0;
+                window.height = 0;
+            }
         }
     }
 
     if notifications_enable {
-        crate::config::show_notification("ccec", &format!("Applied tiling mode {} to all windows sharing mode {}", new_mode.as_str(), old_mode.as_str()));
+        crate::config::show_notification("cce-client", &format!("Applied tiling mode {} to all windows sharing mode {}", new_mode.as_str(), old_mode.as_str()));
     }
     state.needs_render = true;
     state.needs_status_update = true;
@@ -898,7 +916,7 @@ fn handle_tag_layout_command(rest: &str, state: &mut WindowManager) {
             state.tag_layouts[tag as usize - 1] = mode;
             state.has_tag_layout[tag as usize - 1] = true;
             if state.notifications_enable {
-                crate::config::show_notification("ccec", &format!("Tag {} layout set to {}", tag, mode.as_str()));
+                crate::config::show_notification("cce-client", &format!("Tag {} layout set to {}", tag, mode.as_str()));
             }
             state.needs_render = true;
             state.needs_status_update = true;
@@ -931,7 +949,7 @@ fn handle_set_tag_command(rest: &str, state: &mut WindowManager) {
                     let visible_ids: Vec<u64> = state
                         .windows
                         .iter()
-                        .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                        .filter(|w| (w.tags & state.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                         .map(|w| w.id)
                         .collect();
                     if let Some(seat) = state.seats.iter_mut().find(|s| !s.removed) {
@@ -979,7 +997,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
             }
             if state.tap_to_click != old_val && state.notifications_enable {
                 crate::config::show_notification(
-                    "ccec",
+                    "cce-client",
                     &format!(
                         "Tap-to-click {}",
                         if state.tap_to_click { "enabled" } else { "disabled" }
@@ -992,7 +1010,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.accel_speed = Some(val);
                 state.tap_config_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Acceleration speed set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Acceleration speed set to {}", val));
                 }
             }
         }
@@ -1002,7 +1020,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.accel_profile = Some(val.clone());
                 state.tap_config_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Acceleration profile set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Acceleration profile set to {}", val));
                 }
             }
         }
@@ -1024,7 +1042,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.tap_config_applied = false;
                 if state.notifications_enable {
                     crate::config::show_notification(
-                        "ccec",
+                        "cce-client",
                         &format!(
                             "Natural scroll {}",
                             if state.natural_scroll.unwrap_or(false) { "enabled" } else { "disabled" }
@@ -1051,7 +1069,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.tap_config_applied = false;
                 if state.notifications_enable {
                     crate::config::show_notification(
-                        "ccec",
+                        "cce-client",
                         &format!(
                             "Disable-while-typing {}",
                             if state.dwt.unwrap_or(false) { "enabled" } else { "disabled" }
@@ -1078,7 +1096,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.tap_config_applied = false;
                 if state.notifications_enable {
                     crate::config::show_notification(
-                        "ccec",
+                        "cce-client",
                         &format!(
                             "Disable-while-trackpointing {}",
                             if state.dwtp.unwrap_or(false) { "enabled" } else { "disabled" }
@@ -1107,7 +1125,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.trackpoint_accel_speed = Some(val);
                 state.tap_config_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Trackpoint acceleration speed set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Trackpoint acceleration speed set to {}", val));
                 }
             }
         }
@@ -1117,7 +1135,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.trackpoint_accel_profile = Some(val.clone());
                 state.tap_config_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Trackpoint acceleration profile set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Trackpoint acceleration profile set to {}", val));
                 }
             }
         }
@@ -1127,7 +1145,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.cursor_theme = Some(val.clone());
                 state.cursor_theme_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Cursor theme set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Cursor theme set to {}", val));
                 }
             }
         }
@@ -1136,7 +1154,7 @@ fn handle_input_command(rest: &str, state: &mut WindowManager) {
                 state.cursor_size = Some(val);
                 state.cursor_theme_applied = false;
                 if state.notifications_enable {
-                    crate::config::show_notification("ccec", &format!("Cursor size set to {}", val));
+                    crate::config::show_notification("cce-client", &format!("Cursor size set to {}", val));
                 }
             }
         }
@@ -1283,11 +1301,11 @@ mod tests {
     #[test]
     fn test_ipc_mode_rule_update() {
         let mut state = WindowManager::default();
-        handle_ipc_command("mode fullscreen clear-system-interface", &mut state);
+        handle_ipc_command("mode fullscreen cce-system-interface", &mut state);
         assert_eq!(state.mode_rules.len(), 1);
         assert_eq!(state.mode_rules[0].mode, TilingMode::Fullscreen);
 
-        handle_ipc_command("mode cascade clear-system-interface", &mut state);
+        handle_ipc_command("mode cascade cce-system-interface", &mut state);
         assert_eq!(state.mode_rules.len(), 1);
         assert_eq!(state.mode_rules[0].mode, TilingMode::Cascade);
     }
diff --git a/src/ipc_server.rs b/src/ipc_server.rs
index caece55..858d1f3 100644
--- a/src/ipc_server.rs
+++ b/src/ipc_server.rs
@@ -19,7 +19,7 @@ pub fn spawn_ipc_server(pipe_write: libc::c_int) -> IpcReceiver {
     let tx_clone = tx.clone();
 
     std::thread::Builder::new()
-        .name("ccec-ipc".into())
+        .name("cce-client-ipc".into())
         .spawn(move || {
             ipc_server_main(tx, pipe_write);
         })
diff --git a/src/lib.rs b/src/lib.rs
index df105d1..caaa726 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,4 +1,4 @@
-// ccec — Wayland window manager for river, written in Rust
+// cce-client — Wayland window manager for river, written in Rust
 
 pub mod borders;
 pub mod config;
diff --git a/src/main.rs b/src/main.rs
index af90874..dc9da97 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,18 +1,18 @@
-// ccec — Wayland window manager for river
-
-use ccec::config::parse_config;
-use ccec::ipc;
-use ccec::ipc_server;
-use ccec::restart;
-use ccec::status_server;
-use ccec::wayland::wayland_init;
+// cce-client — Wayland window manager for river
+
+use cce_client::config::parse_config;
+use cce_client::ipc;
+use cce_client::ipc_server;
+use cce_client::restart;
+use cce_client::status_server;
+use cce_client::wayland::wayland_init;
 use std::env;
 use std::fs;
 
-use ccec::paths;
+use cce_client::paths;
 
-/// Write a crash/exit trace to /tmp/ccec-death.log so we can diagnose
-/// why ccec dies even when the normal log gets overwritten on restart.
+/// Write a crash/exit trace to /tmp/cce-client-death.log so we can diagnose
+/// why cce-client dies even when the normal log gets overwritten on restart.
 fn log_death(msg: &str) {
     use std::io::Write;
     if let Ok(mut f) = std::fs::OpenOptions::new()
@@ -40,7 +40,7 @@ fn main() {
         }
     }));
 
-    eprintln!("ccec starting...");
+    eprintln!("cce-client starting...");
 
     // Start the status socket server thread (for waybar integration)
     let status_sender = status_server::spawn_status_server();
@@ -66,7 +66,7 @@ fn main() {
     }
 
     // Connect to Wayland display and get initial state.
-    // SIGUSR2 handler: dump backtrace to /tmp/ccec-bt.txt for debugging busy loops
+    // SIGUSR2 handler: dump backtrace to /tmp/cce-client-bt.txt for debugging busy loops
     unsafe {
         nix::sys::signal::sigaction(
             nix::sys::signal::SIGUSR2,
@@ -95,22 +95,22 @@ fn main() {
     let pipe_read = pipe_fds[0];
     let pipe_write = pipe_fds[1];
 
-    // Start the IPC server thread (for clearctl and clear-system-interface)
+    // Start the IPC server thread (for clearctl and cce-system-interface)
     let ipc_server = ipc_server::spawn_ipc_server(pipe_write);
     let ipc_rx = ipc_server.rx;
     let ipc_tx = ipc_server.tx;
 
     // Setup channel for configuration updates:
-    let (config_tx, config_rx) = tokio::sync::mpsc::unbounded_channel::<ccec::input::InputDaemonMsg>();
+    let (config_tx, config_rx) = tokio::sync::mpsc::unbounded_channel::<cce_client::input::InputDaemonMsg>();
     state.wm.input_controller = Some(config_tx);
 
     // Spawn the input subsystem background thread:
     let pipe_write_clone = pipe_write;
     let ipc_tx_clone = ipc_tx.clone();
     std::thread::Builder::new()
-        .name("ccec-input-subsystem".into())
+        .name("cce-client-input-subsystem".into())
         .spawn(move || {
-            if let Err(e) = ccec::input::run_input_daemon(config_rx, ipc_tx_clone, pipe_write_clone) {
+            if let Err(e) = cce_client::input::run_input_daemon(config_rx, ipc_tx_clone, pipe_write_clone) {
                 eprintln!("[input-subsystem] Fatal error: {:?}", e);
             }
         })
@@ -120,8 +120,8 @@ fn main() {
     state.status_sender = Some(status_sender);
 
     // Check if this is a restart
-    let cold_start = if env::var("CCEC_RESTARTING").as_deref() == Ok("1") {
-        env::remove_var("CCEC_RESTARTING");
+    let cold_start = if env::var("CCE_CLIENT_RESTARTING").as_deref() == Ok("1") {
+        env::remove_var("CCE_CLIENT_RESTARTING");
         false
     } else {
         true
@@ -139,7 +139,7 @@ fn main() {
     );
     let config_start = std::time::Instant::now();
     if let Ok(home) = env::var("HOME") {
-        let config_path = format!("{}/.config/ccec/config.toml", home);
+        let config_path = format!("{}/.config/cce/config.toml", home);
         if fs::metadata(&config_path).is_ok() {
             if let Err(e) = parse_config(&config_path, cold_start, &mut state.wm) {
                 eprintln!("[init] failed to load config: {}", e);
@@ -156,7 +156,7 @@ fn main() {
     if state.wm.pending_scale_apply && state.wm.output_scale > 0.0 && !state.output_heads.is_empty()
     {
         let qh = event_queue.handle();
-        ccec::wayland::apply_output_scale(&mut state, &qh);
+        cce_client::wayland::apply_output_scale(&mut state, &qh);
     }
 
     // Flush any queued requests from config loading (bindings, etc.)
@@ -282,7 +282,7 @@ fn main() {
             }
             if !state.wm.tap_config_applied && !state.libinput_devices.is_empty() {
                 let qh = event_queue.handle();
-                ccec::wayland::apply_input_config(&mut state, &qh);
+                cce_client::wayland::apply_input_config(&mut state, &qh);
             }
         }
 
diff --git a/src/paths.rs b/src/paths.rs
index de180f6..a74053a 100644
--- a/src/paths.rs
+++ b/src/paths.rs
@@ -1,69 +1,69 @@
 use std::env;
-
+ 
 pub fn get_socket_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-{}.sock", display)
+        format!("/tmp/cce-client-{}.sock", display)
     } else {
-        "/tmp/ccec.sock".to_string()
+        "/tmp/cce-client.sock".to_string()
     }
 }
-
+ 
 pub fn get_status_socket_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-status-{}.sock", display)
+        format!("/tmp/cce-client-status-{}.sock", display)
     } else {
-        "/tmp/ccec-status.sock".to_string()
+        "/tmp/cce-client-status.sock".to_string()
     }
 }
-
+ 
 pub fn get_windows_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-windows-{}", display)
+        format!("/tmp/cce-client-windows-{}", display)
     } else {
-        "/tmp/ccec-windows".to_string()
+        "/tmp/cce-client-windows".to_string()
     }
 }
-
+ 
 pub fn get_tags_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-tags-{}", display)
+        format!("/tmp/cce-client-tags-{}", display)
     } else {
-        "/tmp/ccec-tags".to_string()
+        "/tmp/cce-client-tags".to_string()
     }
 }
-
+ 
 pub fn get_layout_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-layout-{}", display)
+        format!("/tmp/cce-client-layout-{}", display)
     } else {
-        "/tmp/ccec-layout".to_string()
+        "/tmp/cce-client-layout".to_string()
     }
 }
-
+ 
 pub fn get_title_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-title-{}", display)
+        format!("/tmp/cce-client-title-{}", display)
     } else {
-        "/tmp/ccec-title".to_string()
+        "/tmp/cce-client-title".to_string()
     }
 }
-
+ 
 pub fn get_death_log_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-death-{}.log", display)
+        format!("/tmp/cce-client-death-{}.log", display)
     } else {
-        "/tmp/ccec-death.log".to_string()
+        "/tmp/cce-client-death.log".to_string()
     }
 }
-
+ 
 pub fn get_bt_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-bt-{}.txt", display)
+        format!("/tmp/cce-client-bt-{}.txt", display)
     } else {
-        "/tmp/ccec-bt.txt".to_string()
+        "/tmp/cce-client-bt.txt".to_string()
     }
 }
-
+ 
 pub fn get_input_coords_socket_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
         format!("/tmp/clear-input-coords-{}.sock", display)
@@ -71,27 +71,27 @@ pub fn get_input_coords_socket_path() -> String {
         "/tmp/clear-input-coords.sock".to_string()
     }
 }
-
+ 
 pub fn get_log_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-{}.log", display)
+        format!("/tmp/cce-client-{}.log", display)
     } else {
-        "/tmp/ccec.log".to_string()
+        "/tmp/cce-client.log".to_string()
     }
 }
-
+ 
 pub fn get_prev_log_path() -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-{}-prev.log", display)
+        format!("/tmp/cce-client-{}-prev.log", display)
     } else {
-        "/tmp/ccec-prev.log".to_string()
+        "/tmp/cce-client-prev.log".to_string()
     }
 }
-
+ 
 pub fn get_xprop_path(wid: u64) -> String {
     if let Ok(display) = env::var("WAYLAND_DISPLAY") {
-        format!("/tmp/ccec-xprop-{}-{}", wid, display)
+        format!("/tmp/cce-client-xprop-{}-{}", wid, display)
     } else {
-        format!("/tmp/ccec-xprop-{}", wid)
+        format!("/tmp/cce-client-xprop-{}", wid)
     }
 }
diff --git a/src/restart.rs b/src/restart.rs
index ca1f11d..2481bcf 100644
--- a/src/restart.rs
+++ b/src/restart.rs
@@ -1,4 +1,4 @@
-// Restart and reload logic for ccec
+// Restart and reload logic for cce-client
 
 use crate::config::parse_config;
 use crate::types::WindowManager;
@@ -7,17 +7,17 @@ use crate::types::WindowManager;
 ///
 /// This forks a child process that waits briefly for the parent to die
 /// (so River cleans up the old Wayland connection), then execs a fresh
-/// ccec instance. The parent (current process) exits immediately.
+/// cce-client instance. The parent (current process) exits immediately.
 ///
-/// The CCEC_RESTARTING environment variable signals that this is a restart
+/// The CCE_CLIENT_RESTARTING environment variable signals that this is a restart
 /// (not a cold start), so the new process skips cold_start_only apps.
 ///
 /// ## Why setsid() is required
 ///
-/// ccec is typically a session leader (PID == SID, started by River's
+/// cce-client is typically a session leader (PID == SID, started by River's
 /// `-c` launch script). When a session leader exits, the kernel sends SIGHUP
 /// to all processes in that session — including the forked child. Without
-/// `setsid()`, the child dies from SIGHUP before it can exec, and ccec
+/// `setsid()`, the child dies from SIGHUP before it can exec, and cce-client
 /// never comes back.
 pub fn wm_restart() {
     use std::time::Instant;
@@ -58,9 +58,9 @@ pub fn wm_restart() {
     }
 
     // Signal that this is a restart, not a cold start
-    std::env::set_var("CCEC_RESTARTING", "1");
+    std::env::set_var("CCE_CLIENT_RESTARTING", "1");
 
-    // Persist state to ~/.cache/ccec_state for the new instance to restore.
+    // Persist state to ~/.cache/cce_client_state for the new instance to restore.
     // Note: we can't pass &WindowManager here since wm_restart() has no access
     // to it. The state file is kept fresh by RenderStart's needs_status_update
     // path, so it should be reasonably up-to-date already.
@@ -76,13 +76,13 @@ pub fn wm_restart() {
     // CString is required because execl() needs a null-terminated C string;
     // Rust's String::as_ptr() is NOT guaranteed to be null-terminated.
     //
-    // We prefer the symlink path (~/.local/bin/ccec) over current_exe()
+    // We prefer the symlink path (~/.local/bin/cce-client) over current_exe()
     // because current_exe() resolves through /proc/self/exe to the real path,
     // which may be on a sync filesystem (Dropbox) that temporarily moves files.
     // The symlink is on the root filesystem and always available.
     let home = std::env::var("HOME").unwrap_or_default();
     let exe_path = if !home.is_empty() {
-        let symlink = format!("{}/.local/bin/ccec", home);
+        let symlink = format!("{}/.local/bin/cce-client", home);
         if std::path::Path::new(&symlink).exists() {
             std::path::PathBuf::from(symlink)
         } else {
@@ -95,7 +95,7 @@ pub fn wm_restart() {
     let path_cstr = std::ffi::CString::new(exe_path.to_string_lossy().into_owned())
         .unwrap_or_else(|_| std::process::exit(1));
 
-    // Fork: child waits for parent to die, then execs fresh ccec.
+    // Fork: child waits for parent to die, then execs fresh cce-client.
     // Parent exits so River tears down the old Wayland connection.
     let pid = unsafe { libc::fork() };
     if pid < 0 {
@@ -123,7 +123,7 @@ pub fn wm_restart() {
             std::thread::sleep(std::time::Duration::from_millis(500));
         }
 
-        // Close inherited Wayland FDs so the new ccec instance doesn't
+        // Close inherited Wayland FDs so the new cce-client instance doesn't
         // confuse River with stale connections.
         // (close everything except stdin/stdout/stderr)
         let max_fd = unsafe { libc::sysconf(libc::_SC_OPEN_MAX) } as i32;
@@ -133,7 +133,7 @@ pub fn wm_restart() {
             }
         }
 
-        // Exec the same binary — replaces this process with a fresh ccec.
+        // Exec the same binary — replaces this process with a fresh cce-client.
         // Retry up to 3 times with a short delay — the binary may be temporarily
         // unavailable if cargo build is replacing it mid-write (atomic rename).
         for attempt in 0..3 {
@@ -218,7 +218,7 @@ pub fn wm_reload(state: &mut WindowManager) {
     // Try TOML config first
     let home = std::env::var("HOME").unwrap_or_default();
     if !home.is_empty() {
-        let config_path = format!("{}/.config/ccec/config.toml", home);
+        let config_path = format!("{}/.config/cce/config.toml", home);
         if std::path::Path::new(&config_path).exists() {
             match parse_config(&config_path, false, state) {
                 Ok(_) => {
@@ -227,12 +227,12 @@ pub fn wm_reload(state: &mut WindowManager) {
                         spawn_command_bg(cmd);
                     }
                     if state.notifications_enable {
-                        crate::config::show_notification("ccec", "Configuration reloaded successfully");
+                        crate::config::show_notification("cce-client", "Configuration reloaded successfully");
                     }
                 }
                 Err(e) => {
                     if state.notifications_enable {
-                        crate::config::show_notification("ccec", &format!("Config reload failed:\n{}", e));
+                        crate::config::show_notification("cce-client", &format!("Config reload failed:\n{}", e));
                     }
                 }
             }
diff --git a/src/state.rs b/src/state.rs
index 33be399..94e52c2 100644
--- a/src/state.rs
+++ b/src/state.rs
@@ -1,7 +1,7 @@
-// Persistent state file for ccec restart recovery.
+// Persistent state file for cce-client restart recovery.
 //
 // Writes window tag assignments and global tag/layout state to
-// ~/.cache/ccec_state so that it survives restarts. On startup,
+// ~/.cache/cce_client_state so that it survives restarts. On startup,
 // the state file is read and applied to re-advertised windows
 // matched by their River identifier (stable across WM restarts)
 // or app_id+title as a fallback.
@@ -21,17 +21,17 @@ use std::fs;
 use std::io::{BufRead, Write};
 use std::path::PathBuf;
 
-/// Get the state file path: ~/.cache/ccec_state
+/// Get the state file path: ~/.cache/cce_client_state
 fn state_file_path() -> PathBuf {
     if let Ok(runtime_dir) = std::env::var("XDG_RUNTIME_DIR") {
         let mut path = PathBuf::from(runtime_dir);
-        path.push("ccec_state");
+        path.push("cce_client_state");
         path
     } else {
         let home = std::env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
         let mut path = PathBuf::from(home);
         path.push(".cache");
-        path.push("ccec_state");
+        path.push("cce_client_state");
         path
     }
 }
@@ -358,9 +358,9 @@ mod tests {
 
     #[test]
     fn test_write_read_roundtrip() {
-        let dir = std::env::temp_dir().join("ccec_state_test");
+        let dir = std::env::temp_dir().join("cce_client_state_test");
         let _ = fs::create_dir_all(&dir);
-        let path = dir.join("ccec_state");
+        let path = dir.join("cce_client_state");
 
         let mut wm = WindowManager::default();
         wm.active_tags = 0b1010; // tags 2 and 4
diff --git a/src/status.rs b/src/status.rs
index 6bf54d7..df2fdc8 100644
--- a/src/status.rs
+++ b/src/status.rs
@@ -12,7 +12,7 @@ pub fn write_status_files(state: &WindowManager) {
     use crate::paths;
     use std::io::Write;
 
-    // /tmp/ccec-tags: active_tags focused_tags num_tags
+    // /tmp/cce-client-tags: active_tags focused_tags num_tags
     if let Ok(mut f) = fs::File::create(paths::get_tags_path()) {
         let _ = writeln!(
             f,
@@ -21,7 +21,7 @@ pub fn write_status_files(state: &WindowManager) {
         );
     }
 
-    // /tmp/ccec-layout: focused window's tiling mode
+    // /tmp/cce-client-layout: focused window's tiling mode
     let mode_str = if state.expose_active {
         "Expose"
     } else {
@@ -35,7 +35,7 @@ pub fn write_status_files(state: &WindowManager) {
         let _ = writeln!(f, "{}", mode_str);
     }
 
-    // /tmp/ccec-windows: one line per window
+    // /tmp/cce-client-windows: one line per window
     if let Ok(mut f) = fs::File::create(paths::get_windows_path()) {
         let focused_title = state.focused_window().map(|w| w.title.clone());
 
@@ -67,7 +67,7 @@ pub fn write_status_files(state: &WindowManager) {
             );
         }
 
-        // /tmp/ccec-title
+        // /tmp/cce-client-title
         if let Some(title) = focused_title {
             if let Ok(mut tf) = fs::File::create(paths::get_title_path()) {
                 let _ = writeln!(tf, "{}", title.as_deref().unwrap_or("(null)"));
diff --git a/src/status_server.rs b/src/status_server.rs
index 6e79e1a..0791b36 100644
--- a/src/status_server.rs
+++ b/src/status_server.rs
@@ -1,7 +1,7 @@
 // Status socket server for waybar integration
 //
 // Runs in a dedicated thread. Waybar custom module scripts connect to
-// /tmp/ccec-status.sock, send a subscription line ("tags", "layout",
+// /tmp/cce-client-status.sock, send a subscription line ("tags", "layout",
 // or "title"), and receive JSON lines whenever the status changes.
 //
 // The main loop sends updates through an mpsc channel — no blocking,
@@ -72,7 +72,7 @@ pub fn spawn_status_server() -> StatusSender {
     let (tx, rx) = mpsc::channel::<StatusUpdate>();
 
     std::thread::Builder::new()
-        .name("ccec-status".into())
+        .name("cce-client-status".into())
         .spawn(move || {
             status_server_main(rx);
         })
@@ -246,7 +246,7 @@ fn format_for_subscription(sub: Subscription, update: &StatusUpdate) -> String {
 /// This is the same logic that write_status_files() uses, but produces
 /// the data for the socket instead of writing to files.
 pub fn build_status_update(wm: &crate::types::WindowManager) -> StatusUpdate {
-    // Tags: generate the same pango-marked JSON that ccec-tags.sh produces
+    // Tags: generate the same pango-marked JSON that cce-client-tags.sh produces
     let tags_json = render_tags_json(
         wm.active_tags,
         wm.focused_tags,
@@ -274,7 +274,7 @@ pub fn build_status_update(wm: &crate::types::WindowManager) -> StatusUpdate {
 
 fn read_status_normal_color_from_config() -> String {
     let home = std::env::var("HOME").unwrap_or_else(|_| "/home/lsgalante".to_string());
-    let path = format!("{}/.config/ccec/config.toml", home);
+    let path = format!("{}/.config/cce/config.toml", home);
     if let Ok(content) = std::fs::read_to_string(&path) {
         for line in content.lines() {
             let trimmed = line.trim();
@@ -293,7 +293,7 @@ fn read_status_normal_color_from_config() -> String {
 }
 
 /// Render tag state as a JSON string with pango markup, matching the format
-/// produced by the old ccec-tags.sh script.
+/// produced by the old cce-client-tags.sh script.
 ///
 /// Colors:
 /// - Active + Focused: bright (dynamic normal color, defaults to #ccccd8)
diff --git a/src/tiling.rs b/src/tiling.rs
index c66f0c5..52ecc93 100644
--- a/src/tiling.rs
+++ b/src/tiling.rs
@@ -1,4 +1,4 @@
-// Tiling formulas ported from ccec.c
+// Tiling formulas ported from cce-client.c
 
 /// Cascade depth factor: each depth step multiplies channels by this
 pub const CASCADE_DEPTH_FACTOR: f64 = 0.80;
diff --git a/src/types.rs b/src/types.rs
index 4e1dcda..d115128 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,4 +1,4 @@
-// Core data structures for ccec
+// Core data structures for cce-client
 
 use std::collections::HashMap;
 
@@ -349,7 +349,7 @@ pub struct WindowManager {
     /// on the next output_manager done event. Set by config load and
     /// by VT-switch-back (where wlroots resets scale to 1).
     pub pending_scale_apply: bool,
-    /// When true, apply persisted state from ~/.cache/ccec_state on the
+    /// When true, apply persisted state from ~/.cache/cce_client_state on the
     /// next ManageStart cycle (after windows have been re-advertised).
     /// Set to true on startup/restart, consumed after application.
     pub needs_state_restore: bool,
diff --git a/src/wayland.rs b/src/wayland.rs
index 274a145..0aa3e9d 100644
--- a/src/wayland.rs
+++ b/src/wayland.rs
@@ -1,4 +1,4 @@
-// Wayland display connection, registry, and event dispatch for ccec
+// Wayland display connection, registry, and event dispatch for cce-client
 
 use wayland_client::{
     event_created_child, protocol::wl_registry, Connection, Dispatch, EventQueue, Proxy,
@@ -674,7 +674,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                                 .windows
                                 .iter()
                                 .filter(|w| {
-                                    !w.closed && (w.tags & active_tags) != 0 && w.id != *closed_id && w.app_id.as_deref() != Some("clear-status-interface")
+                                    !w.closed && (w.tags & active_tags) != 0 && w.id != *closed_id && w.app_id.as_deref() != Some("cce-status-interface")
                                 })
                                 .map(|w| w.id)
                                 .collect();
@@ -831,7 +831,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                     }
                 }
 
-                // Apply persisted state from ~/.cache/ccec_state on first ManageStart.
+                // Apply persisted state from ~/.cache/cce_client_state on first ManageStart.
                 // This restores window tag assignments, active_tags, tag_layouts, and
                 // locked tiling modes from the previous session. Must run before
                 // assign_window_modes so restored tags/modes take effect.
@@ -900,7 +900,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                         .wm
                         .windows
                         .iter()
-                        .filter(|w| w.is_new && !w.closed && (w.tags & active_tags) != 0 && w.app_id.as_deref() != Some("clear-status-interface") && w.app_id.as_deref() != Some("clear-notification-daemon"))
+                        .filter(|w| w.is_new && !w.closed && (w.tags & active_tags) != 0 && w.app_id.as_deref() != Some("cce-status-interface") && w.app_id.as_deref() != Some("clear-notification-daemon"))
                         .map(|w| w.id)
                         .last();
                     if let Some(new_id) = new_focused_id {
@@ -1063,7 +1063,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                     crate::decorations::update_decorations(state, qhandle);
 
                     // Raise and stack windows according to z-axis logic:
-                    // 1. clear-status-interface at the absolute bottom (score = 0)
+                    // 1. cce-status-interface at the absolute bottom (score = 0)
                     // 2. Unfocused tiled/fullscreen windows (score = 1)
                     // 3. Focused tiled/fullscreen window (score = 2)
                     // 4. Unfocused floating windows (score = 3)
@@ -1072,7 +1072,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                     let focused_id = state.wm.seats.iter().find(|s| !s.removed).and_then(|s| s.focused_window_id);
 
                     let get_window_score = |win: &crate::types::Window| -> i32 {
-                        if win.app_id.as_deref() == Some("clear-status-interface") {
+                        if win.app_id.as_deref() == Some("cce-status-interface") {
                             0
                         } else if win.tiling_mode == crate::types::TilingMode::Popup {
                             5
@@ -1163,7 +1163,7 @@ impl Dispatch<RiverWindowManagerV1, ()> for AppState {
                 if state.wm.needs_status_update {
                     crate::status::write_status_files(&state.wm);
 
-                    // Persist state to ~/.cache/ccec_state for restart recovery.
+                    // Persist state to ~/.cache/cce_client_state for restart recovery.
                     // Safe: just file I/O, no fork, no blocking.
                     crate::state::write_state(&state.wm);
 
@@ -1320,8 +1320,19 @@ impl Dispatch<RiverWindowV1, ()> for AppState {
 
             river_window_v1::Event::Dimensions { width, height } => {
                 if let Some(window) = state.wm.get_window_mut(wid) {
-                    window.width = width;
-                    window.height = height;
+                    let changed = window.width != width || window.height != height;
+                    eprintln!(
+                        "[window] id={} (app_id={:?}) Event::Dimensions: {}x{} (was {}x{}) changed={}",
+                        wid, window.app_id, width, height, window.width, window.height, changed
+                    );
+                    if changed {
+                        window.width = width;
+                        window.height = height;
+                        state.wm.needs_render = true;
+                        if let Some(ref wm) = state.window_manager {
+                            wm.manage_dirty();
+                        }
+                    }
                 }
             }
 
@@ -1417,7 +1428,7 @@ impl Dispatch<RiverWindowV1, ()> for AppState {
                     // Spawn an async xprop check for XWayland parent detection.
                     // River doesn't forward WM_TRANSIENT_FOR for XWayland windows,
                     // so we check via xdotool + xprop as a fallback.
-                    // The script writes results to /tmp/ccec-xprop-{wid} which
+                    // The script writes results to /tmp/cce-client-xprop-{wid} which
                     // is read on the next ManageStart cycle.
                     if !window.has_parent && window.pid > 0 {
                         let pid = window.pid;
@@ -1459,8 +1470,6 @@ impl Dispatch<RiverWindowV1, ()> for AppState {
                     );
 
                     if !window.size_hint_applied && min_width > 32 {
-                        window.width = min_width;
-                        window.height = min_height;
                         window.size_hint_applied = true;
                         state.wm.needs_render = true;
                         if let Some(ref wm) = state.window_manager {
@@ -1565,7 +1574,7 @@ impl Dispatch<RiverWindowV1, ()> for AppState {
                             let visible_ids: Vec<u64> = state.wm
                                 .windows
                                 .iter()
-                                .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.id != wid && w.app_id.as_deref() != Some("clear-status-interface"))
+                                .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.id != wid && w.app_id.as_deref() != Some("cce-status-interface"))
                                 .map(|w| w.id)
                                 .collect();
                             seat.focused_window_id = visible_ids.last().copied();
@@ -1723,7 +1732,7 @@ impl Dispatch<RiverSeatV1, ()> for AppState {
             } => {
                 if let Some(wid) = state.window_id_for_proxy(&river_window) {
                     let target_app_id = state.wm.get_window(wid).and_then(|w| w.app_id.clone());
-                    if target_app_id.as_deref() == Some("clear-status-interface") {
+                    if target_app_id.as_deref() == Some("cce-status-interface") {
                         // Do not focus status bar!
                         return;
                     }
@@ -2262,7 +2271,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                 eprintln!("spawn: {}", cmd);
                 // Close inherited FDs > 2 in the child so that spawned
                 // Wayland clients (fuzzel, etc.) never accidentally read
-                // from ccec's Wayland socket fd. This prevents protocol
+                // from cce-client's Wayland socket fd. This prevents protocol
                 // corruption and the CPU spin loop that results from it.
                 use std::os::unix::process::CommandExt;
                 let _ = unsafe {
@@ -2318,7 +2327,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                                 .windows
                                 .iter()
                                 .filter(|w| {
-                                    (w.tags & state.wm.active_tags) != 0 && !w.closed && !w.minimized && w.id != win_id && w.app_id.as_deref() != Some("clear-status-interface")
+                                    (w.tags & state.wm.active_tags) != 0 && !w.closed && !w.minimized && w.id != win_id && w.app_id.as_deref() != Some("cce-status-interface")
                                 })
                                 .map(|w| w.id)
                                 .collect();
@@ -2376,7 +2385,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                         .windows
                         .iter()
                         .filter(|w| {
-                            (w.tags & state.wm.active_tags) != 0 && !w.closed && !w.minimized && w.id != focused_id && w.app_id.as_deref() != Some("clear-status-interface")
+                            (w.tags & state.wm.active_tags) != 0 && !w.closed && !w.minimized && w.id != focused_id && w.app_id.as_deref() != Some("cce-status-interface")
                         })
                         .map(|w| w.id)
                         .collect();
@@ -2402,7 +2411,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                 let visible_ids: Vec<u64> = state.wm
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.id != focused_id && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & active_tags) != 0 && !w.closed && !w.minimized && w.id != focused_id && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 let next_id = visible_ids.last().copied();
@@ -2433,7 +2442,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                         (w.tags & state.wm.active_tags) != 0
                             && !w.closed
                             && !w.minimized
-                            && w.app_id.as_deref() != Some("clear-status-interface")
+                            && w.app_id.as_deref() != Some("cce-status-interface")
                             && (focused_mode.is_none() || Some(w.tiling_mode) == focused_mode)
                     })
                     .map(|w| w.id)
@@ -2477,7 +2486,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                         (w.tags & state.wm.active_tags) != 0
                             && !w.closed
                             && !w.minimized
-                            && w.app_id.as_deref() != Some("clear-status-interface")
+                            && w.app_id.as_deref() != Some("cce-status-interface")
                             && (focused_mode.is_none() || Some(w.tiling_mode) == focused_mode)
                     })
                     .map(|w| w.id)
@@ -2686,7 +2695,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
             );
 
             if state.wm.notifications_enable {
-                crate::config::show_notification("ccec", &format!("Layout set to {} for active tags", next.as_str()));
+                crate::config::show_notification("cce-client", &format!("Layout set to {} for active tags", next.as_str()));
             }
 
             // Unlock windows that got their mode from the layout (not from mode_rules
@@ -2730,7 +2739,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                     win.mode_locked = true;
                     if notifications_enable {
                         let win_title = win.title.as_deref().unwrap_or("Window");
-                        crate::config::show_notification("ccec", &format!("Tiling mode set to {} for: {}", next.as_str(), win_title));
+                        crate::config::show_notification("cce-client", &format!("Tiling mode set to {} for: {}", next.as_str(), win_title));
                     }
                     state.wm.needs_render = true;
                     state.wm.needs_status_update = true;
@@ -2765,7 +2774,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                     let mut updated_count = 0;
                     for win in &mut state.wm.windows {
                         if !win.closed
-                            && win.app_id.as_deref() != Some("clear-status-interface")
+                            && win.app_id.as_deref() != Some("cce-status-interface")
                             && (win.tags & active_tags) != 0
                             && win.tiling_mode == old_mode
                         {
@@ -2784,7 +2793,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
 
                     if notifications_enable && updated_count > 0 {
                         crate::config::show_notification(
-                            "ccec",
+                            "cce-client",
                             &format!(
                                 "Tiling mode set to {} for all {} windows on active tag",
                                 next.as_str(),
@@ -2825,7 +2834,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                 .wm
                 .windows
                 .iter()
-                .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                 .map(|w| w.id)
                 .collect();
             if let Some(seat) = state.wm.seats.iter_mut().find(|s| !s.removed) {
@@ -2864,7 +2873,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                     .wm
                     .windows
                     .iter()
-                    .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                    .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                     .map(|w| w.id)
                     .collect();
                 if let Some(seat) = state.wm.seats.iter_mut().find(|s| !s.removed) {
@@ -2906,7 +2915,7 @@ fn execute_action(state: &mut AppState, seat_id: u64, action: &crate::types::Act
                         .wm
                         .windows
                         .iter()
-                        .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("clear-status-interface"))
+                        .filter(|w| (w.tags & state.wm.active_tags) != 0 && !w.closed && w.app_id.as_deref() != Some("cce-status-interface"))
                         .map(|w| w.id)
                         .collect();
                     if let Some(seat) = state.wm.seats.iter_mut().find(|s| !s.removed) {
@@ -3409,7 +3418,7 @@ pub fn wayland_init() -> Result<(Connection, EventQueue<AppState>, AppState), St
         state.render_count
     );
 
-    eprintln!("ccec: Wayland connection established");
+    eprintln!("cce-client: Wayland connection established");
 
     Ok((conn, event_queue, state))
 }
diff --git a/src/wm.rs b/src/wm.rs
index 3b1fa97..f280d9e 100644
--- a/src/wm.rs
+++ b/src/wm.rs
@@ -19,7 +19,7 @@ use wayland_client::QueueHandle;
 /// Returns the resolved TilingMode, or None if the window's mode is locked
 /// (i.e., the user manually set it and it should not be overridden).
 pub fn get_mode_for_window(wm: &WindowManager, win: &Window) -> Option<TilingMode> {
-    if win.app_id.as_deref() == Some("clear-status-interface") {
+    if win.app_id.as_deref() == Some("cce-status-interface") {
         return Some(TilingMode::Fullscreen);
     }
 
@@ -131,12 +131,12 @@ fn get_circular_for_window(mode_rules: &[ModeRule], win: &Window) -> bool {
 /// Assign tiling modes to all windows that aren't mode_locked.
 /// Should be called during ManageStart before compute_tiling.
 pub fn assign_window_modes(wm: &mut WindowManager) {
-    // Enforce that clear-status-interface is assigned all tags so that it is always visible
+    // Enforce that cce-status-interface is assigned all tags so that it is always visible
     // and that blank steam_proton helper windows are always untagged so they remain hidden.
     for win in &mut wm.windows {
         win.circular = get_circular_for_window(&wm.mode_rules, win);
 
-        if win.app_id.as_deref() == Some("clear-status-interface") {
+        if win.app_id.as_deref() == Some("cce-status-interface") {
             win.tags = u32::MAX;
         }
 
@@ -156,7 +156,7 @@ pub fn assign_window_modes(wm: &mut WindowManager) {
         let mode_rules = &wm.mode_rules;
         for win in &mut wm.windows {
             if win.is_new
-                && win.app_id.as_deref() != Some("clear-status-interface")
+                && win.app_id.as_deref() != Some("cce-status-interface")
                 && !win.has_parent
                 && !matches_mode_rule(mode_rules, win)
             {
@@ -197,7 +197,15 @@ pub fn assign_window_modes(wm: &mut WindowManager) {
                     "[mode] window {} (app_id={:?}): {:?} -> {:?}",
                     wid, win.app_id, win.tiling_mode, mode
                 );
+                let old_mode = win.tiling_mode;
                 win.tiling_mode = mode;
+                if (mode == TilingMode::Floating || mode == TilingMode::Popup)
+                    && old_mode != TilingMode::Floating
+                    && old_mode != TilingMode::Popup
+                {
+                    win.width = 0;
+                    win.height = 0;
+                }
             }
         }
     }
@@ -340,7 +348,7 @@ fn compute_tiling(
         let mut results = Vec::new();
         // Collect all active non-status-bar, non-popup windows on current tags
         let mut expose_windows: Vec<&crate::types::Window> = wm.windows.iter()
-            .filter(|w| !w.closed && !w.minimized && (w.tags & wm.active_tags) != 0 && w.app_id.as_deref() != Some("clear-status-interface") && w.tiling_mode != TilingMode::Popup)
+            .filter(|w| !w.closed && !w.minimized && (w.tags & wm.active_tags) != 0 && w.app_id.as_deref() != Some("cce-status-interface") && w.tiling_mode != TilingMode::Popup)
             .collect();
 
         // Sort expose_windows by current visual location (y first, then x)
@@ -382,8 +390,8 @@ fn compute_tiling(
             }
         }
 
-        // Still layout clear-status-interface as fullscreen/bar if present
-        if let Some(win) = wm.windows.iter().find(|w| !w.closed && w.app_id.as_deref() == Some("clear-status-interface")) {
+        // Still layout cce-status-interface as fullscreen/bar if present
+        if let Some(win) = wm.windows.iter().find(|w| !w.closed && w.app_id.as_deref() == Some("cce-status-interface")) {
             let (tx, ty, tw, th) = tiling::tile_fullscreen(
                 phys_w,
                 phys_h,
@@ -472,13 +480,13 @@ fn compute_tiling(
         .and_then(|s| s.focused_window_id)
         .filter(|&fid| {
             wm.get_window(fid).map_or(false, |w| {
-                (w.tags & wm.active_tags) != 0 && !w.closed && !w.minimized && w.tiling_mode == TilingMode::Fullscreen && w.app_id.as_deref() != Some("clear-status-interface")
+                (w.tags & wm.active_tags) != 0 && !w.closed && !w.minimized && w.tiling_mode == TilingMode::Fullscreen && w.app_id.as_deref() != Some("cce-status-interface")
             })
         })
         .or_else(|| {
             // Fallback: first fullscreen window if no focused window qualifies
             wm.windows.iter().find(|w| {
-                (w.tags & wm.active_tags) != 0 && !w.closed && !w.minimized && w.tiling_mode == TilingMode::Fullscreen && w.app_id.as_deref() != Some("clear-status-interface")
+                (w.tags & wm.active_tags) != 0 && !w.closed && !w.minimized && w.tiling_mode == TilingMode::Fullscreen && w.app_id.as_deref() != Some("cce-status-interface")
             }).map(|w| w.id)
         });
 
@@ -494,7 +502,7 @@ fn compute_tiling(
         if wm.layout.side_panel_behavior == "above" {
             0
         } else if panel_win.hint_min_width > 32 {
-            panel_win.hint_min_width
+            std::cmp::max(wm.layout.side_panel_width, panel_win.hint_min_width)
         } else {
             wm.layout.side_panel_width
         }
@@ -517,7 +525,7 @@ fn compute_tiling(
         let (x, y, w, h) = match mode {
             TilingMode::SidePanel => {
                 let target_w = if win.hint_min_width > 32 {
-                    win.hint_min_width
+                    std::cmp::max(wm.layout.side_panel_width, win.hint_min_width)
                 } else {
                     wm.layout.side_panel_width
                 };
@@ -526,8 +534,8 @@ fn compute_tiling(
                 (phys_x + bw, bar_height + phys_y + dec_h, target_w - bw * 2, screen_h - bar_height - (dec_h + bw))
             }
             TilingMode::Fullscreen => {
-                if fullscreen_id == Some(wid) || win.app_id.as_deref() == Some("clear-status-interface") {
-                    let border_w = if win.app_id.as_deref() == Some("clear-status-interface") {
+                if fullscreen_id == Some(wid) || win.app_id.as_deref() == Some("cce-status-interface") {
+                    let border_w = if win.app_id.as_deref() == Some("cce-status-interface") {
                         0
                     } else {
                         wm.layout.fullscreen_border_width
@@ -644,7 +652,11 @@ fn compute_tiling(
             }
         };
 
-        let final_x = if mode != TilingMode::SidePanel && win.app_id.as_deref() != Some("clear-status-interface") {
+        let final_x = if mode != TilingMode::SidePanel
+            && mode != TilingMode::Fullscreen
+            && mode != TilingMode::Popup
+            && win.app_id.as_deref() != Some("cce-status-interface")
+        {
             x + shift_x
         } else {
             x
@@ -654,7 +666,7 @@ fn compute_tiling(
 
     // Layout minimized windows as bubbles stacked at the right edge
     let minimized_windows: Vec<&crate::types::Window> = wm.windows.iter()
-        .filter(|w| !w.closed && w.minimized && (w.tags & wm.active_tags) != 0 && w.app_id.as_deref() != Some("clear-status-interface"))
+        .filter(|w| !w.closed && w.minimized && (w.tags & wm.active_tags) != 0 && w.app_id.as_deref() != Some("cce-status-interface"))
         .collect();
 
     let bubble_width = 160;
@@ -716,7 +728,7 @@ fn apply_tiling(state: &mut AppState, results: &[TileResult]) {
 
         if let Some(win) = state.wm.get_window_mut(tr.wid) {
             let is_cascade = win.tiling_mode == TilingMode::Cascade;
-            let is_exposed = expose_active && win.tiling_mode != TilingMode::Popup && win.app_id.as_deref() != Some("clear-status-interface");
+            let is_exposed = expose_active && win.tiling_mode != TilingMode::Popup && win.app_id.as_deref() != Some("cce-status-interface");
             let was_animating = win.anim_x.is_some() || win.anim_y.is_some() || win.anim_w.is_some() || win.anim_h.is_some() || win.anim_opacity.is_some();
             let should_animate = (is_cascade || is_exposed || is_side_panel_present || win.tiling_mode == TilingMode::SidePanel || was_animating) && !win.minimized;
 
@@ -803,8 +815,11 @@ fn apply_tiling(state: &mut AppState, results: &[TileResult]) {
             if !is_floating_and_expose {
                 win.x = final_x;
                 win.y = final_y;
-                win.width = final_w;
-                win.height = final_h;
+                let is_floating_or_popup = win.tiling_mode == TilingMode::Floating || win.tiling_mode == TilingMode::Popup;
+                if !(is_floating_or_popup && win.width == 0) {
+                    win.width = final_w;
+                    win.height = final_h;
+                }
             } else {
                 // If it's a new floating window created during expose mode,
                 // initialize its position to the default floating position if unset.
@@ -833,7 +848,17 @@ fn apply_tiling(state: &mut AppState, results: &[TileResult]) {
 
         // Propose dimensions via river_window_v1
         if let Some(wp) = state.get_window_proxy(tr.wid) {
-            wp.river_window.propose_dimensions(final_w, final_h);
+            let is_floating_or_popup = if let Some(win) = state.wm.get_window(tr.wid) {
+                (win.tiling_mode == TilingMode::Floating || win.tiling_mode == TilingMode::Popup) && win.width == 0
+            } else {
+                false
+            };
+
+            if is_floating_or_popup {
+                wp.river_window.propose_dimensions(0, 0);
+            } else {
+                wp.river_window.propose_dimensions(final_w, final_h);
+            }
             // Tell the client to use server-side decoration.
             // Per the River protocol, use_csd is the default when neither
             // use_csd nor use_ssd is called. Calling use_ssd here ensures
@@ -863,7 +888,7 @@ pub fn set_expose_active(wm: &mut WindowManager, active: bool) {
         .and_then(|s| s.focused_window_id);
 
     for win in &mut wm.windows {
-        if win.closed || win.app_id.as_deref() == Some("clear-status-interface") || win.tiling_mode == TilingMode::Popup {
+        if win.closed || win.app_id.as_deref() == Some("cce-status-interface") || win.tiling_mode == TilingMode::Popup {
             continue;
         }
         let is_focused = Some(win.id) == focused_id;
@@ -922,7 +947,7 @@ pub fn render_opacity(state: &mut AppState) {
         }
         if let Some(wp) = state.get_window_proxy(win.id) {
             let is_cascade = win.tiling_mode == TilingMode::Cascade;
-            let is_exposed = state.wm.expose_visual_active && win.tiling_mode != TilingMode::Popup && win.app_id.as_deref() != Some("clear-status-interface");
+            let is_exposed = state.wm.expose_visual_active && win.tiling_mode != TilingMode::Popup && win.app_id.as_deref() != Some("cce-status-interface");
             let was_animating = win.anim_opacity.is_some();
             let should_fade = is_cascade || is_exposed || was_animating;
 
diff --git a/start-river.sh b/start-river.sh
index ce87e56..bd9dbf8 100755
--- a/start-river.sh
+++ b/start-river.sh
@@ -1,40 +1,40 @@
 #!/bin/bash
-# Launch river with ccec on this TTY
+# Launch river with cce-client on this TTY
 # Usage: Switch to a free TTY, log in, and run this script
-
+ 
 LOGGING=false
 for arg in "$@"; do
     case "$arg" in
         --logging) LOGGING=true ;;
     esac
 done
-
+ 
 export XDG_RUNTIME_DIR=/run/user/$(id -u)
 export WAYLAND_DISPLAY=wayland-1
 export XCURSOR_THEME="crosshair-theme"
 export XCURSOR_SIZE=24
 export XCURSOR_PATH="/home/lsgalante/.local/share/icons:/home/lsgalante/.icons:/usr/share/icons"
-
-# Create the River init executable (ccec launch script)
+ 
+# Create the River init executable (cce-client launch script)
 # This must exist before River starts, and /tmp is cleared on reboot.
 if [ "$LOGGING" = true ]; then
-    cat > /tmp/ccec-launch-river.sh << 'LAUNCH_EOF'
+    cat > /tmp/cce-client-launch-river.sh << 'LAUNCH_EOF'
 #!/bin/sh
-exec /home/lsgalante/.local/bin/ccec 2>/tmp/ccec-${WAYLAND_DISPLAY}.log
+exec /home/lsgalante/.local/bin/cce-client 2>/tmp/cce-client-${WAYLAND_DISPLAY}.log
 LAUNCH_EOF
 else
-    cat > /tmp/ccec-launch-river.sh << 'LAUNCH_EOF'
+    cat > /tmp/cce-client-launch-river.sh << 'LAUNCH_EOF'
 #!/bin/sh
-exec /home/lsgalante/.local/bin/ccec
+exec /home/lsgalante/.local/bin/cce-client
 LAUNCH_EOF
 fi
-chmod +x /tmp/ccec-launch-river.sh
-
-echo "Starting river with ccec..."
+chmod +x /tmp/cce-client-launch-river.sh
+ 
+echo "Starting river with cce-client..."
 if [ "$LOGGING" = true ]; then
-    echo "Logs: /tmp/river-ccec.log + /tmp/ccec-${WAYLAND_DISPLAY}.log"
+    echo "Logs: /tmp/river-cce-client.log + /tmp/cce-client-${WAYLAND_DISPLAY}.log"
 else
     echo "Logging disabled. Use --logging to enable."
 fi
-
-exec river -c /tmp/ccec-launch-river.sh 2>/tmp/river-ccec.log
+ 
+exec river -c /tmp/cce-client-launch-river.sh 2>/tmp/river-cce-client.log