From 307ded6129cffa9a29c6ef4a7a73aad9ba2217c8 Mon Sep 17 00:00:00 2001 From: momenbasel Date: Wed, 12 Aug 2026 08:43:17 +0300 Subject: [PATCH] Scope the bar key monitor to its own panel and resolve the paste target robustly Two infrastructure fixes extracted from #42: - The local key monitor now ignores events destined for any window other than the bar panel, so typing into the Rename / Create Pinboard alerts (and any future editor or Settings surface shown while the bar is up) reaches that window instead of being swallowed into search. - Pasting resolves its target through lastActiveApp -> previousApp -> frontmost, skipping Pesty itself and terminated apps. previousApp is only captured inside showBar(), so the menu-bar and reopen paths used to paste into a stale target. showBar() also keeps lastActiveApp in sync when it captures the frontmost app. Co-authored-by: Alvie Stoddard Co-authored-by: Cursor --- Sources/Pesty/AppController.swift | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/Sources/Pesty/AppController.swift b/Sources/Pesty/AppController.swift index f9ce410..b82830b 100644 --- a/Sources/Pesty/AppController.swift +++ b/Sources/Pesty/AppController.swift @@ -206,8 +206,9 @@ final class AppController: NSObject, NSApplicationDelegate { func showBar() { let front = NSWorkspace.shared.frontmostApplication - if front?.bundleIdentifier != Bundle.main.bundleIdentifier { + if let front, !isPesty(front) { previousApp = front + lastActiveApp = front } store.searchText = "" store.source = .history @@ -229,13 +230,28 @@ final class AppController: NSObject, NSApplicationDelegate { func pasteSelected() { guard let item = store.selectedItem else { return } - hideBar() - PasteService.paste(item, into: previousApp, monitor: monitor) + pasteItem(item) + } + + /// The app that will receive a paste after the floating Pesty panel closes. + /// `previousApp` is captured before the panel activates, while + /// `lastActiveApp` covers menu-bar and reopen paths where it is unavailable. + private var pasteTarget: NSRunningApplication? { + [lastActiveApp, previousApp, NSWorkspace.shared.frontmostApplication] + .compactMap { $0 } + .first { !$0.isTerminated && !isPesty($0) } + } + + private func isPesty(_ app: NSRunningApplication) -> Bool { + if app.processIdentifier == ProcessInfo.processInfo.processIdentifier { return true } + guard let bundleID = Bundle.main.bundleIdentifier else { return false } + return app.bundleIdentifier == bundleID } func pasteItem(_ item: ClipItem) { + let target = pasteTarget hideBar() - PasteService.paste(item, into: previousApp, monitor: monitor) + PasteService.paste(item, into: target, monitor: monitor) } func copyItem(_ item: ClipItem) { @@ -296,6 +312,11 @@ final class AppController: NSObject, NSApplicationDelegate { } private func handleKey(_ event: NSEvent) -> NSEvent? { + // Events belonging to a native context menu, editor, alert, or the + // Settings window must stay with their own responder chain. The bar + // monitor is only responsible for keys delivered to the panel itself. + guard event.window === barController?.window else { return event } + if handleBarCommandShortcut(event) { return nil } let code = Int(event.keyCode)