Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Prevent NSPopover from stealing an NSTextField’s focus when using the popover to display live search results. Swift adaption of Wil Shipley’s solution (https://stackoverflow.com/a/21111462)
protocol PopoverFirstResponderStealingSuppression {
var suppressFirstResponderWhenPopoverShows: Bool { get }
}
class CustomDocumentWindow: NSWindow {
override func makeFirstResponder(_ responder: NSResponder?) -> Bool {
if responder != self.firstResponder,
let newFirstResponder = responder as? NSView {
let newFirstResponderWindow = newFirstResponder.window
let currentFirstResponder = self.firstResponder
var currentFirstResponderWindow: NSWindow
if let currentFirstResponder = currentFirstResponder as? NSWindow {
currentFirstResponderWindow = currentFirstResponder
} else if let currentFirstResponder = currentFirstResponder as? NSView,
let window = currentFirstResponder.window {
currentFirstResponderWindow = window
} else {
return super.makeFirstResponder(newFirstResponder)
}
if newFirstResponderWindow != self
&& newFirstResponderWindow != currentFirstResponderWindow
&& self.currentEvent?.window != newFirstResponderWindow {
var responderView: NSResponder? = newFirstResponder
while responderView != nil {
if let responderView = responderView as? PopoverFirstResponderStealingSuppression,
responderView.suppressFirstResponderWhenPopoverShows {
return false
}
responderView = (responderView as? NSView)?.superview
}
}
}
return super.makeFirstResponder(responder)
}
}
@frankrausch

This comment has been minimized.

Copy link
Owner Author

@frankrausch frankrausch commented Mar 31, 2018

The NSWindow containing the NSTextField (or NSSearchField) must be subclassed as CustomDocumentWindow.

If you have an NSCollectionView inside the NSPopover, your NSCollectionView subclass must adapt the PopoverFirstResponderStealingSuppression protocol; not the NSPopover subclass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment