Skip to content

Restore full-width windows after the idle screensaver - #11277

Open
physikal wants to merge 10 commits into
omacom:quattrofrom
physikal:fix/screensaver-preserve-fullwidth
Open

Restore full-width windows after the idle screensaver#11277
physikal wants to merge 10 commits into
omacom:quattrofrom
physikal:fix/screensaver-preserve-fullwidth

Conversation

@physikal

@physikal physikal commented Sep 11, 2026

Copy link
Copy Markdown

Summary

Idle AFK lock was leaving maximized / full-width windows tiled after unlock, while a manual lock did not. The difference is the idle screensaver: it maps as a real Hyprland client (org.omarchy.screensaver) in compositor fullscreen, which demotes any full-width window underneath. Lock then kills the screensaver without putting that state back.

This PR snapshots non-screensaver fullscreen modes before the screensaver launches and restores them when it exits or when lock kills it. Screensaver visuals stay as they are today.

Why not other approaches

Float/pin overlay instead of compositor fullscreen. Hyprland can raise a floating window over a maximized one without demoting it, so in theory we could cover the monitor without fullscreen = true. We did not take that path here because it changes how the screensaver covers the screen (bar / reserved areas / focus behavior) and we did not want to trade a layout bug for a visual/UX change in the same PR. Preventing demotion at the window-rule layer is still a reasonable follow-up if someone wants to delete the snapshot helper.

Layer-shell / Quickshell overlay (best long-term). The cleanest architecture is for the screensaver not to be a real client window at all — same family as the lock/menu overlays. That never touches tiling. It is not a small refactor of this bug: today's screensaver is a terminal running ttfx (ASCII branding + random effects), one instance per monitor, with idle tracking keyed on Hyprland openwindow/closewindow for org.omarchy.screensaver, dismiss-on-input, force-start from the menu, and lock's pkill of those terminals. Moving to a layer means reimplementing or embedding that experience and rewiring idle. Worth doing as its own project; out of scope for restoring full-width after idle.

Snapshot/restore (this PR). Compensates at the screensaver lifecycle instead of rewriting the screensaver. Small, testable, keeps current visuals, and matches the failure mode (demotion on map, missing restore on exit/lock).

Security

No security change. The screensaver is cosmetic idle UI; authentication remains the Wayland session lock. This only restores layout state the screensaver cleared as a side effect.

Test plan

  • ./test/shell.d/hyprland-fullscreen-snapshot-test.sh
  • ./test/shell.d/system-lock-test.sh
  • Full width (Super + Alt + F) → force Screensaver from the menu → dismiss — stays full width (verified on a live install of these scripts)
  • Full width → idle screensaver → lock → unlock — stays full width
  • Manual lock/unlock still blanks the display and unlocks normally

The screensaver used compositor fullscreen mode, which demotes any maximized
window underneath. Idle lock then killed the screensaver without restoring
that state, so unlock left people tiled. Cover the monitor as a floating
overlay instead; session lock remains the security boundary.
@physikal physikal changed the title Preserve full-width windows across the idle screensaver Restore full-width windows after the idle screensaver Sep 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant