From db70d40e43cdcbbb1a7edc10d7491d1de68dce58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leon=20B=C3=B6ttger?= <49094811+leonboe1@users.noreply.github.com> Date: Tue, 19 May 2026 21:29:18 +0200 Subject: [PATCH] Fix clipboard notification occasionally not appearing --- QuickDrop.xcodeproj/project.pbxproj | 4 ++-- QuickDrop/AppDelegate.swift | 7 +++---- .../ClipboardSyncNotificationPresenter.swift | 21 ++++++++++++++++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/QuickDrop.xcodeproj/project.pbxproj b/QuickDrop.xcodeproj/project.pbxproj index 3c78485..bade4de 100644 --- a/QuickDrop.xcodeproj/project.pbxproj +++ b/QuickDrop.xcodeproj/project.pbxproj @@ -1798,7 +1798,7 @@ MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; - SHARED_BUILD = 144; + SHARED_BUILD = 147; SHARED_VERSION = 4.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -1861,7 +1861,7 @@ MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = macosx; - SHARED_BUILD = 144; + SHARED_BUILD = 147; SHARED_VERSION = 4.0; STRING_CATALOG_GENERATE_SYMBOLS = YES; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/QuickDrop/AppDelegate.swift b/QuickDrop/AppDelegate.swift index 191e19e..9f7b916 100644 --- a/QuickDrop/AppDelegate.swift +++ b/QuickDrop/AppDelegate.swift @@ -35,6 +35,8 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele // MARK: NSApplicationDelegate functions func applicationDidFinishLaunching(_: Notification) { + UNUserNotificationCenter.current().delegate = self + // app did not lauch before if !Settings.sharedInstance.appLaunchedBefore { runAfter(seconds: 0.1) { log("[AppDelegate] Opening Welcome Screen") } @@ -66,9 +68,6 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele startReceiving() } - UNUserNotificationCenter.current().delegate = self - - // MARK: Menu Bar let menu = NSMenu() @@ -171,7 +170,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele public func userNotificationCenter(_: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { - if notification.request.identifier == ClipboardSyncNotificationPresenter.notificationIdentifier { + if ClipboardSyncNotificationPresenter.isClipboardSyncNotification(notification) { completionHandler([.banner]) return } diff --git a/QuickDrop/Util/ClipboardSyncNotificationPresenter.swift b/QuickDrop/Util/ClipboardSyncNotificationPresenter.swift index ad48906..95bec36 100644 --- a/QuickDrop/Util/ClipboardSyncNotificationPresenter.swift +++ b/QuickDrop/Util/ClipboardSyncNotificationPresenter.swift @@ -13,14 +13,22 @@ final class ClipboardSyncNotificationPresenter { static let shared = ClipboardSyncNotificationPresenter() static let notificationIdentifier = "quickdrop-clipboard-sync" + private static let notificationIdentifierPrefix = "\(notificationIdentifier)-" private let center = UNUserNotificationCenter.current() private let queue = DispatchQueue(label: "ClipboardSyncNotificationPresenter") private var pendingNotifications: [(String, String?)] = [] private var authorizationRequestInFlight = false + private var postedNotificationIdentifiers: Set = [] private init() {} + static func isClipboardSyncNotification(_ notification: UNNotification) -> Bool { + notification.request.identifier == notificationIdentifier + || notification.request.identifier.hasPrefix(notificationIdentifierPrefix) + || notification.request.content.threadIdentifier == notificationIdentifier + } + func present(clipboardText: String, senderDeviceName: String?) { queue.async { self.postNotificationIfAuthorized( @@ -101,9 +109,12 @@ final class ClipboardSyncNotificationPresenter { content.threadIdentifier = Self.notificationIdentifier content.interruptionLevel = .active - let identifier = Self.notificationIdentifier - center.removePendingNotificationRequests(withIdentifiers: [identifier]) - center.removeDeliveredNotifications(withIdentifiers: [identifier]) + let identifier = Self.makeNotificationIdentifier() + var identifiersToRemove = postedNotificationIdentifiers + identifiersToRemove.insert(Self.notificationIdentifier) + postedNotificationIdentifiers = [identifier] + center.removePendingNotificationRequests(withIdentifiers: Array(identifiersToRemove)) + center.removeDeliveredNotifications(withIdentifiers: Array(identifiersToRemove)) let request = UNNotificationRequest(identifier: identifier, content: content, trigger: nil) center.add(request) { error in @@ -120,6 +131,10 @@ final class ClipboardSyncNotificationPresenter { .replacingOccurrences(of: "\\s+", with: " ", options: .regularExpression) .trimmingCharacters(in: .whitespacesAndNewlines) } + + private static func makeNotificationIdentifier() -> String { + "\(notificationIdentifierPrefix)\(UUID().uuidString)" + } } #endif