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

commitc20e2d3902a8775e15da55da373a61b578132a9f
parent5f092f734a
authorLucas Galante <[email protected]>
date2026-08-18 12:57
grid: honor style.surface.desktop.line_relief in the fallback

Same semantics as the cce-grid client: logical px for the rail lip,
0 = no lip, negative/unset = the bevel_thickness-derived default. Parsed
in the desktop style node, mapped as Option so unset stays distinct
from zero, applied on ccectl reload like the other desktop keys.

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

 src/server/config.rs | 22 ++++++++++++++++++++++
 src/server/output.rs | 12 +++++++++---
 2 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/src/server/config.rs b/src/server/config.rs
index 8b932c2..a019195 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -54,6 +54,9 @@ pub struct Layout {
     pub desktop_cell_color: [f32; 4],
     pub desktop_grid_scale: f64,
     pub desktop_gap_width: i32,
+    /// Grid-line lip width in logical px; None = follow the DE-wide relief
+    /// material (bevel_thickness clamped to the rail), 0 = no lip.
+    pub desktop_line_relief: Option<f64>,
     pub desktop_cell_fade_inset: i64,
     pub desktop_grid_fade_mode: String,
     /// Drop shadow under cce/ssd windows (scenefx box-shadow node).
@@ -184,6 +187,7 @@ impl Default for Layout {
             desktop_cell_color: [0.05, 0.05, 0.05, 0.05],
             desktop_grid_scale: 100.0,
             desktop_gap_width: 1,
+            desktop_line_relief: None,
             desktop_cell_fade_inset: 0,
             desktop_grid_fade_mode: "linear".to_string(),
             bevel_enabled: true,
@@ -390,6 +394,9 @@ pub struct SurfaceConfig {
     pub desktop_grid_scale: i64,
     #[serde(default = "default_desktop_gap_width")]
     pub desktop_gap_width: i64,
+    /// Negative = unset (follow the DE-wide relief material).
+    #[serde(default = "default_desktop_line_relief")]
+    pub desktop_line_relief: i64,
     #[serde(default = "default_desktop_cell_fade_inset")]
     pub desktop_cell_fade_inset: i64,
     #[serde(default = "default_desktop_grid_fade_mode")]
@@ -496,6 +503,7 @@ impl Default for SurfaceConfig {
             desktop_cell_color: default_desktop_cell_color(),
             desktop_grid_scale: default_desktop_grid_scale(),
             desktop_gap_width: default_desktop_gap_width(),
+            desktop_line_relief: default_desktop_line_relief(),
             desktop_cell_fade_inset: default_desktop_cell_fade_inset(),
             desktop_grid_fade_mode: default_desktop_grid_fade_mode(),
             desktop_snap: default_desktop_snap(),
@@ -553,6 +561,10 @@ fn default_desktop_gap_width() -> i64 {
     1
 }
 
+fn default_desktop_line_relief() -> i64 {
+    -1
+}
+
 fn default_desktop_cell_fade_inset() -> i64 {
     0
 }
@@ -1726,6 +1738,11 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
                                             surface.desktop_gap_width = val;
                                         }
                                     }
+                                    "line_relief" => {
+                                        if let Some(val) = entry.value().as_i64() {
+                                            surface.desktop_line_relief = val;
+                                        }
+                                    }
                                     "cell_fade_inset" => {
                                         if let Some(val) = entry.value().as_i64() {
                                             surface.desktop_cell_fade_inset = val;
@@ -2151,6 +2168,11 @@ pub fn parse_config(path: &str, state: &mut crate::window_manager::WindowManager
     state.layout.desktop_edge_pan_band = config.surface.desktop_edge_pan_band.max(1) as f64;
     state.layout.desktop_edge_pan_speed = config.surface.desktop_edge_pan_speed.max(0) as f64;
     state.layout.desktop_gap_width = config.surface.desktop_gap_width as i32;
+    state.layout.desktop_line_relief = if config.surface.desktop_line_relief < 0 {
+        None
+    } else {
+        Some(config.surface.desktop_line_relief as f64)
+    };
     state.layout.desktop_cell_fade_inset = config.surface.desktop_cell_fade_inset;
     state.layout.desktop_grid_fade_mode = config.surface.desktop_grid_fade_mode.clone();
 
diff --git a/src/server/output.rs b/src/server/output.rs
index 6b111d8..23b8cbf 100644
--- a/src/server/output.rs
+++ b/src/server/output.rs
@@ -960,10 +960,16 @@ impl Output {
                         // rail, pre-scaled by zoom like every cell metric,
                         // so the rail reads as a flat face with a narrow
                         // lip at each sunken cell — not a full-ramp grout.
-                        // The ring expands the cell box by the roll, inner
-                        // edge concentric with the cell arc.
+                        // style.surface.desktop.line_relief overrides the
+                        // width outright (0 = no lip). The ring expands the
+                        // cell box by the roll, inner edge concentric with
+                        // the cell arc.
                         let gap_px = (frame.period_px_exact - cells.cell_px as f64).max(0.0);
-                        let roll = (layout.bevel_thickness as f64 * zoom).min(gap_px * 0.25).max(0.0);
+                        let roll = layout
+                            .desktop_line_relief
+                            .map(|v| v * zoom)
+                            .unwrap_or_else(|| (layout.bevel_thickness as f64 * zoom).min(gap_px * 0.25))
+                            .max(0.0);
                         let hg = roll.round() as i32;
                         let ring_px = cells.cell_px + 2 * hg;
                         let ring_radius = cell_radius + hg;