diff --git a/macos/Sources/Ghostty/Ghostty.Config.swift b/macos/Sources/Ghostty/Ghostty.Config.swift index d7134029d..cb4b4b415 100644 --- a/macos/Sources/Ghostty/Ghostty.Config.swift +++ b/macos/Sources/Ghostty/Ghostty.Config.swift @@ -274,6 +274,16 @@ extension Ghostty { return v } + var dragHandle: DragHandle { + let defaultValue = DragHandle.auto + guard let config = self.config else { return defaultValue } + var v: UnsafePointer? + let key = "drag-handle" + guard ghostty_config_get(config, &v, key, UInt(key.lengthOfBytes(using: .utf8))) else { return defaultValue } + guard let ptr = v else { return defaultValue } + return DragHandle(rawValue: String(cString: ptr)) ?? defaultValue + } + /// Returns the fullscreen mode if fullscreen is enabled, or nil if disabled. /// This parses the `fullscreen` enum config which supports both /// native and non-native fullscreen modes. @@ -933,4 +943,8 @@ extension Ghostty.Config { static let `default` = MacOSTitlebarStyle.transparent case native, transparent, tabs, hidden } + + enum DragHandle: String { + case always, auto, never + } } diff --git a/macos/Sources/Ghostty/Surface View/SurfaceGrabHandle.swift b/macos/Sources/Ghostty/Surface View/SurfaceGrabHandle.swift index c5ab84124..95c170528 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceGrabHandle.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceGrabHandle.swift @@ -10,11 +10,20 @@ extension Ghostty { private static let hoverHeightFactor: CGFloat = 0.2 @ObservedObject var surfaceView: SurfaceView + let dragHandle: Ghostty.Config.DragHandle @State private var isHovering: Bool = false @State private var isDragging: Bool = false private var handleVisible: Bool { + switch dragHandle { + case .always: + return true + case .never: + return false + case .auto: + break + } // Handle should always be visible in non-fullscreen guard let window = surfaceView.window else { return true } guard window.styleMask.contains(.fullScreen) else { return true } @@ -25,6 +34,14 @@ extension Ghostty { } private var ellipsisVisible: Bool { + switch dragHandle { + case .always: + return true + case .never: + return false + case .auto: + break + } // If the cursor isn't visible, never show the handle guard surfaceView.cursorVisible else { return false } // If we're hovering or actively dragging, always visible diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView.swift b/macos/Sources/Ghostty/Surface View/SurfaceView.swift index cda77884d..887c7cf86 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView.swift @@ -205,7 +205,10 @@ extension Ghostty { // top Z-index os it isn't faded by the unfocused overlay. // // This is disabled except on macOS because it uses AppKit drag/drop APIs. - SurfaceGrabHandle(surfaceView: surfaceView) + SurfaceGrabHandle( + surfaceView: surfaceView, + dragHandle: ghostty.config.dragHandle, + ) #endif } } diff --git a/src/config/Config.zig b/src/config/Config.zig index b96300d14..475f97960 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -2356,8 +2356,13 @@ keybind: Keybinds = .{}, /// /// - `auto` *(default)* /// -/// Automatically show and hide the drag handle. The handle is only -/// shown when there are two or more splits present. +/// Automatically show and hide the drag handle. +/// +/// On Linux, the handle is only shown when there are two or +/// more splits present. +/// +/// On macOS, the handle is only hidden when there's one split +/// in **fullscreen** mode, otherwise it's shown when hovered. /// /// - `never` /// @@ -2365,8 +2370,6 @@ keybind: Keybinds = .{}, /// mouse controls. /// /// Available since: 1.4.0. -/// -/// Currently only supported on Linux (GTK). @"drag-handle": DragHandle = .auto, /// This controls when resize overlays are shown. Resize overlays are a