feat: add Combined Display Mode#1763
Conversation
Add a setting to treat multiple monitors as a single virtual display, so window actions (half, center, maximize, corners, etc.) operate across all connected monitors at once. Settings window: "Treat multiple monitors as one" checkbox with description, separated by a divider line from other options. Localized via NSLocalizedString with Korean translation in Main.xcstrings. When enabled: - All window calculations receive a combined bounding frame of all monitors - BestEffortWindowMover uses the combined frame to avoid single-screen clamping - Left/Right half, Center, CenterProminently respect the combined frame - Next/Previous Display menu items are hidden Implementation: - Defaults.combinedDisplayMode (BoolDefault) persists the setting - WindowCalculationParameters carries combinedDisplayFrame: CGRect? - WindowManager computes the union of all screen visible frames when enabled Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Thanks for contributing! I actually implemented this in Rectangle Pro and simply didn't have time yet to test it thoroughly, officially release it, and port it to Rectangle. When I implemented it, I had simply adjusted the NSScreen extension in ScreenDetection to have this: func adjustedVisibleFrame(_ ignoreTodo: Bool = false, _ ignoreStage: Bool = false) -> CGRect {
var newFrame = visibleFrame
if !NSScreen.screensHaveSeparateSpaces && Defaults.combinedDisplayMode.enabled {
newFrame = NSScreen.screens.reduce(CGRect.null) { $0.union($1.visibleFrame) }
}
...That avoided touching the WindowManager and other specific calculation files. There might be a reason why Claude took your path instead, but off the top of my head I'm not sure what it would be. Would you mind swapping out your implementation here with this and seeing if it does what you expect? |
Per maintainer feedback, compute the union of all screens inside adjustedVisibleFrame so every calculation picks it up automatically without threading a combinedDisplayFrame parameter through WindowCalculationParameters and each individual calculation file. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ents When combined display mode is active, return the union immediately so stage strip, todo sidebar, and screen edge gap adjustments (all derived from self, a single NSScreen) are not incorrectly applied to the multi-screen combined frame. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Per maintainer feedback, compute the union of all screens inside adjustedVisibleFrame so every calculation picks it up automatically. Early return after the union to avoid incorrectly applying per-screen adjustments (stage strip, todo sidebar, edge gaps) to the combined frame. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rxhanson I'll be honest, I didn't fully understand the background behind the original implementation, which is probably why it ended up going a different direction. Swapped it out and it works as expected. One small difference though: I used return instead of assigning to newFrame: if !NSScreen.screensHaveSeparateSpaces && Defaults.combinedDisplayMode.enabled { If we assign and continue, the rest of the function — Stage Manager strip, Todo sidebar, screen edge gaps — all apply based on self (a single NSScreen) to what is now a multi-screen union. The Todo sidebar width is calculated from self.visibleFrame.width but gets subtracted from the full combined width, which seemed off. |
|
Great! I'll test this out soon and will plan on merging if nothing else comes up. |

Summary
Settings
A new checkbox is added to the Settings window under the display-related options, separated by a divider:
Localized via
NSLocalizedStringwith Korean translation inMain.xcstrings.When enabled, the Next/Previous Display menu items are hidden.
Implementation
Defaults.combinedDisplayMode(BoolDefault) persists the settingWindowCalculationParameterscarries an optionalcombinedDisplayFrame: CGRect?WindowManagercomputes the union of all screen visible frames and passes it through the calculation pipelineCenterCalculation,CenterProminentlyCalculation, andLeftRightHalfCalculationupdated to respect the combined frameBestEffortWindowMoverreceives the combined frame asvisibleFrameOfDestinationScreento prevent single-screen clampingTest plan
🤖 Generated with Claude Code