Fix window position restore on relaunch (#2129)

* test: cover accessible window frame restore

* fix: preserve accessible window frame on relaunch
This commit is contained in:
Austin Wang 2026-03-25 02:05:13 -07:00 committed by GitHub
parent da70f3fa47
commit 0ea16b12c2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 69 additions and 0 deletions

View file

@ -3066,6 +3066,15 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
minHeight: CGFloat
) -> CGRect {
if targetDisplay.visibleFrame.intersects(frame) {
// Preserve the user's exact frame when enough of the top of the window
// remains reachable on-screen; only clamp when the saved frame would
// reopen with an inaccessible titlebar/top strip.
if shouldPreserveAccessibleFrame(
frame: frame,
targetDisplay: targetDisplay
) {
return frame
}
return clampFrame(
frame,
within: targetDisplay.visibleFrame,
@ -3092,6 +3101,38 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
)
}
private nonisolated static func shouldPreserveAccessibleFrame(
frame: CGRect,
targetDisplay: SessionDisplayGeometry,
minimumVisibleTopStripWidth: CGFloat = 120,
topStripHeight: CGFloat = 64,
minimumVisibleTopStripHeight: CGFloat = 24
) -> Bool {
let standardizedFrame = frame.standardized
guard standardizedFrame.width.isFinite,
standardizedFrame.height.isFinite,
standardizedFrame.width > 0,
standardizedFrame.height > 0,
standardizedFrame.intersects(targetDisplay.frame) else {
return false
}
let stripHeight = min(topStripHeight, standardizedFrame.height)
let topStrip = CGRect(
x: standardizedFrame.minX,
y: standardizedFrame.maxY - stripHeight,
width: standardizedFrame.width,
height: stripHeight
)
let visibleTopStrip = topStrip.intersection(targetDisplay.visibleFrame)
guard !visibleTopStrip.isNull else { return false }
let requiredWidth = min(minimumVisibleTopStripWidth, standardizedFrame.width)
let requiredHeight = min(minimumVisibleTopStripHeight, stripHeight)
return visibleTopStrip.width >= requiredWidth
&& visibleTopStrip.height >= requiredHeight
}
private nonisolated static func display(
for snapshot: SessionDisplaySnapshot?,
in displays: [SessionDisplayGeometry]

View file

@ -693,6 +693,34 @@ final class SessionPersistenceTests: XCTestCase {
XCTAssertEqual(restored.height, 1_410, accuracy: 0.001)
}
func testResolvedWindowFramePreservesExactGeometryWhenDisplayChangesButWindowRemainsAccessible() {
let savedFrame = SessionRectSnapshot(x: 1_100, y: -20, width: 1_280, height: 1_000)
let savedDisplay = SessionDisplaySnapshot(
displayID: 2,
frame: SessionRectSnapshot(x: 0, y: 0, width: 2_560, height: 1_440),
visibleFrame: SessionRectSnapshot(x: 0, y: 0, width: 2_560, height: 1_410)
)
let adjustedDisplay = AppDelegate.SessionDisplayGeometry(
displayID: 2,
frame: CGRect(x: 0, y: 0, width: 2_560, height: 1_440),
visibleFrame: CGRect(x: 0, y: 40, width: 2_560, height: 1_360)
)
let restored = AppDelegate.resolvedWindowFrame(
from: savedFrame,
display: savedDisplay,
availableDisplays: [adjustedDisplay],
fallbackDisplay: adjustedDisplay
)
XCTAssertNotNil(restored)
guard let restored else { return }
XCTAssertEqual(restored.minX, 1_100, accuracy: 0.001)
XCTAssertEqual(restored.minY, -20, accuracy: 0.001)
XCTAssertEqual(restored.width, 1_280, accuracy: 0.001)
XCTAssertEqual(restored.height, 1_000, accuracy: 0.001)
}
func testResolvedWindowFrameClampsWhenDisplayGeometryChangesEvenWithSameDisplayID() {
let savedFrame = SessionRectSnapshot(x: 1_303, y: -90, width: 1_280, height: 1_410)
let savedDisplay = SessionDisplaySnapshot(