Repository navigation
Conversation
constrainFrameRect recenters the window vertically when it shrinks from taller than the visible frame of its screen to shorter than it, to counter the 'snap to top' behaviour. the new origin was calculated as (vf.height - nf.height) / 2, which is only correct for a screen whose visible frame starts at y = 0, i.e. the main screen. every other check in this function uses screen relative coordinates (vf.maxY, vf.minY). on any other screen the window was moved to the main screen's coordinate range instead, usually onto a different display. since the top bound check clamps the window to its new screen's visible frame, it could not be moved back by programmatic frame changes afterwards (e.g. window managers using the accessibility API) and had to be dragged back manually. example, with a screen stacked two screens above the main one: visible frame: y = 3600 (cocoa coordinates), height = 1800 window resized from 1824 to 1530 height before: origin.y = (1800 - 1530) / 2 = 135, window on the main screen after: origin.y = 3600 + (1800 - 1530) / 2 = 3735, window stays reproduce on a multi monitor setup: place a window on a screen other than the main one, make it taller than that screen's visible frame and then set a frame shorter than it via the accessibility API (e.g. Hammerspoon's hs.window:setFrame). fix this by offsetting the recentered origin by the visible frame's minY.
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.
constrainFrameRectrecenters the window vertically when it shrinks from taller than its screen's visible frame to shorter than it. The new origin was(vf.height - nf.height) / 2, which is only correct for a screen whose visible frame starts at y = 0 (the main screen). All other checks in the function are screen relative.On any other screen the window jumps to the main screen's coordinate range, usually a different display. The top bound check then clamps it to that new screen, so programmatic frame changes (e.g. window managers via the accessibility API) cannot move it back.
Example, screen stacked two screens above the main one (visible frame y = 3600, height = 1800), window resized from 1824 to 1530 height:
To reproduce: on a multi monitor setup, place a window on a non-main screen, make it taller than that screen's visible frame, then set a shorter frame via the accessibility API (e.g. Hammerspoon
hs.window:setFrame).Fix: offset the recentered origin by
vf.minY.