diff --git a/Sources/DSFQuickActionBar/DSFQuickActionBar.swift b/Sources/DSFQuickActionBar/DSFQuickActionBar.swift index 54730f2..dd7b0ae 100644 --- a/Sources/DSFQuickActionBar/DSFQuickActionBar.swift +++ b/Sources/DSFQuickActionBar/DSFQuickActionBar.swift @@ -147,8 +147,22 @@ public extension DSFQuickActionBar { quickBarWindow.placeholderText = placeholderText ?? "" quickBarWindow.didDetectClose = { [weak self] in - self?.quickBarController = nil - self?.onCloseCallback?() + guard + let self = self, + let window = self.quickActionBarWindow + else { + return + } + + // If the user hasn't activated an item, call the didCancel() delegate if it is present + if window.userDidActivateItem == false { + self.contentSource?.quickActionBarDidCancel(self) + } + + self.quickBarController = nil + + // Call the close callback + self.onCloseCallback?() } // Make sure that the application is frontmost or else the quick action bar won't display (it cannot be diff --git a/Sources/DSFQuickActionBar/private/DSFQuickActionBar+ResultsView.swift b/Sources/DSFQuickActionBar/private/DSFQuickActionBar+ResultsView.swift index dc675ef..0517291 100644 --- a/Sources/DSFQuickActionBar/private/DSFQuickActionBar+ResultsView.swift +++ b/Sources/DSFQuickActionBar/private/DSFQuickActionBar+ResultsView.swift @@ -33,6 +33,11 @@ extension DSFQuickActionBar { private let tableView = DSFQuickActionBar.ResultsTableView() private let horizontalView = NSBox() + // The parent window + var quickActionBarWindow: DSFQuickActionBar.Window? { + self.window as? DSFQuickActionBar.Window + } + // The parent var quickActionBar: DSFQuickActionBar! @@ -284,6 +289,10 @@ extension DSFQuickActionBar.ResultsView { return false } + // Mark that the user activated an item in the list + self.quickActionBarWindow?.userDidActivateItem = true + + // Tell the delegate that the user selected an item self.quickActionBar.contentSource?.quickActionBar(self.quickActionBar, didActivateItem: which.key) // Close the bar @@ -307,10 +316,13 @@ extension DSFQuickActionBar.ResultsView { return } + // Mark that the user has activated an item in the list + self.quickActionBarWindow?.userDidActivateItem = true + let itemIdentifier = self.identifiers[selectedRow] self.quickActionBar.contentSource?.quickActionBar(self.quickActionBar, didActivateItem: itemIdentifier) - // If the row is double-clicked, close the bar + // Make the bar lose focus, which will trigger it to close. self.window?.resignMain() } diff --git a/Sources/DSFQuickActionBar/private/DSFQuickActionBar+Window.swift b/Sources/DSFQuickActionBar/private/DSFQuickActionBar+Window.swift index 41f8d0a..eb3e72d 100644 --- a/Sources/DSFQuickActionBar/private/DSFQuickActionBar+Window.swift +++ b/Sources/DSFQuickActionBar/private/DSFQuickActionBar+Window.swift @@ -154,6 +154,9 @@ extension DSFQuickActionBar { return r }() + + // Is set to true when the user 'activates' an item in the result list + internal var userDidActivateItem: Bool = false } } @@ -227,7 +230,7 @@ internal extension DSFQuickActionBar.Window { extension DSFQuickActionBar.Window { // Called when the user presses 'escape' when the window is present override func cancelOperation(_: Any?) { - self.quickActionBar.contentSource?.quickActionBarDidCancel(self.quickActionBar) + // Tell the window to lose its initial responder status, which will close it. self.resignMain() }