非 .titled NSPanel 内的可编辑 NSTextField

Editable NSTextField inside not .titled NSPanel

我正在为 react-native-macos 搭建一座桥梁。我需要与 Spotlight 具有相同行为的 NSPanel。

我以编程方式在里面创建了 NSPanel 和 NSTextField。一切都按预期工作,但如果我将 NSPanel 更改为 not .titled - 文本字段被禁用。

作品:

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)

无效:

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)

如何在隐藏标题栏和内部可编辑 NSTextField 的情况下实现 NSPanel?

我认为 .borderless.titled 是互斥的。换句话说,当您在顶部代码中指定 .borderless 时,.titled 会覆盖它,您最终会得到一个正常处理事件的“正常 window”。在第二个代码中, .borderless 实际上注册了,你最终得到了一个无边界的 window 子类,它以完全不同的方式处理事件。但所有这些都离题了。

假设你可以要求大于 macOS 10.10,你可以使用下面的代码:

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)

这会得到一个 full-sized 标题面板,可以正常处理事件(它允许其视图成为关键)。然后在显示面板之前,隐藏标题栏并使其透明。请注意,要使标题栏完全消失,您需要不使用任何 .resizable.closable.miniaturizable 选项。