feat: every window goes back after a display change - #115
Merged
Merged
Conversation
ostapondo
force-pushed
the
feat/desk-snapshot
branch
from
August 26, 2026 10:33
7de4cda to
4d607d5
Compare
DeskWatcher notes where every window on screen sits, per set of attached displays: each window Plonk places the moment it is placed, and the whole desk by one AX walk on its own queue whenever the window server says something has moved, folded into what was known so a window on another Space keeps its place. When that set of displays comes back the desk is put back first, off the main queue with one announcement, then the zone placements cover what the desk had no note of. Off, and forgotten, when the display-change switch or the Zones module is off. A second switch under When the desktop changes, on by default.
ostapondo
force-pushed
the
feat/desk-snapshot
branch
from
August 26, 2026 10:56
4d607d5 to
bccd60d
Compare
# Conflicts: # CHANGELOG.md # docs/zones.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed, and why
Plonk put its own placements back after a display change and left every other window scrambled. Now
DeskWatcherkeeps a note of where every window on screen sits, per set of attached displays. A window Plonk places (hotkey, drop, grab, API, workspace) is noted the moment it is placed. The rest comes from one AX walk on its own queue, and only when a one-call look at the window server says something has moved since the last note, so an idle desk costs nothing. Each walk is folded into what was known, so a window on another Space keeps its place. A walk that a display change or a switch-off overtakes lands on nothing.When that set of displays comes back the desk is put back first, on its own queue so it never waits behind a stale walk, skipping windows already where the note says, with one change-bus announcement for all of it. Then the zone placements cover only what the desk had no note of, so a window is never moved twice and a hand move after a snap is what wins. A second display change mid-restore stops the first restore where it is.
New switch under "When the desktop changes", on by default; it widens the existing display-change switch and is put away when that one is off.
Confighas the one predicate all three readers use. Off, or with the Zones module off, the timer stops and the desks are forgotten. Apps on the exceptions list are filtered on the main queue before a walk, so the walk never reads the config. Memory only: an AX element does not survive a relaunch and neither does the scramble.What you ran
Checks
swift buildpasses on every commit in the branchDeskMemoryTests(per-desk keys, replace, note, clear, merging a walk, what a walk notes and skips, the fraction round trip, the switches)If this moves windows
Setup: macOS 26, one built-in display at 2x.
restoreDeskgoes through the samemayTouchcheck as the zone placements.