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