[NSScreen mainscreen]
的{{3}}具有误导性。
主屏幕不一定是包含菜单栏的同一屏幕,也不一定是起源于(0,0)的屏幕。主屏幕是指包含当前正在接收键盘事件的窗口的屏幕。它是主屏幕,因为它是用户最有可能与之交互的屏幕。
我尝试:
printf( "%p \n", [NSScreen mainScreen]);
for( NSScreen* sc in [NSScreen screens] ) {
NSRect f = [sc frame];
printf("%p %f %f %f %f \n", sc, f.origin.x, f.origin.y, f.size.width,f.size.height );
}
我将Xcode窗口拖到本机MacBook显示器上,确保它具有键盘焦点,然后执行:
0x1006aaac0
0x1006aaac0 0.000000 0.000000 2560.000000 1440.000000
0x1006ab3d0 0.000000 -800.000000 1280.000000 800.000000
现在我将其拖动到LCD上,确保其具有键盘焦点,然后执行:
0x1005a15e0
0x1005a15e0 0.000000 0.000000 2560.000000 1440.000000
0x1005a64c0 0.000000 -800.000000 1280.000000 800.000000
因此[NSScreen mainscreen]
每次都标识LCD(带有菜单栏的LCD)。
看来[NSScreen mainscreen]
(与文档相反)确实会产生带有菜单栏的屏幕。
有人愿意确认这是文档错误吗?
答案 0 :(得分:2)
Xcode窗口的位置与它有什么关系?查询它的程序大概不是Xcode本身,而是您的应用程序。
无论如何,这受“系统偏好设置”>“任务控制”>“显示器有单独的空格”影响。另外,请参见10.9 AppKit release notes:
空格和多个屏幕
在10.9版中,我们添加了一个功能,其中每个屏幕都有自己的一组 空格,并且可以在一个屏幕上的空格之间切换 而不干扰其他屏幕上的空间。在此模式下, 全屏窗口使用一个屏幕,并保留任何内容 其他屏幕保持不变。
每个屏幕现在都有自己的菜单栏,可以显示 如果您将Dock设置为“ Position on 底部”。
菜单栏在活动屏幕上具有活动外观,即 通常是包含键窗口的屏幕。其他菜单栏 屏幕外观无效。
在这种模式下,最好在活动窗口上打开新窗口 屏幕。为了支持该模型,+ [NSScreen mainScreen]现在返回 活动屏幕,与之前的行为略有不同 返回包含keyWindow(如果有)和零的屏幕的时间 否则屏幕。
在应用启动时通过-restoreStateWithCoder:恢复的窗口: 返回其先前位置,与活动屏幕无关。一种 使用-setFrameAutosaveName定位的窗口:将首选活动窗口 显示。
可以通过取消选中命名的首选项来禁用此功能 “任务控制”首选项窗格中的“显示具有单独的空间” 在系统偏好设置中。该设置仅在登录后生效 退出并重新启动,或重新启动。 NSScreen具有API来查询是否 启用了单独的空间功能:
+ (BOOL)screensHaveSeparateSpaces NS_AVAILABLE_MAC(10_9);
启用此功能后,窗口可能不会明显覆盖显示。 一个窗口将分配给包含大部分 如果以编程方式将其几何形状定位在跨度位置,一种 窗口将分配给包含鼠标的显示器,如果 窗口由用户移动。一个窗口夹到 显示,是否还有另一个相邻的显示。
不幸的是,许多重要信息仅在发行说明中。它并不总是包含在主要文档中。
请注意,+mainScreen
的“旧”行为的解释略有不同:
…其先前的行为 返回包含keyWindow(如果有)和零的屏幕的时间 否则屏幕。
请考虑,对于非活动应用程序或没有窗口的应用程序,-[NSApplication keyWindow]
将是nil
,因此+mainScreen
将返回零屏幕。因此,参考您引用的文档:
主屏幕是指包含当前正在接收键盘事件的窗口的屏幕。
未说的是“正在调用的应用程序中”。
无论如何,如果您想要的是主显示(位于(0,0)的显示),只需使用NSScreen.screens[0]
。