diff options
| author | srdusr <[email protected]> | 2024-11-30 23:03:00 +0200 |
|---|---|---|
| committer | srdusr <[email protected]> | 2024-11-30 23:03:00 +0200 |
| commit | 583063c3094ca0cf9f6cceba92d710b238547f6b (patch) | |
| tree | a1ff8f181027892f4a45846b67898beb136a9312 /crates/core/src/manager/focus.rs | |
| parent | 87f5c04b2593dc49409644e69e7962b73d26b9d8 (diff) | |
| download | srdwm-583063c3094ca0cf9f6cceba92d710b238547f6b.tar.gz srdwm-583063c3094ca0cf9f6cceba92d710b238547f6b.zip | |
Accumulate core-crate additions: capture requests, focus/workspace fixes, test coverage
Bundles several related changes to crates/core built up over this
session rather than committed incrementally:
- WindowManager::request_capture_workspace/drain_capture_requests (new
manager/capture.rs) - backend-agnostic queuing for an off-screen
workspace render, see the wayland-side commit for why this exists.
- focus_window now switches workspace as a side effect when the target
isn't on the current one, matching Hyprland's focuswindow convention
(manager/focus.rs).
- Assorted window/rules/theme field additions and their test coverage.
Left less granular than the repo's usual one-purpose-per-commit
convention deliberately: these accumulated across a long session
without being committed as they landed, and are too entangled
line-by-line to safely split apart now without risking mis-attributing
changes to the wrong commit message.
Diffstat (limited to 'crates/core/src/manager/focus.rs')
| -rw-r--r-- | crates/core/src/manager/focus.rs | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/crates/core/src/manager/focus.rs b/crates/core/src/manager/focus.rs index c281d7c..6dae20a 100644 --- a/crates/core/src/manager/focus.rs +++ b/crates/core/src/manager/focus.rs @@ -17,7 +17,34 @@ impl WindowManager { } pub fn focus_window(&mut self, id: WindowId) { - if self.windows.contains_key(&id) { + if let Some(workspace) = self.windows.get(&id).map(|w| w.workspace) { + // Switch to the target's workspace first if it isn't already + // the active one - without this, focusing a window elsewhere + // (Alt-Tab, a dock icon, anything that ends up calling this) + // marked it focused while leaving it genuinely off-screen: + // `visible_windows`/rendering both gate on `workspace == + // current_workspace`, so keyboard focus landed on a window the + // user could not see, while whatever was actually on screen + // kept looking focused-ish. Reported live (relayed from the + // AGS peer session, who measured it directly over IPC): + // `srd dispatch focus` on a window from a different workspace + // left `current_workspace` unchanged and the target `visible: + // false`. Every caller of `focus_window` gets this for free + // rather than each one remembering to switch workspaces + // itself first - matches the convention the AGS shell was + // already built against (Hyprland's `focuswindow` switches + // workspace as a side effect of focusing). Guarded on + // `w.workspace != self.current_workspace` specifically, not + // just always calling `switch_workspace`: that function's own + // `auto_back_and_forth` handling treats being asked to + // "switch" to the *already*-current workspace as a deliberate + // toggle-to-previous gesture, which an ordinary redundant + // focus call (the common case: re-focusing whatever is + // already focused and already visible) must not trigger as a + // surprise workspace jump. + if workspace != self.current_workspace { + self.switch_workspace(workspace); + } self.focused = Some(id); self.raise_window(id); } |