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

commitcf81535ce6fc5f05c6ee6cf02f58ca9ed0d51d38
parentb82a0eec9d
authorLucas Galante <[email protected]>
date2026-08-26 12:59
fix: never focus the grid window

The grid became clickable when it started advertising an input region
for its desktop items, and the click path focuses whatever it hits — so
a press on a pinned image handed focus to a surface the size of the
whole patch, and focus-follow then panned the camera to "reveal" it.
Every click on an item dragged the desktop out from under the pointer.

Blocked at Seat::focus alongside the status bar and wallpaper rather
than at the call sites: the grid is the canvas, not a window, so it is
never focusable by any path, present or future.

Shadow-verified: right-clicking an item leaves the camera pixel-still,
where it previously jumped the image out of view.

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

 src/server/seat.rs | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/src/server/seat.rs b/src/server/seat.rs
index 68d3c79..5ad07e2 100644
--- a/src/server/seat.rs
+++ b/src/server/seat.rs
@@ -347,8 +347,17 @@ impl Seat {
 
     pub unsafe fn focus(&mut self, new_focus: Focus) {
         if let Focus::Window(window) = new_focus {
-            if !window.is_null() && ((*window).is_status_bar() || (*window).is_wallpaper()) {
-                log::info!("[FocusDebug] Seat::focus blocking focus to status bar/wallpaper window");
+            // The grid is the canvas, not a window: it must never take focus.
+            // It became clickable when it started advertising an input region
+            // for its desktop items, and the click path focuses whatever it
+            // hits — which handed focus to a surface the size of the whole
+            // patch and then let focus-follow pan the camera to "reveal" it,
+            // so every press on an item dragged the desktop out from under
+            // the pointer.
+            if !window.is_null()
+                && ((*window).is_status_bar() || (*window).is_wallpaper() || (*window).is_grid())
+            {
+                log::info!("[FocusDebug] Seat::focus blocking focus to status bar/wallpaper/grid window");
                 return;
             }
         }