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 @@
1
 docs/
1
 docs/
2
 target/
2
 target/
3
+CLAUDE.md
gar/src/core/window.rsmodified
@@ -21,6 +21,8 @@ pub struct Window {
21
     pub frame: Option<XWindow>,
21
     pub frame: Option<XWindow>,
22
     /// Window title (cached from _NET_WM_NAME or WM_NAME)
22
     /// Window title (cached from _NET_WM_NAME or WM_NAME)
23
     pub title: String,
23
     pub title: String,
24
+    /// Count of UnmapNotify events to ignore (for intentional unmaps during workspace switch)
25
+    pub ignore_unmap_count: u32,
24
 }
26
 }
25
 
27
 
26
 impl Window {
28
 impl Window {
@@ -38,6 +40,7 @@ impl Window {
38
             workspace,
40
             workspace,
39
             frame: None,
41
             frame: None,
40
             title: String::new(),
42
             title: String::new(),
43
+            ignore_unmap_count: 0,
41
         }
44
         }
42
     }
45
     }
43
 
46
 
gar/src/x11/events.rsmodified
@@ -320,6 +320,17 @@ impl WindowManager {
320
             return Ok(());
320
             return Ok(());
321
         }
321
         }
322
 
322
 
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
+
323
         // Check if this window is on a visible workspace (any monitor's active workspace)
334
         // Check if this window is on a visible workspace (any monitor's active workspace)
324
         let is_visible = self.windows.get(&window)
335
         let is_visible = self.windows.get(&window)
325
             .map(|w| self.is_workspace_visible(w.workspace))
336
             .map(|w| self.is_workspace_visible(w.workspace))
@@ -1069,6 +1080,10 @@ impl WindowManager {
1069
 
1080
 
1070
             // Hide windows on old workspace
1081
             // Hide windows on old workspace
1071
             for window in self.workspaces[old_ws].all_windows() {
1082
             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
+                }
1072
                 self.conn.unmap_window(window)?;
1087
                 self.conn.unmap_window(window)?;
1073
                 // Also unmap frames if present
1088
                 // Also unmap frames if present
1074
                 if let Some(frame) = self.frames.frame_for_client(window) {
1089
                 if let Some(frame) = self.frames.frame_for_client(window) {
@@ -1194,6 +1209,10 @@ impl WindowManager {
1194
             self.conn.map_window(window)?;
1209
             self.conn.map_window(window)?;
1195
         } else {
1210
         } else {
1196
             // Target is not visible - hide the window
1211
             // 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
+            }
1197
             self.conn.unmap_window(window)?;
1216
             self.conn.unmap_window(window)?;
1198
             if let Some(frame) = self.frames.frame_for_client(window) {
1217
             if let Some(frame) = self.frames.frame_for_client(window) {
1199
                 self.conn.unmap_window(frame)?;
1218
                 self.conn.unmap_window(frame)?;