Work around strange SwiftUI behavior in "older" macOSen. (might fix #7690) (#8026)

The Quick Terminal would not appear anymore, as somewhere in the
framework the Quick Terminal Window's geometry gets corrupted when the
window is added to the UI.

This works around by caching the windows geometry and reusing it
afterwards

This might fix #7690
pull/8352/head
Mitchell Hashimoto 2025-08-22 09:31:11 -07:00 committed by GitHub
commit 3859f50b88
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 30 additions and 0 deletions

View File

@ -111,12 +111,27 @@ class QuickTerminalController: BaseTerminalController {
// Setup our initial size based on our configured position // Setup our initial size based on our configured position
position.setLoaded(window) position.setLoaded(window)
// Upon first adding this Window to its host view, older SwiftUI
// seems to have a "hiccup" and corrupts the frameRect,
// sometimes setting the size to zero, sometimes corrupting it.
// We pass the actual window's frame as "initial" frame directly
// to the window, so it can use that instead of the frameworks
// "interpretation"
if let qtWindow = window as? QuickTerminalWindow {
qtWindow.initialFrame = window.frame
}
// Setup our content // Setup our content
window.contentView = NSHostingView(rootView: TerminalView( window.contentView = NSHostingView(rootView: TerminalView(
ghostty: self.ghostty, ghostty: self.ghostty,
viewModel: self, viewModel: self,
delegate: self delegate: self
)) ))
// Clear out our frame at this point, the fixup from above is complete.
if let qtWindow = window as? QuickTerminalWindow {
qtWindow.initialFrame = nil
}
// Animate the window in // Animate the window in
animateIn() animateIn()

View File

@ -29,4 +29,19 @@ class QuickTerminalWindow: NSPanel {
// We don't want to activate the owning app when quick terminal is triggered. // We don't want to activate the owning app when quick terminal is triggered.
self.styleMask.insert(.nonactivatingPanel) self.styleMask.insert(.nonactivatingPanel)
} }
/// This is set to the frame prior to setting `contentView`. This is purely a hack to workaround
/// bugs in older macOS versions (Ventura): https://github.com/ghostty-org/ghostty/pull/8026
var initialFrame: NSRect? = nil
override func setFrame(_ frameRect: NSRect, display flag: Bool) {
// Upon first adding this Window to its host view, older SwiftUI
// seems to have a "hiccup" and corrupts the frameRect,
// sometimes setting the size to zero, sometimes corrupting it.
// If we find we have cached the "initial" frame, use that instead
// the propagated one through the framework
//
// https://github.com/ghostty-org/ghostty/pull/8026
super.setFrame(initialFrame ?? frameRect, display: flag)
}
} }