I'm making a bridge for react-native-macos. I need NSPanel with the same behaviour as Spotlight.
I programmatically created NSPanel and NSTextField inside. Everything working as expected, but if I change NSPanel to not .titled - the text field is disabled.
Works:
panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
.borderless,
.nonactivatingPanel,
.titled, < ------- HERE
.resizable,
], backing: .buffered, defer: true)
searchField = NSTextField()
searchField.delegate = self
searchField.isBezeled = false
searchField.font = NSFont.systemFont(ofSize: 20, weight: .light
searchField.drawsBackground = false
searchField.placeholderString = "Query here..."
searchField.setFrameSize(NSMakeSize(400, 40)
Doesn't work:
panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
.borderless,
.nonactivatingPanel,
.resizable,
], backing: .buffered, defer: true)
searchField = NSTextField()
searchField.delegate = self
searchField.isBezeled = false
searchField.font = NSFont.systemFont(ofSize: 20, weight: .light
searchField.drawsBackground = false
searchField.placeholderString = "Query here..."
searchField.setFrameSize(NSMakeSize(400, 40)
How can I do NSPanel with hidden titlebar and editable NSTextField inside?
I believe .borderless
and .titled
are mutually exclusive. In other words, when you specify .borderless
in the top code, the .titled
overrides it and you get end up getting a "normal window" that handles events normally. In the second code, the .borderless
actually registers and you end up getting a borderless window subclass that handles events quite differently. But all of this is beside the point.
Assuming you can require greater than macOS 10.10, you can use the following code:
panel = NSPanel(contentRect: NSRect(x: 0, y: 0, width: 400, height: 40), styleMask: [
.titled,
.fullSizeContentView,
], backing: .buffered, defer: true)
panel.titleVisibility = .hidden
panel.titlebarAppearsTransparent = true
panel.makeFirstResponder(searchField)
panel.makeKeyAndOrderFront(nil)
This gets a full-sized titled panel that handles events normally (it allows its views to become key). Then before showing the panel, hide the titlebar and also make it transparent. Note that to have the titlebar fully disappeared, you need to not use any of the .resizable
, .closable
, or .miniaturizable
options.