Fix command palette focus after terminal find (#2089)

* test: cover command palette focus guard

* fix: block terminal find from stealing palette focus

* test: cover text view focus-stealer fallback

* Add regression for hidden DevTools sync republish loop

* Avoid redundant DevTools visibility publishes

* test: cover browser find focus after workspace round-trip

* fix: restore browser find focus after workspace round-trip

* fix: keep browser find caret on workspace return

* Add workspace round-trip split find regressions

* Keep inactive find overlays from stealing focus

---------

Co-authored-by: Lawrence Chen <lawrencecchen@users.noreply.github.com>
This commit is contained in:
Lawrence Chen 2026-03-25 17:27:54 -07:00 committed by GitHub
parent b42f64fbe3
commit 8a3ab6b3f0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 402 additions and 59 deletions

View file

@ -37,6 +37,38 @@ private enum CmuxThemeNotifications {
static let reloadConfig = Notification.Name("com.cmuxterm.themes.reload-config")
}
func isCommandPaletteFocusStealingTerminalOrBrowserResponder(_ responder: NSResponder) -> Bool {
if responder is GhosttyNSView || responder is WKWebView {
return true
}
if let textView = responder as? NSTextView,
!textView.isFieldEditor,
let delegateView = textView.delegate as? NSView {
return isCommandPaletteFocusStealingTerminalOrBrowserView(delegateView)
}
if let view = responder as? NSView {
return isCommandPaletteFocusStealingTerminalOrBrowserView(view)
}
return false
}
func isCommandPaletteFocusStealingTerminalOrBrowserView(_ view: NSView) -> Bool {
if view is GhosttyNSView || view is GhosttySurfaceScrollView || view is WKWebView {
return true
}
var current: NSView? = view.superview
while let candidate = current {
if candidate is GhosttyNSView || candidate is GhosttySurfaceScrollView || candidate is WKWebView {
return true
}
current = candidate.superview
}
return false
}
#if DEBUG
enum CmuxTypingTiming {
static let isEnabled: Bool = {
@ -4656,35 +4688,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
}
private func isFocusStealingResponderWhileCommandPaletteVisible(_ responder: NSResponder) -> Bool {
if responder is GhosttyNSView || responder is WKWebView {
return true
}
if let textView = responder as? NSTextView,
!textView.isFieldEditor,
let delegateView = textView.delegate as? NSView {
return isTerminalOrBrowserView(delegateView)
}
if let view = responder as? NSView {
return isTerminalOrBrowserView(view)
}
return false
}
private func isTerminalOrBrowserView(_ view: NSView) -> Bool {
if view is GhosttyNSView || view is WKWebView {
return true
}
var current: NSView? = view.superview
while let candidate = current {
if candidate is GhosttyNSView || candidate is WKWebView {
return true
}
current = candidate.superview
}
return false
isCommandPaletteFocusStealingTerminalOrBrowserResponder(responder)
}
private func isInsideCommandPaletteOverlay(_ view: NSView) -> Bool {