diff --git a/macos/Sources/Features/Terminal/TerminalRestorable.swift b/macos/Sources/Features/Terminal/TerminalRestorable.swift index 84ec53316..c80818b0a 100644 --- a/macos/Sources/Features/Terminal/TerminalRestorable.swift +++ b/macos/Sources/Features/Terminal/TerminalRestorable.swift @@ -101,11 +101,23 @@ class TerminalWindowRestoration: NSObject, NSWindowRestoration { /// This restores the focus state of the surfaceview within the given window. When restoring, /// the view isn't immediately attached to the window since we have to wait for SwiftUI to /// catch up. Therefore, we sit in an async loop waiting for the attachment to happen. - private static func restoreFocus(to: Ghostty.SurfaceView, inWindow: NSWindow) { - DispatchQueue.main.async { + private static func restoreFocus(to: Ghostty.SurfaceView, inWindow: NSWindow, attempts: Int = 0) { + // For the first attempt, we schedule it immediately. Subsequent events wait a bit + // so we don't just spin the CPU at 100%. Give up after some period of time. + let after: DispatchTime + if (attempts == 0) { + after = .now() + } else if (attempts > 40) { + // 2 seconds, give up + return + } else { + after = .now() + .milliseconds(50) + } + + DispatchQueue.main.asyncAfter(deadline: after) { // If the view is not attached to a window yet then we repeat. guard let viewWindow = to.window else { - restoreFocus(to: to, inWindow: inWindow) + restoreFocus(to: to, inWindow: inWindow, attempts: attempts + 1) return }