macos: quick terminal restores previous size when exiting final surface (#7543)

This fixes a regression from the new split work last week, but it was
also probably an issue before that in a slightly different way.

With the new split work, the quick terminal was becoming unusable when
the final surface explicitly `exit`-ed, because AppKit/SwiftUI would
resize the window to a very small size and you couldn't see the new
terminal on the next toggle.

Prior to this, I think the quick terminal would've reverted to its
original size but I'm not sure (even if the user resized it manually).

This commit saves the size of the quick terminal at the point all
surfaces are exited and restores it when the quick terminal is shown the
next time with a new initial surface.
This commit is contained in:
Mitchell Hashimoto
2025-06-07 12:46:04 -07:00
committed by GitHub

View File

@@ -21,6 +21,14 @@ class QuickTerminalController: BaseTerminalController {
// The active space when the quick terminal was last shown.
private var previousActiveSpace: CGSSpace? = nil
/// The window frame saved when the quick terminal's surface tree becomes empty.
///
/// This preserves the user's window size and position when all terminal surfaces
/// are closed (e.g., via the `exit` command). When a new surface is created,
/// the window will be restored to this frame, preventing SwiftUI from resetting
/// the window to its default minimum size.
private var lastClosedFrame: NSRect? = nil
/// Non-nil if we have hidden dock state.
private var hiddenDock: HiddenDock? = nil
@@ -190,6 +198,12 @@ class QuickTerminalController: BaseTerminalController {
// If our surface tree is nil then we animate the window out.
if (to.isEmpty) {
// Save the current window frame before animating out. This preserves
// the user's preferred window size and position for when the quick
// terminal is reactivated with a new surface. Without this, SwiftUI
// would reset the window to its minimum content size.
lastClosedFrame = window?.frame
animateOut()
}
}
@@ -230,9 +244,6 @@ class QuickTerminalController: BaseTerminalController {
// Set previous active space
self.previousActiveSpace = CGSSpace.active()
// Animate the window in
animateWindowIn(window: window, from: position)
// If our surface tree is empty then we initialize a new terminal. The surface
// tree can be empty if for example we run "exit" in the terminal and force
// animate out.
@@ -241,7 +252,16 @@ class QuickTerminalController: BaseTerminalController {
let view = Ghostty.SurfaceView(ghostty_app, baseConfig: nil)
surfaceTree = SplitTree(view: view)
focusedSurface = view
// Restore our previous frame if we have one
if let lastClosedFrame {
window.setFrame(lastClosedFrame, display: false)
self.lastClosedFrame = nil
}
}
// Animate the window in
animateWindowIn(window: window, from: position)
}
func animateOut() {