Conversation
The mouse fence keeps the pointer off the Edge, but nothing stopped an application from placing a window there: Safari or the Finder restoring a frame saved before the Edge was plugged in, or a display rearranged under windows that were where they belonged. The kiosk covers that display above the status-bar level, so a window that arrives there is focused, holds the keyboard, and is invisible. Nothing on screen says it exists, and the pointer cannot reach it, which is the same trap AdminPlacement was written for, from the other side. A two-second sweep reads the window list, which costs one call and no round trip to any application, and hands anything of somebody else's that overlaps the Edge to AdminPlacement, the geometry the admin window already uses, then moves it there. The Accessibility API is reached only for an application that actually has a window on the Edge, which is almost never. Three moves per window is the limit: an application that puts its window straight back would otherwise be fought forever, twice a second, with the window flickering between two displays. It rides on the existing fence switch rather than adding one, since it is the same promise for the pointer and for windows, and the menu entry is renamed from "Mouse fence" to "Edge fence" to say so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mcouzinet
force-pushed
the
window-fence
branch
from
September 25, 2026 13:50
2530a28 to
0efb040
Compare
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.
The mouse fence keeps the pointer off the Edge, but nothing stops an application from placing a window there, which is how it actually happens. It happened to me twice today: a Safari window and a Finder window, both restored to a frame saved before the Edge was plugged in. The kiosk covers that display above the status-bar level, so the window was focused, held the keyboard, and was invisible. Nothing on screen says it exists, the pointer cannot reach it, and Mission Control shows the kiosk. I got the Finder one back with
tell application "Finder" to set bounds of window 1 to ..., which is not a thing to ask of anybody.Same trap
AdminPlacementwas written for, from the other side, so this reuses it rather than growing new geometry.How it works.
WindowFencesweeps every two seconds: oneCGWindowListCopyWindowInfocall, no round trip to any application, no permission. Anything of somebody else's on layer 0 overlapping the Edge goes toAdminPlacement.rescue, and only then is the Accessibility API reached, for that one application, to setkAXPosition(andkAXSizewhen the window is wider than the display it is moved to). So the steady-state cost is one list read every two seconds, and AX traffic only when there is something to rescue, which is almost never.Choices worth a look.
fenceconfig flag and toggle rather than adding a second switch: the promise is the same for the pointer and for windows. The menu entry is renamed Mouse fence to Edge fence. Easy to split if you would rather have two.AdminPlacement.isUsablealready gives: a straddling window has the part you read on the side you cannot see.Checked.
scripts/test-helper.shgreen (85 tests, 9 new onWindowSweep, listed in the shim registry) andscripts/build-helper.shbuilds the bundle. The geometry was verified by hand on my Edge (a Finder window at x -1740 came back to the main display keeping its size). What I could not exercise here is the AX move from inside a running helper: this machine has no "Fremkit Helper Dev" identity in the keychain, so a local install would be ad-hoc signed and would drop the Accessibility and Input Monitoring grants of the helper that is running. Worth a try on a machine set up for it before merging.🤖 Generated with Claude Code