git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit10e54393d26ead0aa53d4d7e0802840045964ef8
parentdd9f738532
authorLucas Galante <[email protected]>
date2026-08-21 14:45
config/layout: shared-only reads + window_corner_radius

An app's per-app config override restyles the app, but some values
describe things OUTSIDE the app: the compositor clips every decorated
window at the SHARED backplate corner_radius, and the desktop grid draws
its cells from it. An app that overrides the backplate radius (the
designer ships corner_radius=24 for chunkier plates) and derives its
window-corner arcs from the merged view detaches its silhouette
tracing from the actual silhouette.

cached_shared_config/get_i64_shared read the shared config without the
per-app merge (own mtime cache), and layout::window_corner_radius is the
canonical 'what arc is my window clipped at' — use it for any
window-corner arc an app draws itself.

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

 src/config.rs | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/layout.rs | 11 +++++++++++
 2 files changed, 54 insertions(+)

diff --git a/src/config.rs b/src/config.rs
index f2fc67e..5c788bf 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -543,6 +543,49 @@ pub fn cached_config_content() -> String {
     CONFIG_CACHE.read().map(|c| c.raw_content.clone()).unwrap_or_default()
 }
 
+static SHARED_CONFIG_CACHE: std::sync::RwLock<ConfigCache> = std::sync::RwLock::new(ConfigCache {
+    last_modified: None,
+    parsed: None,
+    raw_content: String::new(),
+});
+
+/// The SHARED config alone — the per-app override is deliberately NOT merged.
+/// For values that describe something outside the app (the compositor's
+/// window silhouette radius), where an app-local override restyles the app
+/// but must not desynchronize it from the DE. Mtime-cached like
+/// [`cached_config`].
+pub fn cached_shared_config() -> serde_json::Value {
+    let path = get_config_path();
+    let current_modified = std::fs::metadata(&path).ok().and_then(|m| m.modified().ok());
+
+    if let Ok(cache) = SHARED_CONFIG_CACHE.read() {
+        if cache.last_modified.is_some() && cache.last_modified == current_modified {
+            if let Some(ref val) = cache.parsed {
+                return val.clone();
+            }
+        }
+    }
+
+    let content = std::fs::read_to_string(&path).unwrap_or_default();
+    let val = if let Ok(doc) = content.parse::<kdl::KdlDocument>() {
+        kdl_to_json(&doc)
+    } else {
+        serde_json::json!({})
+    };
+    if let Ok(mut cache) = SHARED_CONFIG_CACHE.write() {
+        cache.last_modified = current_modified;
+        cache.parsed = Some(val.clone());
+        cache.raw_content = content;
+    }
+    val
+}
+
+/// Read an i64 at `pointer` from the SHARED config only (no per-app merge),
+/// or `default` — see [`cached_shared_config`].
+pub fn get_i64_shared(pointer: &str, default: i64) -> i64 {
+    cached_shared_config().pointer(pointer).and_then(|v| v.as_i64()).unwrap_or(default)
+}
+
 // ── Typed accessors over the cached config ──────────────────────────────────
 // Each reads the mtime-cached config and extracts a value at a JSON pointer
 // (e.g. "/notifications/enable"), returning the default when absent or mistyped.
diff --git a/src/layout.rs b/src/layout.rs
index 500d873..7bed991 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -1570,6 +1570,17 @@ pub fn corner_shape() -> f32 {
     get_style_registry().read().unwrap().get_float("corner_shape").unwrap_or(2.0).clamp(2.0, 16.0)
 }
 
+/// The window silhouette's nominal corner radius: the SHARED config's
+/// backplate corner_radius, never the per-app override. The compositor clips
+/// every decorated window with this value (widened by
+/// [`corner_span_factor`]), so any window-corner arc an app draws itself must
+/// use it too — even when the app restyles its own plates through its
+/// override file — or its corners detach from the silhouette (and from the
+/// desktop grid's cells, which share the same knob).
+pub fn window_corner_radius() -> f32 {
+    crate::config::get_i64_shared("/style/surface/backplate/corner_radius", 12) as f32
+}
+
 /// The curvature-matched corner-span factor for window-scale squircle corners.
 /// A raw superellipse of exponent n at a circle's nominal radius turns tighter
 /// at the diagonal than that circle — its radius of curvature there is