diff --git a/src/Wm.zig b/src/Wm.zig index cd7b31c..a5b9902 100644 --- a/src/Wm.zig +++ b/src/Wm.zig @@ -449,6 +449,7 @@ fn onWmEvent(_: *river.WindowManagerV1, event: river.WindowManagerV1.Event, self }, .session_unlocked => { self.locked = false; + for (self.seats.items) |seat| self.restoreFocus(seat); self.ipcDirty(); }, @@ -811,6 +812,25 @@ fn validateFocus(self: *Wm, seat: *Seat) void { } } +/// Put the keyboard back where it was before the session locked. +/// +/// While locked the lock surface holds focus and river drops it again on +/// unlock, but our own `focused` never changed — nothing looks stale, so +/// `validateFocus` sees no work and no focus request is ever made. The seat +/// then sits there with no window focused until the user clicks one. Re-issue +/// the focus, falling back the way `validateFocus` does if that window went +/// away while the screen was locked. +fn restoreFocus(self: *Wm, seat: *Seat) void { + if (seat.focused) |win| { + if (!win.closed and win.visible) { + seat.focus(win); + return; + } + } + const out = seat.currentOutput() orelse return; + if (self.topVisible(out)) |win| seat.focus(win); +} + /// View a set of tags, on whichever screen owns them. /// /// With the tag set split across displays, `Mod+7` is as much "go to the screen