如何让macOS窗口始终显示在所有应用之上(含全屏应用)
如何让macOS窗口显示在全屏应用之上?
我尝试了以下操作,但均无效果:
- 在
Info.plist中配置Application is agent(UIElement)为YES(不确定该配置是否仅适用于iOS) - 执行以下代码:
wnd.collectionBehavior = [.stationary, .canJoinAllSpaces, .fullScreenAuxiliary] wnd.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)) + 2 ) NSApp.activate(ignoringOtherApps: true)
唯一有效的方法是:
NSApp.setActivationPolicy(.prohibited)
但这并非理想解决方案,因为它会禁用应用的诸多功能和特性。
有没有其他方法能让窗口显示在全屏应用之上?
完整代码如下:
func openMainWnd(show: Bool = true) { if mainWndController == nil { let styleMask: NSWindow.StyleMask = [ /*.closable,.miniaturizable, .resizable, .titled*/] let wnd = NSWindow() wnd.styleMask = styleMask wnd.title = "Main1" wnd.contentView = NSHostingView(rootView: MainView(model: appVm) ) wnd.standardWindowButton(.closeButton)?.isHidden = true wnd.standardWindowButton(.miniaturizeButton)?.isHidden = true wnd.standardWindowButton(.zoomButton)?.isHidden = true wnd.isMovable = false wnd.acceptsMouseMovedEvents = true wnd.hasShadow = true wnd.titleVisibility = .hidden wnd.titlebarAppearsTransparent = true wnd.backgroundColor = .clear wnd.collectionBehavior = [.stationary, .canJoinAllSpaces, .fullScreenAuxiliary] wnd.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)) + 2 ) NSApp.activate(ignoringOtherApps: true) wnd.setPosition(vertical: .top(offset: MainWndConfig.topOffset), horizontal: .center) mainWndController = NSWindowController(window: wnd) } if show { mainWndController?.showWindow(mainWndController?.window) } }
可行解决方案
使用系统原生全屏辅助窗口层级
不要手动计算窗口层级,直接使用系统提供的.fullScreenAuxiliary层级,这是专门为浮在全屏应用上的辅助窗口设计的:wnd.level = .fullScreenAuxiliary修正窗口集合行为
移除.stationary,保留.canJoinAllSpaces和.fullScreenAuxiliary——.stationary会让窗口固定在原空间,反而无法跟随全屏应用:wnd.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]调整应用激活时机
将NSApp.activate(ignoringOtherApps: true)移到showWindow之后调用,确保窗口显示完成后再激活应用:if show { mainWndController?.showWindow(mainWndController?.window) NSApp.activate(ignoringOtherApps: true) }补全窗口StyleMask
空的StyleMask会导致系统无法正确识别窗口类型,建议至少添加.borderless:let styleMask: NSWindow.StyleMask = [.borderless]
调整后的完整代码
func openMainWnd(show: Bool = true) { if mainWndController == nil { let styleMask: NSWindow.StyleMask = [.borderless] let wnd = NSWindow() wnd.styleMask = styleMask wnd.title = "Main1" wnd.contentView = NSHostingView(rootView: MainView(model: appVm) ) wnd.standardWindowButton(.closeButton)?.isHidden = true wnd.standardWindowButton(.miniaturizeButton)?.isHidden = true wnd.standardWindowButton(.zoomButton)?.isHidden = true wnd.isMovable = false wnd.acceptsMouseMovedEvents = true wnd.hasShadow = true wnd.titleVisibility = .hidden wnd.titlebarAppearsTransparent = true wnd.backgroundColor = .clear wnd.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary] wnd.level = .fullScreenAuxiliary wnd.setPosition(vertical: .top(offset: MainWndConfig.topOffset), horizontal: .center) mainWndController = NSWindowController(window: wnd) } if show { mainWndController?.showWindow(mainWndController?.window) NSApp.activate(ignoringOtherApps: true) } }
补充说明
Application is agent(UIElement)是macOS的配置,并非iOS专属,但设置为YES会让应用变为后台代理,确实会限制大量功能,不推荐使用。- 如果上述方法仍无效,可尝试启用窗口的
ignoresMouseEvents(若窗口无需交互),但这仅作为备选方案,优先保证层级和行为配置正确。
内容的提问来源于stack exchange,提问作者Andrew
相关产品推荐
相关产品推荐

