diff --git a/macos/Sources/Features/Terminal/TerminalController.swift b/macos/Sources/Features/Terminal/TerminalController.swift index 89da6bfeb..f24261b9b 100644 --- a/macos/Sources/Features/Terminal/TerminalController.swift +++ b/macos/Sources/Features/Terminal/TerminalController.swift @@ -22,7 +22,7 @@ class TerminalController: BaseTerminalController { private var restorable: Bool = true /// The configuration derived from the Ghostty config so we don't need to rely on references. - private var derivedConfig: DerivedConfig + private(set) var derivedConfig: DerivedConfig /// The notification cancellable for focused surface property changes. private var surfaceAppearanceCancellables: Set = [] @@ -315,28 +315,28 @@ class TerminalController: BaseTerminalController { window.styleMask = [ // We need `titled` in the mask to get the normal window frame .titled, - + // Full size content view so we can extend // content in to the hidden titlebar's area - .fullSizeContentView, - - .resizable, + .fullSizeContentView, + + .resizable, .closable, .miniaturizable, ] - + // Hide the title window.titleVisibility = .hidden window.titlebarAppearsTransparent = true - + // Hide the traffic lights (window control buttons) window.standardWindowButton(.closeButton)?.isHidden = true window.standardWindowButton(.miniaturizeButton)?.isHidden = true window.standardWindowButton(.zoomButton)?.isHidden = true - + // Disallow tabbing if the titlebar is hidden, since that will (should) also hide the tab bar. window.tabbingMode = .disallowed - + // Nuke it from orbit -- hide the titlebar container entirely, just in case. There are // some operations that appear to bring back the titlebar visibility so this ensures // it is gone forever. @@ -345,7 +345,7 @@ class TerminalController: BaseTerminalController { titleBarContainer.isHidden = true } } - + override func windowDidLoad() { super.windowDidLoad() guard let window = window as? TerminalWindow else { return } @@ -776,7 +776,7 @@ class TerminalController: BaseTerminalController { toggleFullscreen(mode: fullscreenMode) } - private struct DerivedConfig { + struct DerivedConfig { let backgroundColor: Color let macosTitlebarStyle: String diff --git a/macos/Sources/Features/Terminal/TerminalWindow.swift b/macos/Sources/Features/Terminal/TerminalWindow.swift index 0eb8daeeb..9d29c193f 100644 --- a/macos/Sources/Features/Terminal/TerminalWindow.swift +++ b/macos/Sources/Features/Terminal/TerminalWindow.swift @@ -115,6 +115,21 @@ class TerminalWindow: NSWindow { } } + // We override this so that with the hidden titlebar style the titlebar + // area is not draggable. + override var contentLayoutRect: CGRect { + var rect = super.contentLayoutRect + + // If we are using a hidden titlebar style, the content layout is the + // full frame making it so that it is not draggable. + if let controller = windowController as? TerminalController, + controller.derivedConfig.macosTitlebarStyle == "hidden" { + rect.origin.y = 0 + rect.size.height = self.frame.height + } + return rect + } + // The window theme configuration from Ghostty. This is used to control some // behaviors that don't look quite right in certain situations. var windowTheme: TerminalWindowTheme? diff --git a/src/config/Config.zig b/src/config/Config.zig index fd0f58669..e32a3485f 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1816,9 +1816,12 @@ keybind: Keybinds = .{}, /// The "hidden" style hides the titlebar. Unlike `window-decoration = false`, /// however, it does not remove the frame from the window or cause it to have /// squared corners. Changing to or from this option at run-time may affect -/// existing windows in buggy ways. The top titlebar area of the window will -/// continue to drag the window around and you will not be able to use -/// the mouse for terminal events in this space. +/// existing windows in buggy ways. +/// +/// When "hidden", the top titlebar area can no longer be used for dragging +/// the window. To drag the window, you can use option+click on the resizable +/// areas of the frame to drag the window. This is a standard macOS behavior +/// and not something Ghostty enables. /// /// The default value is "transparent". This is an opinionated choice /// but its one I think is the most aesthetically pleasing and works in