mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-14 07:46:12 +03:00
macOS: prevent native window drag by top region when titlebar hidden (#2523)
Currently `macos-titlebar-style = hidden` doesn't prevent the native window drag gesture in the top region of the window- in the original PR it did, but there were issues with how it went about it so it was removed (see c6bbdfb). I figured out how to safely and simply remove the gesture, and as a bonus it opens up potential future enhancements. The native window drag region is driven ultimately by the window's `contentLayoutRect`, so we can just override it in `TerminalWindow` to return a rect the size of the full window, disabling the gesture without causing any side effects by altering the responder chain. This makes `macos-titlebar-style = hidden` a much nicer experience. The window can still be resized, managed by the OS and third party window managers, and dragged by the edges, but the native drag gesture in the titlebar region is fully avoided. ### Future work We may consider adjusting this to produce a `contentLayoutRect` that doesn't include the padding area of the terminal grid(s), so that the window can be dragged from a larger region around the edges (and not just the resize region).
This commit is contained in:
@ -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<AnyCancellable> = []
|
||||
@ -318,9 +318,9 @@ class TerminalController: BaseTerminalController {
|
||||
|
||||
// Full size content view so we can extend
|
||||
// content in to the hidden titlebar's area
|
||||
.fullSizeContentView,
|
||||
.fullSizeContentView,
|
||||
|
||||
.resizable,
|
||||
.resizable,
|
||||
.closable,
|
||||
.miniaturizable,
|
||||
]
|
||||
@ -776,7 +776,7 @@ class TerminalController: BaseTerminalController {
|
||||
toggleFullscreen(mode: fullscreenMode)
|
||||
}
|
||||
|
||||
private struct DerivedConfig {
|
||||
struct DerivedConfig {
|
||||
let backgroundColor: Color
|
||||
let macosTitlebarStyle: String
|
||||
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user