Mac菜单栏应用升级Ventura后无法隐藏NSWindowController问题
macOS Ventura下菜单栏应用启动自动显示窗口的修复方案
问题现象
升级至Ventura 13.4 (22F66)后,菜单栏应用启动时会自动显示NSWindowController窗口,此前通过标记关闭窗口的方法失效,控制台出现警告:
[Window] Warning: Window NSWindow 0x119e17510 ordered front from a non-active application and may order beneath the active application's windows
核心原因
Ventura系统调整了应用启动流程的窗口管理逻辑,Storyboard中默认设为「初始控制器」的Window Controller会在应用启动时自动初始化并显示窗口,与你仅通过菜单栏按钮触发Popover的需求冲突。
修复步骤
1. 修改Storyboard配置
- 打开
Main.storyboard,找到默认的Window Controller - 取消勾选其「Is Initial Controller」属性(右侧属性面板「Identity」标签下)
- 选中该Window Controller下的
Window,取消勾选「Visible at Launch」(右侧属性面板「Attributes」标签下)
2. 调整应用激活策略
在AppDelegate的applicationDidFinishLaunching方法中添加激活策略设置,确保应用启动时仅在菜单栏运行,不自动激活窗口:
func applicationDidFinishLaunching(_ aNotification: Notification) { statusItem.button?.image = NSImage(systemSymbolName: "book", accessibilityDescription: "Open") statusItem.button?.toolTip = "Demo" statusItem.button?.target = self statusItem.button?.action = #selector(showSettings) // 添加应用激活策略设置 NSApp.setActivationPolicy(.accessory) }
3. 优化Popover显示逻辑
在showSettings方法中补充激活应用的操作,避免Popover被其他窗口遮挡:
@objc func showSettings() { let storyboard = NSStoryboard(name: "Main", bundle: nil) guard let vc = storyboard.instantiateController(withIdentifier: "ViewController") as? ViewController else { fatalError("Unable to find ViewController in the storyboard.") } guard let button = statusItem.button else { fatalError("Couldn't find status item button.") } let popoverView = NSPopover() popoverView.contentViewController = vc popoverView.behavior = .transient // 激活应用确保Popover显示在顶层 NSApp.activate(ignoringOtherApps: true) popoverView.show(relativeTo: button.bounds, of: button, preferredEdge: .maxY) }
说明
.accessory激活策略会让应用不在Dock和Cmd+Tab切换列表中显示,仅保留菜单栏图标,符合纯菜单栏应用的定位- 激活应用的操作可以避免Popover被其他窗口覆盖,提升交互体验
内容的提问来源于stack exchange,提问作者subin272
相关产品推荐
相关产品推荐

