You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让NSWindow完全覆盖含菜单栏与Dock的整个屏幕?

解决方案

问题分析

当前窗口显示在菜单栏下方,核心原因是系统默认会将NSWindow约束到菜单栏下方区域,且原窗口级别不足以覆盖菜单栏;同时需确保窗口仅作为overlay存在,不会触发原生全屏创建独立桌面。

修改后的实现代码

import Foundation
import AppKit
import SwiftUI

class FullScreenPanel: NSPanel {
    override func constrainFrameRect(_ frameRect: NSRect, to screen: NSScreen?) -> NSRect {
        // 强制返回完整屏幕帧,禁止系统自动调整窗口位置
        return frameRect
    }
}

final class Panel: FullScreenPanel, NSWindowDelegate {
    init(contentRect: NSRect, backing: NSWindow.BackingStoreType, defer flag: Bool) {
        super.init(
            contentRect: contentRect,
            styleMask: [.borderless, .nonactivatingPanel],
            backing: backing,
            defer: flag
        )
        
        // 设置窗口级别高于菜单栏,确保覆盖整个屏幕(包括菜单栏区域)
        self.level = .popUpMenu
        // 配置集合行为:在所有空间显示,且作为全屏辅助窗口(不会生成新桌面)
        self.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]
        self.titleVisibility = .hidden
        self.isMovable = false
        self.isMovableByWindowBackground = false
        self.isReleasedWhenClosed = false
        self.isOpaque = false
        self.backgroundColor = .clear
        self.delegate = self
    }

    func windowDidResignKey(_ notification: Notification) {
        DispatchQueue.main.async {
            appDelegate?.hideWindow()
        }
    }
}

实例化代码(增加安全校验)

if let mainScreen = NSScreen.main {
    mainWindow = Panel(
        contentRect: mainScreen.frame,
        backing: .buffered,
        defer: false
    )
}

关键调整点

  • 窗口级别:使用.popUpMenu级别(高于菜单栏的.mainMenu级别),确保窗口能覆盖菜单栏区域。
  • 约束重写:constrainFrameRect直接返回传入的完整屏幕帧,阻止系统自动将窗口下移至菜单栏下方。
  • 集合行为:组合.canJoinAllSpaces和.fullScreenAuxiliary,让窗口在所有空间显示,且不会触发原生全屏创建新桌面。
  • 透明背景:设置backgroundColor = .clear,适配overlay应用的半透明需求(若不需要可移除)。

内容的提问来源于stack exchange,提问作者JonLuca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 03:31:36