mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-15 16:26:08 +03:00
76 lines
2.8 KiB
Swift
76 lines
2.8 KiB
Swift
import AppKit
|
|
|
|
/// The base class for all standalone, "normal" terminal windows. This sets the basic
|
|
/// style and configuration of the window based on the app configuration.
|
|
class TerminalWindow: NSWindow {
|
|
/// This is the key in UserDefaults to use for the default `level` value. This is
|
|
/// used by the manual float on top menu item feature.
|
|
static let defaultLevelKey: String = "TerminalDefaultLevel"
|
|
|
|
// MARK: NSWindow Overrides
|
|
|
|
override func awakeFromNib() {
|
|
guard let appDelegate = NSApp.delegate as? AppDelegate else { return }
|
|
|
|
// All new windows are based on the app config at the time of creation.
|
|
let config = appDelegate.ghostty.config
|
|
|
|
// If window decorations are disabled, remove our title
|
|
if (!config.windowDecorations) { styleMask.remove(.titled) }
|
|
|
|
// Set our window positioning to coordinates if config value exists, otherwise
|
|
// fallback to original centering behavior
|
|
setInitialWindowPosition(
|
|
x: config.windowPositionX,
|
|
y: config.windowPositionY,
|
|
windowDecorations: config.windowDecorations)
|
|
|
|
// If our traffic buttons should be hidden, then hide them
|
|
if config.macosWindowButtons == .hidden {
|
|
hideWindowButtons()
|
|
}
|
|
|
|
// Get our saved level
|
|
level = UserDefaults.standard.value(forKey: Self.defaultLevelKey) as? NSWindow.Level ?? .normal
|
|
}
|
|
|
|
// Both of these must be true for windows without decorations to be able to
|
|
// still become key/main and receive events.
|
|
override var canBecomeKey: Bool { return true }
|
|
override var canBecomeMain: Bool { return true }
|
|
|
|
// MARK: Positioning And Styling
|
|
|
|
/// This is called by the controller when there is a need to reset the window apperance.
|
|
func syncAppearance(_ surfaceConfig: Ghostty.SurfaceView.DerivedConfig) {}
|
|
|
|
private func setInitialWindowPosition(x: Int16?, y: Int16?, windowDecorations: Bool) {
|
|
// If we don't have an X/Y then we try to use the previously saved window pos.
|
|
guard let x, let y else {
|
|
if (!LastWindowPosition.shared.restore(self)) {
|
|
center()
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// Prefer the screen our window is being placed on otherwise our primary screen.
|
|
guard let screen = screen ?? NSScreen.screens.first else {
|
|
center()
|
|
return
|
|
}
|
|
|
|
// Orient based on the top left of the primary monitor
|
|
let frame = screen.visibleFrame
|
|
setFrameOrigin(.init(
|
|
x: frame.minX + CGFloat(x),
|
|
y: frame.maxY - (CGFloat(y) + frame.height)))
|
|
}
|
|
|
|
private func hideWindowButtons() {
|
|
standardWindowButton(.closeButton)?.isHidden = true
|
|
standardWindowButton(.miniaturizeButton)?.isHidden = true
|
|
standardWindowButton(.zoomButton)?.isHidden = true
|
|
}
|
|
}
|