diff options
| author | srdusr <[email protected]> | 2025-02-03 20:15:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2025-02-03 20:15:00 +0200 |
| commit | dae1617a8b7ee7c40beb452046c5ec84e69931ee (patch) | |
| tree | dd1d00855571c75e1238dbfc823567cded60fd20 /crates/core | |
| parent | 6c1dfe191843ad56aaa0381e5645ad9e74c38b8b (diff) | |
| download | srdwm-dae1617a8b7ee7c40beb452046c5ec84e69931ee.tar.gz srdwm-dae1617a8b7ee7c40beb452046c5ec84e69931ee.zip | |
Fix focusing a minimized window not restoring it
focus_window marked the target focused without clearing minimized, so
a dock icon's Activate (or the plain "focus" IPC command) on a
minimized window left it focused but still excluded from
visible_windows/rendering - reads exactly like the click did nothing,
since the window never actually reappears. Every focus_window caller
gets the restore for free now. Added a Super+n keybind for minimize
too, since none existed at all before this.
Diffstat (limited to 'crates/core')
| -rw-r--r-- | crates/core/src/manager/focus.rs | 16 | ||||
| -rw-r--r-- | crates/core/src/manager/tests.rs | 21 |
2 files changed, 37 insertions, 0 deletions
diff --git a/crates/core/src/manager/focus.rs b/crates/core/src/manager/focus.rs index 6dae20a..f1473cf 100644 --- a/crates/core/src/manager/focus.rs +++ b/crates/core/src/manager/focus.rs @@ -45,6 +45,22 @@ impl WindowManager { if workspace != self.current_workspace { self.switch_workspace(workspace); } + // A minimized window's dock icon (or Alt-Tab entry, or any + // other `focus_window` caller) has to un-minimize it too, not + // just focus it - without this, clicking a minimized app's + // dock icon left it focused (keyboard input, `srd clients`' + // own `focused: true`) while still `minimized: true`, still + // excluded from `visible_windows`/rendering. Reads exactly like + // the click did nothing, since the one visible thing "focused" + // usually implies (the window coming to the front) never + // happens. Every desktop's taskbar/dock has this behavior for + // free; this compositor's `Activate` (zwlr-foreign-toplevel) + // and `"focus"` IPC handlers both route through here already, + // so they get it too rather than each needing their own + // explicit restore call. + if let Some(w) = self.windows.get_mut(&id) { + w.minimized = false; + } self.focused = Some(id); self.raise_window(id); } diff --git a/crates/core/src/manager/tests.rs b/crates/core/src/manager/tests.rs index 1c80304..aa2fb1a 100644 --- a/crates/core/src/manager/tests.rs +++ b/crates/core/src/manager/tests.rs @@ -429,6 +429,27 @@ } #[test] + fn focusing_a_minimized_window_also_restores_it() { + // Regression: `focus_window` marked a window focused without + // clearing `minimized` - a dock icon's click (foreign-toplevel + // `Activate`, or the plain `"focus"` IPC command) both route + // through here, so clicking a minimized app's dock icon left it + // `focused: true` but still `minimized: true`, still excluded from + // `visible_windows`/rendering. Reads exactly like the click did + // nothing, since the window never actually reappears. + let mut wm = wm_with_monitor(); + let id = wm.alloc_window_id(); + wm.add_window(Window::new(id, "a")); + wm.minimize_window(id); + assert!(wm.window(id).unwrap().minimized, "sanity: actually minimized first"); + + wm.focus_window(id); + assert!(!wm.window(id).unwrap().minimized, "focusing a minimized window must restore it"); + assert_eq!(wm.focused_id(), Some(id)); + assert!(wm.visible_windows().any(|w| w.id == id)); + } + + #[test] fn refocusing_an_already_visible_window_does_not_trigger_auto_back_and_forth() { // The fix above must not call `switch_workspace` unconditionally -- // `switch_workspace`'s own `auto_back_and_forth` handling treats |