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

commit71ad9a530bbd626d10702ae38cbf56c0510c2233
parentd2af53e7ea
authorLucas Galante <[email protected]>
date2026-08-13 00:22
perf: gate arrange_views tracing, drop the wl_list_insert trace

arrange_views logged a header plus a per-window dump (allocating a title and an
app_id String per window) whenever debug logging was on. A status-bar commit
runs an arrange every second, so that was ~15-20 lines/second on an idle
desktop. Now behind CCE_ARRANGE_DEBUG, matching the policy-side switch in
cce-window-manager.

Also removes the entry/exit log::info! pair in wl_list_insert — a raw list
splice helper tracing every call at info level, 2149 lines in a two-minute
session. The null-check error paths stay; wl_list_remove right below it never
had this, which is the tell that it was leftover debugging.

Together with the earlier CCE_DIRTY_BACKTRACE and CCE_BLUR_DEBUG gates, an idle
session log should now be nearly silent.

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

 src/server/server.rs         |  2 --
 src/server/window_manager.rs | 13 +++++++++++--
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/server/server.rs b/src/server/server.rs
index 7440588..f335b0f 100644
--- a/src/server/server.rs
+++ b/src/server/server.rs
@@ -203,7 +203,6 @@ pub struct WlrXwayland {
 
 // Wayland list manipulation utilities
 pub unsafe fn wl_list_insert(list: *mut WlList, elm: *mut WlList) {
-    log::info!("wl_list_insert: list={:?}, elm={:?}", list, elm);
     if list.is_null() {
         log::error!("wl_list_insert: list is null!");
         return;
@@ -216,7 +215,6 @@ pub unsafe fn wl_list_insert(list: *mut WlList, elm: *mut WlList) {
     (*elm).next = (*list).next;
     (*(*list).next).prev = elm;
     (*list).next = elm;
-    log::info!("wl_list_insert: done");
 }
 
 pub unsafe fn wl_list_remove(elm: *mut WlList) {
diff --git a/src/server/window_manager.rs b/src/server/window_manager.rs
index 5d59747..aa95d77 100644
--- a/src/server/window_manager.rs
+++ b/src/server/window_manager.rs
@@ -181,6 +181,15 @@ fn dirty_backtrace_debug() -> bool {
     *FLAG.get_or_init(|| std::env::var_os("CCE_DIRTY_BACKTRACE").is_some())
 }
 
+/// `CCE_ARRANGE_DEBUG=1` — the arrange pass and its per-window dump. A status
+/// bar commit runs a full arrange every second, so at debug level this alone
+/// wrote ~15-20 lines/second (and allocated a title + app_id String per window
+/// per pass) on an otherwise idle desktop.
+pub(crate) fn arrange_debug() -> bool {
+    static FLAG: std::sync::OnceLock<bool> = std::sync::OnceLock::new();
+    *FLAG.get_or_init(|| std::env::var_os("CCE_ARRANGE_DEBUG").is_some())
+}
+
 impl WindowManager {
     pub unsafe fn init(&mut self) -> Result<(), ()> {
         // This is a stub for the 0-arg struct instantiation.
@@ -1732,8 +1741,8 @@ impl WindowManager {
 
     pub unsafe fn arrange_views(&mut self) {
         self.update_restore_placeholders();
-        log::debug!("Monolithic arrange_views triggered. Windows: {}", self.windows.count());
-        if log::log_enabled!(log::Level::Debug) {
+        if arrange_debug() {
+            log::debug!("Monolithic arrange_views triggered. Windows: {}", self.windows.count());
             for (idx, &win_ptr) in self.windows.iter().enumerate() {
                 if win_ptr.is_null() { continue; }
                 let title = (*win_ptr).get_title_string().unwrap_or_else(|| "None".to_string());