macos - 如何创建一个包含仅在按住键盘修改键时出现的 NSMenuItem 的 NSMenu?
问题描述
我想创建一个默认隐藏的NSMenu
包含一个NSMenuItem
,并且仅在用户按住键盘修饰键时出现。
基本上,我正在寻找与 Finder 的“Go”菜单中的“Library”选项相同的行为:
我已经尝试安装一个关键监听器,通过设置它的属性[NSEvent addGlobalMonitorForEventsMatchingMask: handler:]
以编程方式隐藏和取消隐藏它。这种工作,但问题是隐藏/取消隐藏在打开时不起作用。显然,在它打开时完全接管了事件处理循环,从而阻止了关键侦听器工作。
我可能会使用 CGEventTap 在打开时仍然接收事件,但这似乎完全是矫枉过正。NSMenuItem
hidden
NSMenu
NSMenu
NSMenu
我发现的另一件事与我想要的做类似的事情是NSMenu
. 但我只能让它关闭NSMenuItems
,而不是隐藏/取消隐藏它们。
任何帮助将不胜感激。谢谢!
解决方案
假设您的仅选项菜单项的操作是(在 Swift 中)performOptionOnlyMenuItem(_:)
,它的目标是您的AppDelegate
.
您需要做的第一件事是确保
AppDelegate
符合NSMenuItemValidation
协议。您需要做的第二件事是实现该
validateMenuItem(_:)
方法,并让它检查菜单项是否发送performOptionOnlyMenuItem(_:)
操作。如果是这样,请isHidden
根据当前是否按下选项键来设置项目的属性。
如果您不需要验证任何其他菜单项,代码可能如下所示:
extension AppDelegate: NSMenuItemValidation {
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
switch menuItem.action {
case #selector(performOptionOnlyMenuItem(_:)):
let flags = NSApp.currentEvent?.modifierFlags ?? []
menuItem.isHidden = !flags.contains(.option)
return true
default:
return true
}
}
}
如果操作被发送到其他目标,您需要在该目标上实现验证(包括协议一致性)。每个菜单项仅由项目的目标验证。