gardesk/gar / 6c08b3a

Browse files

focus workspace on its last monitor instead of moving it to current

Authored by espadonne
SHA
6c08b3a4be58c0c5132430f428029d690e4d1d44
Parents
3ab345f
Tree
b6cf40d

3 changed files

StatusFile+-
M gar/src/core/mod.rs 7 1
M gar/src/core/workspace.rs 3 0
M gar/src/x11/events.rs 12 6
gar/src/core/mod.rsmodified
@@ -59,7 +59,7 @@ pub struct WindowManager {
5959
 
6060
 impl WindowManager {
6161
     pub fn new(conn: Connection) -> Result<Self> {
62
-        let workspaces: Vec<Workspace> = (1..=10)
62
+        let mut workspaces: Vec<Workspace> = (1..=10)
6363
             .map(|i| Workspace::new(i, i.to_string()))
6464
             .collect();
6565
 
@@ -131,6 +131,9 @@ impl WindowManager {
131131
         for (i, monitor) in monitors.iter_mut().enumerate() {
132132
             monitor.workspaces = vec![i]; // Just track initial workspace
133133
             monitor.active_workspace = i; // Monitor 0 shows ws 0, monitor 1 shows ws 1, etc.
134
+            if i < workspaces.len() {
135
+                workspaces[i].last_monitor = Some(i);
136
+            }
134137
             tracing::debug!("Monitor '{}' starts with workspace {}", monitor.name, i + 1);
135138
         }
136139
 
@@ -331,6 +334,9 @@ impl WindowManager {
331334
                 monitor.workspaces = vec![first_free];
332335
                 used_workspaces.insert(first_free);
333336
             }
337
+            if monitor.active_workspace < self.workspaces.len() {
338
+                self.workspaces[monitor.active_workspace].last_monitor = Some(i);
339
+            }
334340
             tracing::info!("Monitor '{}' showing workspace {}", monitor.name, monitor.active_workspace + 1);
335341
         }
336342
 
gar/src/core/workspace.rsmodified
@@ -11,6 +11,8 @@ pub struct Workspace {
1111
     pub floating: Vec<XWindow>,
1212
     pub focused: Option<XWindow>,
1313
     pub visible: bool,
14
+    /// Last monitor this workspace was displayed on (for focus-back behavior)
15
+    pub last_monitor: Option<usize>,
1416
 }
1517
 
1618
 impl Workspace {
@@ -22,6 +24,7 @@ impl Workspace {
2224
             floating: Vec::new(),
2325
             focused: None,
2426
             visible: id == 1,
27
+            last_monitor: None,
2528
         }
2629
     }
2730
 
gar/src/x11/events.rsmodified
@@ -2417,6 +2417,7 @@ impl WindowManager {
24172417
             // Focus the monitor that has this workspace
24182418
             self.focused_monitor = monitor_idx;
24192419
             self.focused_workspace = idx;
2420
+            self.workspaces[idx].last_monitor = Some(monitor_idx);
24202421
 
24212422
             // Update EWMH
24222423
             self.conn.set_current_desktop(idx as u32)?;
@@ -2441,13 +2442,16 @@ impl WindowManager {
24412442
                 self.conn.set_active_window(None)?;
24422443
             }
24432444
         } else {
2444
-            // Workspace not visible - show it on current monitor (i3 behavior)
2445
-            let current_monitor = self.focused_monitor;
2446
-            let old_ws = self.monitors[current_monitor].active_workspace;
2445
+            // Workspace not visible — show it on the monitor it was last on,
2446
+            // falling back to the current monitor if it was never shown.
2447
+            let target_monitor = self.workspaces[idx].last_monitor
2448
+                .filter(|&m| m < self.monitors.len())
2449
+                .unwrap_or(self.focused_monitor);
2450
+            let old_ws = self.monitors[target_monitor].active_workspace;
24472451
 
24482452
             tracing::info!(
24492453
                 "Switching monitor {} from workspace {} to {}",
2450
-                current_monitor, old_ws + 1, idx + 1
2454
+                target_monitor, old_ws + 1, idx + 1
24512455
             );
24522456
 
24532457
             // Hide windows on old workspace
@@ -2464,7 +2468,9 @@ impl WindowManager {
24642468
             }
24652469
 
24662470
             // Update monitor's active workspace
2467
-            self.monitors[current_monitor].active_workspace = idx;
2471
+            self.monitors[target_monitor].active_workspace = idx;
2472
+            self.workspaces[idx].last_monitor = Some(target_monitor);
2473
+            self.focused_monitor = target_monitor;
24682474
             self.focused_workspace = idx;
24692475
 
24702476
             // Update EWMH
@@ -2492,7 +2498,7 @@ impl WindowManager {
24922498
                 self.focused_window = None;
24932499
                 self.conn.set_active_window(None)?;
24942500
                 if warp_pointer {
2495
-                    let monitor_geom = self.monitors[current_monitor].geometry;
2501
+                    let monitor_geom = self.monitors[target_monitor].geometry;
24962502
                     let center_x = monitor_geom.x + (monitor_geom.width as i16 / 2);
24972503
                     let center_y = monitor_geom.y + (monitor_geom.height as i16 / 2);
24982504
                     self.conn.warp_pointer(center_x, center_y)?;