在 macOS 开发中,NSWindow.CollectionBehavior 是一个位掩码(OptionSet),用来定义窗口在 Spaces、Mission Control、全屏模式、标签页等环境下的行为。可以通过设置 window.collectionBehavior 来控制窗口在不同上下文中的表现。
常见的 NSWindow.CollectionBehavior 值
1、.canJoinAllSpaces:窗口会显示在所有 Spaces 中(类似 Dock、菜单栏那种“全局存在”的窗口)。
实际效果:切换桌面时,它不会消失,而是“全局固定”在屏幕上。
典型用途:悬浮工具条、系统监视器、剪贴板工具(如 Paste)、计时器。
2、.moveToActiveSpace:当用户切换到某个 Space 时,窗口会自动移动到该 Space。
当用户切换到一个 Space 时,窗口会自动跟随。
区别于 canJoinAllSpaces:它不是“全局存在”,而是“跟随用户”。
举个例子:
在 Space 1 打开了一个工具面板 → 切到 Space 2 → 这个面板会跟过来。
用途:辅助窗口(比如 Photoshop 的颜色面板、调试工具)。
3、.managed:窗口由系统管理,参与 Mission Control、Spaces。
默认情况下窗口都是 managed,表示由系统的 window server 管理 → 在 Exposé、Spaces、全屏切换中都会正常参与。
几乎不需要手动设置managed,因为普通窗口的 collectionBehavior 默认就是包含 .managed。
4、.transient:窗口被视为“临时”,例如面板(Panel),它通常会出现在当前应用的活动空间里。
效果:在 Mission Control 里看不到它。
切换应用时(Cmd+Tab)通常也不会单独列出。
典型用途:浮动面板(Font 面板、颜色选择器)、工具提示(HUD)。
5、.stationary:窗口不会在 Expose/Mission Control 中被重新排序或分组。
用途:窗口保持在原地,不会被打乱位置。而普通窗口在Mission Control中,会按照 app – 窗口的层级展示。
6、.participatesInCycle:窗口会参与“窗口循环”(Command+` 切换窗口时可见)。
注:` 需要fn1+ESC才能打出,如果打出的是 · 需要按一下Caps切换大小写。
效果:加了这个属性,窗口能被选中。
用途:普通应用窗口。
7、.ignoresCycle:与上面相反:窗口不会参与窗口循环。
效果:即便这个窗口打开,按 Cmd+` 时也不会切换到它。
用途:不想让用户在窗口切换时被“打扰”的窗口,比如后台面板。
8、.fullScreenPrimary:窗口可作为全屏应用的主要窗口。
举例:Safari → 点击绿色按钮,它全屏了,Safari 主窗口就成了 fullScreenPrimary。
用途:主界面窗口。
9、.fullScreenAuxiliary:窗口可作为全屏应用的辅助窗口(比如 Pages 的检查器面板)。
举例:Pages → 进入全屏后,侧边栏的“检查器”面板也会跟随进入全屏。
区别于普通窗口:如果没有这个属性,辅助窗口在主窗口进入全屏后会消失。
10、.fullScreenNone:禁止窗口进入全屏模式。
点击绿色按钮不会触发全屏,而是只会最大化窗口。
用途:某些窗口不适合全屏(比如浮动工具面板)。
11、fullScreenAllowsTiling:
作用:允许窗口在 macOS 分屏 (Split View) 模式下被选择进入。
场景:如果开发的是一个支持分屏的编辑器(如 Xcode、Pages),就需要开启它。
如果不开启,即使用户拖动窗口到屏幕边缘,也不会进入分屏选择器。
12、fullScreenDisallowsTiling:
作用:禁止窗口进入 macOS 的分屏模式。
场景:一些“工具型”窗口(例如 Inspector、浮动调色板)不适合进入分屏,所以可以加这个标志。
13、primary:
作用:表示这个窗口在 Expose(Mission Control)或 App Exposé 中,应该作为应用的“主窗口”展示。
场景:一个 App 可能有多个窗口(例如文稿窗口 + 工具窗口),那么 primary 窗口会在 Mission Control/App Exposé 里作为代表显示在最前。
14、auxiliary:
作用:标记窗口为辅助窗口,它会和主窗口一起管理,但不会成为独立的 app 窗口。
场景:适合“工具栏”或“控制面板”,它跟随主窗口的生命周期,不单独占 Mission Control 的空间。
15、canJoinAllApplications:
作用:允许这个窗口在所有应用的空间(Spaces) 里出现,而不仅限于自己的应用空间。
场景:如果不开启,一个窗口只会存在于自己 App 的 Space 或全屏环境里。
开启后,这个窗口就可以在所有桌面空间里保持可见(有点类似 Finder 的“显示所有空间”效果)。
常用组合
1、普通主窗口
window.collectionBehavior = [.fullScreenAllowsTiling, .participatesInCycle]
2、工具型窗口(调色板、浮动窗口)
window.collectionBehavior = [.auxiliary, .ignoresCycle, .fullScreenDisallowsTiling]
3、HUD 或临时窗口
window.collectionBehavior = [.transient, .ignoresCycle, .canJoinAllSpaces]
使用示例
let window = NSWindow(
contentRect: NSMakeRect(0, 0, 600, 400),
styleMask: [.titled, .resizable, .closable],
backing: .buffered,
defer: false
)
// 让窗口显示在所有 Spaces
window.collectionBehavior = [.canJoinAllSpaces]
// 设置为全屏的辅助窗口
window.collectionBehavior = [.fullScreenAuxiliary, .canJoinAllSpaces]
总结
CollectionBehavior是开发者层级的窗口行为控制。
在macOS中Dock栏右击-选项-分配到桌面,也可以将App窗口分配到当前桌面或所有桌面。如果CollectionBehavior和Dock栏设置存在冲突时,系统以用户在Dock栏的设置为准。
相关文章
macOS窗口NSWindow:https://fangjunyu.com/2025/07/01/macos%e7%aa%97%e5%8f%a3nswindow/