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

commit0ad490f6fe91d95e48db0401dcb549dda4fbeeff
parenta07105c12c
authorLucas Galante <[email protected]>
date2026-08-10 10:39
refactor: remove the viewport tag feature

Gone: the view / set-viewport / set-tag IPC commands and their ccectl
usage lines, the no-op viewport-layout stub, and the status socket's
viewport topic (StatusUpdate.viewport_json, Subscription::Viewport) —
nothing subscribes to it since the bar dropped its tabs and mode menu.

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

 CLAUDE.md                    |  8 ++++----
 README.md                    |  2 +-
 scripts/cce-desktop-menu     |  2 +-
 src/cce_ctl.rs               |  3 ---
 src/server/status_server.rs  | 26 +-------------------------
 src/server/window_manager.rs | 37 -------------------------------------
 6 files changed, 7 insertions(+), 71 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 869da62..9ab19a9 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -13,7 +13,7 @@ protocol XML files you'll see throughout `src/server/` and `protocol/`.
 
 This crate lives inside a larger Cargo workspace (the workspace root is the **parent**
 directory `../Cargo.toml`, which lists ~20 `cce-*` sibling apps). This crate is the
-compositor; the siblings (`cce-status-interface`, `cce-system-settings`, etc.) are
+compositor; the siblings (`cce-status-interface`, `cce-system-interface`, etc.) are
 clients that talk to it over its sockets. Intra-workspace dependencies: `cce-ui`
 (`../cce-ui`, config helpers) and **`cce-window-manager`** (`../cce-window-manager`,
 its own repo) — the pure-Rust window-management **policy layer** (arrange pass,
@@ -44,7 +44,7 @@ is ignored because profiles are only honored at the workspace root.
   Any arg other than `client`/`help` just starts the server (`cce_fx::run_server()`).
 - **`ccectl`** (`src/bin/ccectl.rs`) — thin IPC client; all logic is in
   `src/cce_ctl.rs` (`run_cce_ctl`). Run `ccectl` with no args to see the full command
-  list (layout, view, mode, viewport, pointer-*, key*, bind, spawn, notify, exit, …).
+  list (layout, mode, pointer-*, key*, bind, spawn, notify, exit, …).
 
 ### System dependencies (checked by `build.rs`)
 
@@ -141,8 +141,8 @@ Persistent window state is saved to **`~/.local/state/cce/state.json`**
 - **Control socket** `/tmp/cce-{WAYLAND_DISPLAY}.sock` (`ipc_server.rs`): line-oriented
   request/reply over a Unix socket. `ccectl` / `cce_ctl.rs` is the client.
 - **Status socket** `/tmp/cce-status-{WAYLAND_DISPLAY}.sock` (`status_server.rs`): runs
-  on its own thread; a client sends one subscription line (`viewport`, `layout`,
-  `title`, or `modifiers`) and receives JSON/text lines on every change. This feeds the
+  on its own thread; a client sends one subscription line (`layout`, `title`,
+  `modifiers`, or `dismiss`) and receives text lines on every change. This feeds the
   status bar (`cce-status-interface`). The main loop pushes updates through a
   `StatusSender` mpsc handle.
 
diff --git a/README.md b/README.md
index 44f1a70..03700e4 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ rounded-corner scene effects. It began as a Rust rewrite of the
 
 This crate is the compositor. It lives inside the larger `cce` Cargo workspace (root at
 the parent directory), alongside client apps such as `cce-status-interface`,
-`cce-system-settings`, and other `cce-*` siblings that connect to it over its sockets.
+`cce-system-interface`, and other `cce-*` siblings that connect to it over its sockets.
 
 ## Binaries
 
diff --git a/scripts/cce-desktop-menu b/scripts/cce-desktop-menu
index 4c11f90..1098618 100644
--- a/scripts/cce-desktop-menu
+++ b/scripts/cce-desktop-menu
@@ -71,7 +71,7 @@ case "$btn" in
         ;;
     "settings")
         # Run settings interface
-        "$HOME"/.local/bin/cce-system-settings &
+        "$HOME"/.local/bin/cce-system-interface &
         ;;
     "expose")
         $CCE_CTL expose
diff --git a/src/cce_ctl.rs b/src/cce_ctl.rs
index 99f9e7b..ad1f637 100644
--- a/src/cce_ctl.rs
+++ b/src/cce_ctl.rs
@@ -32,7 +32,6 @@ fn usage(name: &str, to_stderr: bool) {
     print("");
     print("commands:");
     print("  layout <gap|gap_top|gap_left|gap_right|gap_bottom|offset|grid_gap|bar_height> <value>");
-    print("  view <1-4>");
     print("  close");
     print("  minimize");
     print("  focus-next");
@@ -75,9 +74,7 @@ fn usage(name: &str, to_stderr: bool) {
     print("  bind <mods> <keysym> <action> [args...]");
     print("  pbind <mods> <button> <action>");
     print("  retile");
-    print("  set-viewport <1-4>");
     print("  mode <cascade|grid|fullscreen|floating|popup|maximized|overlay> <app_id> [title]");
-    print("  viewport-layout <1-4> <cascade|grid|fullscreen|floating|popup|maximized|overlay>");
     print("  pointer-location");
     print("  pointer-move-to <x> <y>            (layout pixels)");
     print("  pointer-move-by <dx> <dy>");
diff --git a/src/server/status_server.rs b/src/server/status_server.rs
index 62f08f7..94c2615 100644
--- a/src/server/status_server.rs
+++ b/src/server/status_server.rs
@@ -2,7 +2,7 @@
 //
 // Runs in a dedicated thread. cce-status connects to
 // /tmp/cce-status-{WAYLAND_DISPLAY}.sock, sends a subscription line
-// ("viewport", "layout", or "title"), and receives JSON lines whenever the status changes.
+// ("layout", "title", "modifiers", or "dismiss") and receives lines whenever the status changes.
 //
 // The main loop sends updates through an mpsc channel. The server thread
 // owns the socket and handles all I/O independently of the Wayland event loop.
@@ -14,8 +14,6 @@ use std::sync::mpsc;
 /// A status update sent from the main loop to the server thread.
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct StatusUpdate {
-    /// JSON string for viewport module subscribers
-    pub viewport_json: String,
     /// Plain text for layout module subscribers
     pub layout_text: String,
     /// Plain text for title module subscribers
@@ -38,7 +36,6 @@ pub enum StatusMsg {
 /// Subscription types that the status bar script can request.
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 enum Subscription {
-    Viewport,
     Layout,
     Title,
     Modifiers,
@@ -50,7 +47,6 @@ enum Subscription {
 impl Subscription {
     fn from_str(s: &str) -> Self {
         match s.trim() {
-            "viewport" => Subscription::Viewport,
             "layout" => Subscription::Layout,
             "title" => Subscription::Title,
             "modifiers" => Subscription::Modifiers,
@@ -301,7 +297,6 @@ fn read_subscription(stream: &UnixStream) -> Subscription {
 
 fn format_for_subscription(sub: Subscription, update: &StatusUpdate) -> String {
     match sub {
-        Subscription::Viewport => update.viewport_json.clone(),
         Subscription::Layout => update.layout_text.clone(),
         Subscription::Title => update.title_text.clone(),
         Subscription::Modifiers => update.modifiers_text.clone(),
@@ -326,24 +321,6 @@ pub unsafe fn build_status_update(wm: &crate::window_manager::WindowManager) ->
         wm.focused_window()
     };
 
-    // The viewport payload carries only the active viewport number (nearest
-    // View1-4 anchor): the bar reads it at menu-open time for the layout
-    // menu's viewport-layout target. Nothing renders this payload — the
-    // viewport tabs are gone, and the old camera debug text (live pan/zoom
-    // floats) caused per-frame bar rebuilds during camera animations.
-    let anchors = [(0.0f64, 0.0f64), (2000.0, 0.0), (0.0, 2000.0), (2000.0, 2000.0)];
-    let active = anchors
-        .iter()
-        .enumerate()
-        .min_by(|(_, a), (_, b)| {
-            let da = (wm.desk_pan_x - a.0).powi(2) + (wm.desk_pan_y - a.1).powi(2);
-            let db = (wm.desk_pan_x - b.0).powi(2) + (wm.desk_pan_y - b.1).powi(2);
-            da.partial_cmp(&db).unwrap_or(std::cmp::Ordering::Equal)
-        })
-        .map(|(i, _)| i + 1)
-        .unwrap_or(1);
-    let viewport_json = format!("{{\"active\": {}}}", active);
-
     let layout_text = if !focused_window.is_null() {
         (*focused_window).tiling_mode.as_str().to_string()
     } else {
@@ -398,7 +375,6 @@ pub unsafe fn build_status_update(wm: &crate::window_manager::WindowManager) ->
     let modifiers_text = if super_pressed { "super" } else { "none" }.to_string();
 
     StatusUpdate {
-        viewport_json,
         layout_text,
         title_text,
         modifiers_text,
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index bc477ea..469b95f 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -2727,40 +2727,6 @@ impl WindowManager {
                 self.dirty_windowing();
                 return format!("ok {}\n", enable);
             }
-            "view" => {
-                if parts.len() < 2 { return "error: missing tag\n".to_string(); }
-                if let Ok(tag) = parts[1].parse::<i32>() {
-                    if tag >= 1 && tag <= 4 {
-                        let act = match tag {
-                            1 => crate::config::Action::View1,
-                            2 => crate::config::Action::View2,
-                            3 => crate::config::Action::View3,
-                            4 => crate::config::Action::View4,
-                            _ => crate::config::Action::None,
-                        };
-                        self.execute_action(&act, None);
-                        return "ok\n".to_string();
-                    }
-                }
-                "error: invalid tag\n".to_string()
-            }
-            "set-viewport" | "set-tag" => {
-                if parts.len() < 2 { return "error: missing viewport index\n".to_string(); }
-                if let Ok(tag) = parts[1].parse::<i32>() {
-                    if tag >= 1 && tag <= 4 {
-                        let act = match tag {
-                            1 => crate::config::Action::SetViewport1,
-                            2 => crate::config::Action::SetViewport2,
-                            3 => crate::config::Action::SetViewport3,
-                            4 => crate::config::Action::SetViewport4,
-                            _ => crate::config::Action::None,
-                        };
-                        self.execute_action(&act, None);
-                        return "ok\n".to_string();
-                    }
-                }
-                "error: invalid viewport index\n".to_string()
-            }
             "pan-by" => {
                 if parts.len() < 3 { return "error: missing dx or dy\n".to_string(); }
                 if let (Ok(dx), Ok(dy)) = (parts[1].parse::<f64>(), parts[2].parse::<f64>()) {
@@ -3339,9 +3305,6 @@ impl WindowManager {
                 self.dirty_windowing();
                 "ok\n".to_string()
             }
-            "viewport-layout" => {
-                "ok\n".to_string()
-            }
             "mode" => {
                 if parts.len() < 3 { return "error: missing mode or app_id\n".to_string(); }
                 let mode = crate::config::parse_tiling_mode(parts[1]);