gardesk/gar / 52f19d4

Browse files

Fix window unmap handling during workspace switches and moves

Track intentional unmaps with ignore_unmap_count to prevent
UnmapNotify handler from unmanaging windows we're just hiding.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
52f19d4484111d598aa66ca22581dcae1178151b
Parents
ce429d4
Tree
37d644e

3 changed files

StatusFile+-
M .gitignore 1 0
M gar/src/core/window.rs 3 0
M gar/src/x11/events.rs 19 0
.gitignoremodified
@@ -1,2 +1,3 @@
11
 docs/
22
 target/
3
+CLAUDE.md
gar/src/core/window.rsmodified
@@ -21,6 +21,8 @@ pub struct Window {
2121
     pub frame: Option<XWindow>,
2222
     /// Window title (cached from _NET_WM_NAME or WM_NAME)
2323
     pub title: String,
24
+    /// Count of UnmapNotify events to ignore (for intentional unmaps during workspace switch)
25
+    pub ignore_unmap_count: u32,
2426
 }
2527
 
2628
 impl Window {
@@ -38,6 +40,7 @@ impl Window {
3840
             workspace,
3941
             frame: None,
4042
             title: String::new(),
43
+            ignore_unmap_count: 0,
4144
         }
4245
     }
4346
 
gar/src/x11/events.rsmodified
@@ -320,6 +320,17 @@ impl WindowManager {
320320
             return Ok(());
321321
         }
322322
 
323
+        // Check if we intentionally unmapped this window (workspace switch, move, etc.)
324
+        // If so, decrement the counter and ignore this UnmapNotify
325
+        if let Some(win) = self.windows.get_mut(&window) {
326
+            if win.ignore_unmap_count > 0 {
327
+                win.ignore_unmap_count -= 1;
328
+                tracing::debug!("Ignoring UnmapNotify for window {} (intentional unmap, count now {})",
329
+                    window, win.ignore_unmap_count);
330
+                return Ok(());
331
+            }
332
+        }
333
+
323334
         // Check if this window is on a visible workspace (any monitor's active workspace)
324335
         let is_visible = self.windows.get(&window)
325336
             .map(|w| self.is_workspace_visible(w.workspace))
@@ -1069,6 +1080,10 @@ impl WindowManager {
10691080
 
10701081
             // Hide windows on old workspace
10711082
             for window in self.workspaces[old_ws].all_windows() {
1083
+                // Mark as intentional unmap so UnmapNotify handler ignores it
1084
+                if let Some(win) = self.windows.get_mut(&window) {
1085
+                    win.ignore_unmap_count += 1;
1086
+                }
10721087
                 self.conn.unmap_window(window)?;
10731088
                 // Also unmap frames if present
10741089
                 if let Some(frame) = self.frames.frame_for_client(window) {
@@ -1194,6 +1209,10 @@ impl WindowManager {
11941209
             self.conn.map_window(window)?;
11951210
         } else {
11961211
             // Target is not visible - hide the window
1212
+            // Mark as intentional unmap so UnmapNotify handler ignores it
1213
+            if let Some(win) = self.windows.get_mut(&window) {
1214
+                win.ignore_unmap_count += 1;
1215
+            }
11971216
             self.conn.unmap_window(window)?;
11981217
             if let Some(frame) = self.frames.frame_for_client(window) {
11991218
                 self.conn.unmap_window(frame)?;