From 2c6dd5940688643604f82cd50fd426a463e78d56 Mon Sep 17 00:00:00 2001 From: Lukas <134181853+bo2themax@users.noreply.github.com> Date: Sun, 19 Apr 2026 23:13:40 +0200 Subject: [PATCH] macOS: fix render_thread "stuck" after dragging surface to another tab within the same window The reason the thread is stuck is because the surface's occlusion state is set to invisible after target tab's activate while dragging, since the dragged surface is still in previous tree before dropping, and after dropping the occlusion state of this surface is not updated to visible, which causing the surface is accepting input but not rendering. --- .../Features/Terminal/BaseTerminalController.swift | 8 +++++++- .../Sources/Ghostty/Surface View/SurfaceView_AppKit.swift | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/macos/Sources/Features/Terminal/BaseTerminalController.swift b/macos/Sources/Features/Terminal/BaseTerminalController.swift index 9454b1f86..273d9733f 100644 --- a/macos/Sources/Features/Terminal/BaseTerminalController.swift +++ b/macos/Sources/Features/Terminal/BaseTerminalController.swift @@ -292,6 +292,7 @@ class BaseTerminalController: NSWindowController, if to.isEmpty { focusedSurface = nil } + syncSurfaceTreeOcclusionState() } /// Update all surfaces with the focus state. This ensures that libghostty has an accurate view about @@ -1256,10 +1257,15 @@ class BaseTerminalController: NSWindowController, } func windowDidChangeOcclusionState(_ notification: Notification) { + syncSurfaceTreeOcclusionState() + } + + private func syncSurfaceTreeOcclusionState() { let visible = self.window?.occlusionState.contains(.visible) ?? false for view in surfaceTree { - if let surface = view.surface { + if let surface = view.surface, view.isWindowVisible != visible { ghostty_surface_set_occlusion(surface, visible) + view.isWindowVisible = visible } } } diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift index b1920f170..887482b30 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift @@ -89,6 +89,12 @@ extension Ghostty { // Whether the cursor is currently visible (not hidden by typing, etc.) @Published private(set) var cursorVisible: Bool = true + /// Whether the belonging window is visible + /// + /// We track this to restore surface occlusion state + /// after this surface is dragged to another window + var isWindowVisible = false + /// The configuration derived from the Ghostty config so we don't need to rely on references. @Published private(set) var derivedConfig: DerivedConfig