initial window size needs to take into account window chrome

This commit is contained in:
Mitchell Hashimoto
2023-09-30 21:35:50 -07:00
parent cc8e1cd936
commit a1a8aeb104
6 changed files with 97 additions and 87 deletions

View File

@@ -71,7 +71,6 @@ extension Ghostty {
// We use these notifications to determine when the window our surface is
// attached to is or is not focused.
let pubBecomeFocused = NotificationCenter.default.publisher(for: Notification.didBecomeFocusedSurface, object: surfaceView)
let pubInitialFrame = NotificationCenter.default.publisher(for: Notification.didReceiveInitialWindowFrame, object: surfaceView)
let pubBecomeKey = NotificationCenter.default.publisher(for: NSWindow.didBecomeKeyNotification)
let pubResign = NotificationCenter.default.publisher(for: NSWindow.didResignKeyNotification)
@@ -101,26 +100,6 @@ extension Ghostty {
surfaceFocus = true
}
}
.onReceive(pubInitialFrame) { notification in
// We never set the initial frame if we're a split
guard !isSplit else { return }
// We need a window to set the frame
guard let surfaceWindow = surfaceView.window else { return }
guard let frameAny = notification.userInfo?[Ghostty.Notification.FrameKey] else { return }
guard let frame = frameAny as? NSRect else { return }
// If we have tabs, then do not change the window size
guard let windowControllerRaw = surfaceWindow.windowController else { return }
guard let windowController = windowControllerRaw as? PrimaryWindowController else { return }
guard !windowController.didInitializeFromSurface else { return }
// We have no tabs and we are not a split, so set the initial size of the window.
surfaceWindow.setFrame(frame, display: true)
// Note that we did initialize
windowController.didInitializeFromSurface = true
}
.onAppear() {
// Welcome to the SwiftUI bug house of horrors. On macOS 12 (at least
// 12.5.1, didn't test other versions), the order in which the view
@@ -213,6 +192,10 @@ extension Ghostty {
// to the app level and it is set from there.
@Published var title: String = "👻"
// An initial size to request for a window. This will only affect
// then the view is moved to a new window.
var initialSize: NSSize? = nil
private(set) var surface: ghostty_surface_t?
var error: Error? = nil
@@ -429,27 +412,39 @@ extension Ghostty {
// If we have a blur, set the blur
ghostty_set_window_background_blur(surface, Unmanaged.passUnretained(window).toOpaque())
// Set the window size
let rect = ghostty_surface_window_frame(surface)
if (rect.size || rect.origin) {
var frame = window.frame
if (rect.origin) {
frame.origin.x = Double(rect.x)
frame.origin.y = Double(rect.y)
}
if (rect.size) {
frame.size.width = Double(rect.w)
frame.size.height = Double(rect.h)
}
NotificationCenter.default.post(
name: Notification.didReceiveInitialWindowFrame,
object: self,
userInfo: [
Notification.FrameKey: frame,
]
)
}
// Try to set the initial window size if we have one
setInitialWindowSize()
}
/// Sets the initial window size requested by the Ghostty config.
///
/// This only works under certain conditions:
/// - The window must be "uninitialized"
/// - The window must have no tabs
/// - Ghostty must have requested an initial size
///
private func setInitialWindowSize() {
guard let initialSize = initialSize else { return }
// If we have tabs, then do not change the window size
guard let window = self.window else { return }
guard let windowControllerRaw = window.windowController else { return }
guard let windowController = windowControllerRaw as? PrimaryWindowController else { return }
guard !windowController.didInitializeFromSurface else { return }
// Setup our frame. We need to first subtract the views frame so that we can
// just get the chrome frame so that we only affect the surface view size.
var frame = window.frame
frame.size.width -= self.frame.size.width
frame.size.height -= self.frame.size.height
frame.size.width += initialSize.width
frame.size.height += initialSize.height
// We have no tabs and we are not a split, so set the initial size of the window.
window.setFrame(frame, display: true)
// Note that we did initialize
windowController.didInitializeFromSurface = true
}
override func becomeFirstResponder() -> Bool {