From c384cd050e747579b78c738a09061e1815c5c46a Mon Sep 17 00:00:00 2001 From: Martin Emde Date: Thu, 1 Jan 2026 15:27:26 -0800 Subject: [PATCH] Fix Mac window becomes unmovable after pane rearrangement After rearranging panes, the window becomes permanently unmovable. Grab handles temporarily set `window.isMovable = false` on hover to prevent window dragging from interfering with pane dragging. Override `viewWillMove(toWindow:)` to catch when the view is being removed from the window. This lifecycle method is called before the window reference becomes nil, allowing us to restore `window.isMovable`. --- .../Surface View/SurfaceDragSource.swift | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/macos/Sources/Ghostty/Surface View/SurfaceDragSource.swift b/macos/Sources/Ghostty/Surface View/SurfaceDragSource.swift index 059428b15..37a69852e 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceDragSource.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceDragSource.swift @@ -105,22 +105,30 @@ extension Ghostty { /// Whether the current drag was cancelled by pressing escape. private var dragCancelledByEscape: Bool = false - /// Original value of `window.isMovable` to restore - /// when the mouse exits. - private var isWindowMovable: Bool? - deinit { if let escapeMonitor { NSEvent.removeMonitor(escapeMonitor) } } - + + override func acceptsFirstMouse(for event: NSEvent?) -> Bool { + // Ensure this view gets the mouse event before window dragging handlers + return true + } + + override func mouseDown(with event: NSEvent) { + // Consume the mouseDown event to prevent it from propagating to the + // window's drag handler. This fixes issue #10110 where grab handles + // would drag the window instead of initiating pane drags. + // Don't call super - the drag will be initiated in mouseDragged. + } + override func updateTrackingAreas() { super.updateTrackingAreas() - + // To update our tracking area we just recreate it all. trackingAreas.forEach { removeTrackingArea($0) } - + // Add our tracking area for mouse events addTrackingArea(NSTrackingArea( rect: bounds, @@ -135,18 +143,10 @@ extension Ghostty { } override func mouseEntered(with event: NSEvent) { - // Temporarily disable `isMovable` to fix - // https://github.com/ghostty-org/ghostty/issues/10110 - isWindowMovable = window?.isMovable - window?.isMovable = false onHoverChanged?(true) } override func mouseExited(with event: NSEvent) { - if let isWindowMovable { - window?.isMovable = isWindowMovable - self.isWindowMovable = nil - } onHoverChanged?(false) } @@ -237,7 +237,7 @@ extension Ghostty { NSEvent.removeMonitor(escapeMonitor) self.escapeMonitor = nil } - + if operation == [] && !dragCancelledByEscape { let endsInWindow = NSApplication.shared.windows.contains { window in window.isVisible && window.frame.contains(screenPoint) @@ -250,7 +250,7 @@ extension Ghostty { ) } } - + isTracking = false onDragStateChanged?(false) }