Fix Cmd+P/Cmd+Shift+P window routing (#413)
* Fix command palette shortcuts to stay window-scoped * Fix cross-window command palette typing focus lock
This commit is contained in:
parent
04eee73a22
commit
710ed9b068
3 changed files with 191 additions and 11 deletions
|
|
@ -760,6 +760,9 @@ private final class WindowCommandPaletteOverlayController: NSObject {
|
|||
private weak var installedThemeFrame: NSView?
|
||||
private var focusLockTimer: DispatchSourceTimer?
|
||||
private var scheduledFocusWorkItem: DispatchWorkItem?
|
||||
private var isPaletteVisible = false
|
||||
private var windowDidBecomeKeyObserver: NSObjectProtocol?
|
||||
private var windowDidResignKeyObserver: NSObjectProtocol?
|
||||
|
||||
init(window: NSWindow) {
|
||||
self.window = window
|
||||
|
|
@ -782,6 +785,7 @@ private final class WindowCommandPaletteOverlayController: NSObject {
|
|||
hostingView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
|
||||
])
|
||||
_ = ensureInstalled()
|
||||
installWindowKeyObservers()
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
|
@ -913,6 +917,52 @@ private final class WindowCommandPaletteOverlayController: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
private func installWindowKeyObservers() {
|
||||
guard let window else { return }
|
||||
windowDidBecomeKeyObserver = NotificationCenter.default.addObserver(
|
||||
forName: NSWindow.didBecomeKeyNotification,
|
||||
object: window,
|
||||
queue: .main
|
||||
) { [weak self] _ in
|
||||
Task { @MainActor [weak self] in
|
||||
self?.updateFocusLockForWindowState()
|
||||
}
|
||||
}
|
||||
windowDidResignKeyObserver = NotificationCenter.default.addObserver(
|
||||
forName: NSWindow.didResignKeyNotification,
|
||||
object: window,
|
||||
queue: .main
|
||||
) { [weak self] _ in
|
||||
Task { @MainActor [weak self] in
|
||||
self?.updateFocusLockForWindowState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func updateFocusLockForWindowState() {
|
||||
guard let window else {
|
||||
stopFocusLockTimer()
|
||||
return
|
||||
}
|
||||
guard isPaletteVisible else {
|
||||
stopFocusLockTimer()
|
||||
return
|
||||
}
|
||||
|
||||
guard window.isKeyWindow else {
|
||||
stopFocusLockTimer()
|
||||
if isPaletteResponder(window.firstResponder) {
|
||||
_ = window.makeFirstResponder(nil)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
startFocusLockTimer()
|
||||
if !isPaletteTextInputFirstResponder(window.firstResponder) {
|
||||
scheduleFocusIntoPalette(retries: 8)
|
||||
}
|
||||
}
|
||||
|
||||
private func startFocusLockTimer() {
|
||||
guard focusLockTimer == nil else { return }
|
||||
let timer = DispatchSource.makeTimerSource(queue: .main)
|
||||
|
|
@ -959,6 +1009,7 @@ private final class WindowCommandPaletteOverlayController: NSObject {
|
|||
|
||||
func update(rootView: AnyView, isVisible: Bool) {
|
||||
guard ensureInstalled() else { return }
|
||||
isPaletteVisible = isVisible
|
||||
if isVisible {
|
||||
hostingView.rootView = rootView
|
||||
containerView.capturesMouseEvents = true
|
||||
|
|
@ -967,10 +1018,7 @@ private final class WindowCommandPaletteOverlayController: NSObject {
|
|||
if let themeFrame = installedThemeFrame, themeFrame.subviews.last !== containerView {
|
||||
themeFrame.addSubview(containerView, positioned: .above, relativeTo: nil)
|
||||
}
|
||||
startFocusLockTimer()
|
||||
if let window, !isPaletteTextInputFirstResponder(window.firstResponder) {
|
||||
scheduleFocusIntoPalette(retries: 8)
|
||||
}
|
||||
updateFocusLockForWindowState()
|
||||
} else {
|
||||
stopFocusLockTimer()
|
||||
if let window, isPaletteResponder(window.firstResponder) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue