Moving a window to another screen unexpectedly changes its size
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 11.6k
- Forks
- 270
- Avg merge
- 8h 7m
- Merged PRs (30d)
- 3
Description
Bug Description
When moving an existing window to another screen using Loop's screen-switching actions, the window's size changes unexpectedly.
This appears to happen because Loop preserves the window frame as a percentage of the current screen's usable bounds, then applies that percentage to the destination screen. On displays with different resolutions, scaling, visible frame sizes, menu bar / Dock availability, or padding, this changes the actual window size in points.
Steps To Reproduce
- Use a Mac with multiple displays whose usable screen frames differ.
- Put a normal resizable window on one display.
- Trigger a Loop screen-switching action such as
Next Screen,Previous Screen,Top Screen, orBottom Screen. - Observe the window after it moves to the destination display.
Expected Behavior
Moving a window to another screen should preserve the window's current size in points. The position can be remapped or clamped to fit the destination screen, but the width and height should not be recalculated from the destination screen's dimensions.
Actual Behavior
The window is moved to the destination screen, but its width and/or height changes. For example, moving from a larger usable screen area to a smaller one makes the window smaller; moving in the opposite direction makes it larger.
Technical Notes
I checked Loop 1.4.2 and the current develop branch. The behavior seems to come from the screen-switching path in LoopManager.swift.
When newAction.direction.willChangeScreen is true and the current action is .noSelection or manipulates an existing frame, Loop computes:
let proportionalSize = CGRect(
x: (currentFrame.minX - adjustedBounds.minX) / adjustedBounds.width,
y: (currentFrame.minY - adjustedBounds.minY) / adjustedBounds.height,
width: currentFrame.width / adjustedBounds.width,
height: currentFrame.height / adjustedBounds.height
)
Then it creates an autogenerated custom action with:
unit: .percentage,
width: proportionalSize.width * 100,
height: proportionalSize.height * 100,
xPoint: proportionalSize.minX * 100,
yPoint: proportionalSize.minY * 100,
positionMode: .coordinates,
sizeMode: .custom
Later, custom percentage actions are resolved against the destination screen bounds, so the size changes when the destination bounds differ.
A possible fix would be to preserve currentFrame.width and currentFrame.height in points for screen-switching actions, map the origin or center to the destination screen, and only clamp the final origin to keep the window on-screen.
macOS Version
macOS 26.5.1 (25F80)
Loop Version
1.4.2 (1693)
Additional Context
This is specifically about moving the same window to another display. It is not about focus-only actions such as Focus Left, Focus Right, or Focus Next in Stack.
Final Checks
- My issue is written in English
- My issue title is descriptive
- This is a single bug (multiple bugs should be reported individually)
- I can help with testing a fix
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in LoopManager.swift at the screen-switching path guarded by newAction.direction.willChangeScreen, especially the autogenerated percentage action. Reproduce the behavior with displays having different usable frames and compare the window dimensions before and after moving it. Done means screen-switching actions preserve the current width and height in points while keeping the window visible on the destination display.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100