macos: apply window position after setting content size (#10007)

> **Note**: This is a re-submission of #9952, which was closed in favor
of #9975. However, as noted in my [comment on
#9975](https://github.com/ghostty-org/ghostty/pull/9975#issuecomment-3677916608),
the issue still persists.

## Summary

- Fix `window-position-x/y` not being applied when `window-width/height`
is also configured

## Problem

When both `window-position-x/y` and `window-width/height` are
configured, the window position was not being applied correctly. The
window would appear near the center of the screen instead of the
specified position.

This worked correctly in v1.2.3 but regressed afterwards.

## Root Cause

This is a regression introduced in c75bade89 (#9747).

The commit refactored the default size logic from a computed `NSRect?`
property to a `DefaultSize` enum with `.frame` and
`.contentIntrinsicSize` cases.

**Before (working):**
```swift
private var defaultSize: NSRect? {
    // ... calculate frame ...
    return adjustForWindowPosition(frame: frame, on: screen)  // ← position was applied
}
```

**After (broken):**
```swift
enum DefaultSize {
    case frame(NSRect)
    case contentIntrinsicSize
    
    func apply(to window: NSWindow) {
        case .contentIntrinsicSize:
            window.setContentSize(size)
            window.constrainToScreen()
            // ← adjustForWindowPosition call was lost
    }
}
```

When `window-width/height` is configured, the `.contentIntrinsicSize`
case is used. This case only called `setContentSize` and
`constrainToScreen`, but did not apply the window position adjustment.

## Why This Fix is Correct

`DefaultSize.apply()` is intentionally **not** responsible for
position—it only handles **size**:

1. `apply()` is also called from `returnToDefaultSize(_:)` menu action
2. When user triggers "Return to Default Size", only the **size** should
reset—**not the position**
3. If we added position logic inside `apply()`, the window would
unexpectedly jump back to its initial position

Therefore, position adjustment belongs **outside** of `apply()`,
specifically during initial window setup in `windowDidLoad`.

## Fix

Call `adjustForWindowPosition` after applying the content intrinsic size
to ensure the window position is correctly set during initial window
creation.
This commit is contained in:
Mitchell Hashimoto
2025-12-23 07:08:16 -08:00
committed by GitHub

View File

@@ -952,9 +952,13 @@ class TerminalController: BaseTerminalController, TabGroupCloseCoordinator.Contr
case .contentIntrinsicSize:
// Content intrinsic size requires a short delay so that AppKit
// can layout our SwiftUI views.
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(10_000)) { [weak window] in
guard let window else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + .microseconds(10_000)) { [weak self, weak window] in
guard let self, let window else { return }
defaultSize.apply(to: window)
if let screen = window.screen ?? NSScreen.main {
let frame = self.adjustForWindowPosition(frame: window.frame, on: screen)
window.setFrameOrigin(frame.origin)
}
}
}
}