From a06350df9b077a0aa82657ecff22e7fb0d620faf Mon Sep 17 00:00:00 2001 From: Lukas <134181853+bo2themax@users.noreply.github.com> Date: Sat, 28 Mar 2026 21:02:59 +0100 Subject: [PATCH] macOS: close search bar if needed when it loses focus This adds features like: 1. Clicking outside of SearchBar works like typing `escape` 2. Typing `tab` while search bar is focused also works like typing `escape` --- .../Ghostty/Surface View/SurfaceView.swift | 19 +++++++++++++------ .../Surface View/SurfaceView_AppKit.swift | 7 +++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView.swift b/macos/Sources/Ghostty/Surface View/SurfaceView.swift index 47503dc0e..8036f944d 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView.swift @@ -437,11 +437,10 @@ extension Ghostty { } } #if canImport(AppKit) - .onExitCommand { - if searchState.needle.isEmpty { - onClose() - } else { - Ghostty.moveFocus(to: surfaceView) + .onExitCommand(perform: onResignFirstResponder) + .onChange(of: isSearchFieldFocused) { newValue in + if !newValue { + onResignFirstResponder() } } #endif @@ -520,7 +519,15 @@ extension Ghostty { ) } } - +#if canImport(AppKit) + private func onResignFirstResponder() { + if searchState.needle.isEmpty { + onClose() + } else { + Ghostty.moveFocus(to: surfaceView) + } + } +#endif private var clipShape: some Shape { if #available(iOS 26.0, macOS 26.0, *) { return ConcentricRectangle(corners: .concentric(minimum: 8), isUniform: true) diff --git a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift index 8f4fb01cf..dc39f1051 100644 --- a/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift +++ b/macos/Sources/Ghostty/Surface View/SurfaceView_AppKit.swift @@ -660,6 +660,13 @@ extension Ghostty { return event } + guard searchState == nil else { + // We don't want to process events that + // are supposed to be handled by SearchOverlay + // When clicking outside, SurfaceView will become first responder automatically + return event + } + // We only want to process events that are on this window. guard let window, event.window != nil,