Wayland compositor (wlroots)
git clone https://git.lucas.co/cce-compositor.git
fix(grid): cell labels above the cells; `desktop cell_labels=` toggle
The overview's chess-style square coordinates were direct children of
the grid tree, so any cell rect the pool created after them (a zoom
that grew the lattice) stacked on top and hid them. They now live in
their own subtree of the grid tree, raised above the cells and the
bevel subtree on every draw.
`surface { desktop cell_labels=(bool)false }` turns them off (default
on); also settable live as `desktop_cell_labels` through ccectl's
config path.
Co-Authored-By: Claude Fable 5.1 <[email protected]>
src/server/config.rs | 17 +++++++++++++++++
src/server/output.rs | 26 +++++++++++++++++++++++---
src/server/window_manager.rs | 5 +++++
3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/src/server/config.rs b/src/server/config.rs
index 2bf120f..7ece8f7 100644
--- a/src/server/config.rs
+++ b/src/server/config.rs
@@ -80,6 +80,9 @@ pub struct Layout {
pub desktop_line_relief: Option<f64>,
pub desktop_cell_fade_inset: i64,
pub desktop_grid_fade_mode: String,
+ /// Chess-style coordinates on the desktop squares while overview is
+ /// open. KDL: `surface { desktop cell_labels=(bool)false }`.
+ pub desktop_cell_labels: bool,
/// Drop shadow under cce/ssd windows (scenefx box-shadow node).
pub shadow_enabled: bool,
/// Gaussian spread in logical px.
@@ -236,6 +239,7 @@ impl Default for Layout {
desktop_line_relief: None,
desktop_cell_fade_inset: 0,
desktop_grid_fade_mode: "linear".to_string(),
+ desktop_cell_labels: true,
bevel_enabled: true,
bevel_thickness: 10.0,
bevel_light_x: -0.7071,
@@ -522,6 +526,8 @@ pub struct SurfaceConfig {
pub desktop_cell_fade_inset: i64,
#[serde(default = "default_desktop_grid_fade_mode")]
pub desktop_grid_fade_mode: String,
+ #[serde(default = "default_desktop_cell_labels")]
+ pub desktop_cell_labels: bool,
#[serde(default = "default_desktop_snap")]
pub desktop_snap: bool,
#[serde(default)]
@@ -646,6 +652,7 @@ impl Default for SurfaceConfig {
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_cell_labels: default_desktop_cell_labels(),
desktop_snap: default_desktop_snap(),
desktop_overview_ramp: String::new(),
desktop_overview_ms: default_desktop_overview_ms(),
@@ -716,6 +723,10 @@ fn default_desktop_cell_fade_inset() -> i64 {
0
}
+fn default_desktop_cell_labels() -> bool {
+ true
+}
+
fn default_desktop_grid_fade_mode() -> String {
"linear".to_string()
}
@@ -2003,6 +2014,11 @@ fn parse_kdl_config(content: &str) -> Result<Config, String> {
surface.desktop_cell_fade_inset = val;
}
}
+ "cell_labels" => {
+ if let Some(val) = entry.value().as_bool() {
+ surface.desktop_cell_labels = val;
+ }
+ }
"grid_fade_mode" => {
if let Some(val) = entry.value().as_string() {
surface.desktop_grid_fade_mode = val.to_string();
@@ -2547,6 +2563,7 @@ pub fn parse_config(path: &str, state: &mut crate::window_manager::WindowManager
Some(config.surface.desktop_line_relief as f64)
};
state.layout.desktop_cell_fade_inset = config.surface.desktop_cell_fade_inset;
+ state.layout.desktop_cell_labels = config.surface.desktop_cell_labels;
state.layout.desktop_grid_fade_mode = config.surface.desktop_grid_fade_mode.clone();
state.layout.border_font_size = 11;
diff --git a/src/server/output.rs b/src/server/output.rs
index f7cbfce..4a024d0 100644
--- a/src/server/output.rs
+++ b/src/server/output.rs
@@ -229,6 +229,11 @@ pub struct Output {
/// later-created cell rect.
pub grid_bevel_pool: Vec<*mut ffi::wlr_scene_bevel>,
pub grid_bevel_tree: *mut ffi::wlr_scene_tree,
+ /// The cell labels' own subtree inside `grid_tree`, raised above the
+ /// cell rects and bevels on every draw: label nodes used to be direct
+ /// children of the grid tree, so any cell rect the pool created after
+ /// them stacked on top and hid them.
+ pub cell_label_tree: *mut ffi::wlr_scene_tree,
/// Bevel params the rims were last drawn with (enabled, thickness,
/// light x/y/intensity, shade, shoulder as bits) — the spec alone does
/// not cover them, and a live config reload must redraw the rims too.
@@ -329,6 +334,8 @@ impl Output {
self.grid_rect_pool.clear();
self.grid_bevel_pool.clear();
self.grid_bevel_tree = std::ptr::null_mut();
+ self.cell_label_pool.clear();
+ self.cell_label_tree = std::ptr::null_mut();
}
}
@@ -420,9 +427,11 @@ impl Output {
self.grid_backdrop_rect = std::ptr::null_mut();
}
self.grid_rect_pool.clear();
- // The bevel subtree died with grid_tree above.
+ // The bevel and label subtrees died with grid_tree above.
self.grid_bevel_pool.clear();
self.grid_bevel_tree = std::ptr::null_mut();
+ self.cell_label_pool.clear();
+ self.cell_label_tree = std::ptr::null_mut();
if !self.adjust_tree.is_null() {
ffi::wlr_scene_node_destroy(self.adjust_tree as *mut ffi::wlr_scene_node);
@@ -555,6 +564,7 @@ impl Output {
grid_rect_pool: Vec::new(),
grid_bevel_pool: Vec::new(),
grid_bevel_tree: std::ptr::null_mut(),
+ cell_label_tree: std::ptr::null_mut(),
last_grid_bevel: None,
grid_force_redraw_frames: 0,
cell_label_pool: Vec::new(),
@@ -1579,7 +1589,8 @@ impl Output {
/// navigation aid, not desktop furniture.
unsafe fn draw_cell_labels(&mut self) {
let wm = &(*self.server).wm;
- let overview = wm.mode == crate::window_manager::WindowManagerMode::Overview;
+ let overview = wm.mode == crate::window_manager::WindowManagerMode::Overview
+ && wm.layout.desktop_cell_labels;
if !overview {
if !self.cell_label_pool.is_empty() {
@@ -1592,6 +1603,15 @@ impl Output {
if self.grid_tree.is_null() {
return;
}
+ if self.cell_label_tree.is_null() {
+ self.cell_label_tree = ffi::wlr_scene_tree_create(self.grid_tree);
+ if self.cell_label_tree.is_null() {
+ return;
+ }
+ }
+ // Above the cell rects and the bevel subtree, which draw_grid raised
+ // just before this.
+ ffi::wlr_scene_node_raise_to_top(self.cell_label_tree as *mut ffi::wlr_scene_node);
let (viewport_w, viewport_h) = self.current.dimensions();
let spec = wm.layout.background_spec();
@@ -1653,7 +1673,7 @@ impl Output {
ffi::wlr_scene_node_set_enabled(node as *mut ffi::wlr_scene_node, true);
node
} else {
- let node = ffi::wlr_scene_buffer_create(self.grid_tree, buf);
+ let node = ffi::wlr_scene_buffer_create(self.cell_label_tree, buf);
if node.is_null() {
continue;
}
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index ec5f3f2..d0622b9 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -5459,6 +5459,11 @@ impl WindowManager {
self.layout.desktop_cell_fade_inset = v;
}
}
+ "desktop_cell_labels" => {
+ if let Ok(v) = val.parse::<bool>() {
+ self.layout.desktop_cell_labels = v;
+ }
+ }
"desktop_grid_fade_mode" => {
self.layout.desktop_grid_fade_mode = val.to_string();
}