Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 38 additions & 3 deletions Sources/Pesty/AppController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -43,12 +44,42 @@ 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,
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.
// 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
DispatchQueue.main.async { [weak self] in
guard let self else { return }
self.isReopenPresentationPending = false

// 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 isBarVisible: Bool {
barController?.window?.isVisible == true
}

@objc private func appActivated(_ note: Notification) {
Expand Down Expand Up @@ -133,6 +164,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
Expand Down