From f6511b482d81c79c05cbc2c782b5362ae8beb537 Mon Sep 17 00:00:00 2001 From: Alvie Stoddard Date: Fri, 24 Jul 2026 14:16:45 -0700 Subject: [PATCH 1/2] Show bar when Pesty is reopened --- Sources/Pesty/AppController.swift | 32 +++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Sources/Pesty/AppController.swift b/Sources/Pesty/AppController.swift index ee649f5..e9ccfcf 100644 --- a/Sources/Pesty/AppController.swift +++ b/Sources/Pesty/AppController.swift @@ -13,6 +13,7 @@ final class AppController: NSObject, NSApplicationDelegate { private var statusItem: NSStatusItem? private var settingsWindow: NSWindow? private var keyMonitor: Any? + private var isReopenPresentationPending = false private(set) var previousApp: NSRunningApplication? private(set) var lastActiveApp: NSRunningApplication? @@ -51,6 +52,33 @@ final class AppController: NSObject, NSApplicationDelegate { } } + func applicationShouldHandleReopen(_ sender: NSApplication, + hasVisibleWindows flag: Bool) -> Bool { + // Finder, Spotlight, and the Dock send a reopen event when the user + // invokes an app that is already running. The clipboard bar is an + // NSPanel, so AppKit's `hasVisibleWindows` value does not reliably + // describe whether Pesty already has a surface on screen. + guard !hasVisiblePestySurface else { return true } + guard !isReopenPresentationPending else { return false } + + isReopenPresentationPending = true + DispatchQueue.main.async { [weak self] in + guard let self else { return } + self.isReopenPresentationPending = false + + // A window can appear while AppKit finishes the reopen event + // (for example, during onboarding). Avoid presenting a second + // Pesty surface in that case. + guard !self.hasVisiblePestySurface else { return } + self.showBar() + } + return false + } + + private var hasVisiblePestySurface: Bool { + NSApp.windows.contains { $0.isVisible && !$0.isMiniaturized } + } + @objc private func appActivated(_ note: Notification) { guard let app = note.userInfo?[NSWorkspace.applicationUserInfoKey] as? NSRunningApplication else { return } if app.bundleIdentifier != Bundle.main.bundleIdentifier { @@ -133,6 +161,10 @@ final class AppController: NSObject, NSApplicationDelegate { let front = NSWorkspace.shared.frontmostApplication if front?.bundleIdentifier != Bundle.main.bundleIdentifier { previousApp = front + } else if let lastActiveApp, !lastActiveApp.isTerminated { + // Reopen events arrive after Pesty becomes active, so retain the + // most recently active non-Pesty app as the eventual paste target. + previousApp = lastActiveApp } store.searchText = "" store.source = .history From 9ca0a90506d0962cdd2bac4c9c895d89f73eb7f7 Mon Sep 17 00:00:00 2001 From: Alvie Stoddard Date: Fri, 24 Jul 2026 20:58:37 -0700 Subject: [PATCH 2/2] Show Paste Bar on launch and reopen --- Sources/Pesty/AppController.swift | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Sources/Pesty/AppController.swift b/Sources/Pesty/AppController.swift index e9ccfcf..66b38ef 100644 --- a/Sources/Pesty/AppController.swift +++ b/Sources/Pesty/AppController.swift @@ -44,12 +44,14 @@ final class AppController: NSObject, NSApplicationDelegate { return } + // Pesty's primary interface should be immediately discoverable after + // every normal launch, including the first launch after quitting. if !Settings.shared.onboarded { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) { [weak self] in - self?.showSettings() - } Settings.shared.onboarded = true } + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in + self?.showBar() + } } func applicationShouldHandleReopen(_ sender: NSApplication, @@ -58,7 +60,9 @@ final class AppController: NSObject, NSApplicationDelegate { // invokes an app that is already running. The clipboard bar is an // NSPanel, so AppKit's `hasVisibleWindows` value does not reliably // describe whether Pesty already has a surface on screen. - guard !hasVisiblePestySurface else { return true } + // Settings and previews are secondary surfaces. Only an already + // visible Paste Bar should suppress a new presentation. + guard !isBarVisible else { return true } guard !isReopenPresentationPending else { return false } isReopenPresentationPending = true @@ -66,17 +70,16 @@ final class AppController: NSObject, NSApplicationDelegate { guard let self else { return } self.isReopenPresentationPending = false - // A window can appear while AppKit finishes the reopen event - // (for example, during onboarding). Avoid presenting a second - // Pesty surface in that case. - guard !self.hasVisiblePestySurface else { return } + // A duplicate reopen event can arrive while AppKit finishes the + // first one. Avoid presenting the Paste Bar twice. + guard !self.isBarVisible else { return } self.showBar() } return false } - private var hasVisiblePestySurface: Bool { - NSApp.windows.contains { $0.isVisible && !$0.isMiniaturized } + private var isBarVisible: Bool { + barController?.window?.isVisible == true } @objc private func appActivated(_ note: Notification) {