`[NSScreen 主屏幕]` 误导性文档

P i*_*P i 2 objective-c

文档具有[NSScreen mainscreen]误导性。

主屏幕不一定是包含菜单栏或其原点位于 (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 );
}
Run Code Online (Sandbox Code Playgroud)

我将 Xcode 窗口拖到本机 MacBook 显示屏上,确保它具有键盘焦点,然后执行:

0x1006aaac0 
0x1006aaac0    0.000000 0.000000 2560.000000 1440.000000  
0x1006ab3d0    0.000000 -800.000000 1280.000000 800.000000  
Run Code Online (Sandbox Code Playgroud)

现在我将它拖到 LCD 上,确保它具有键盘焦点,然后执行:

0x1005a15e0 
0x1005a15e0    0.000000 0.000000 2560.000000 1440.000000  
0x1005a64c0    0.000000 -800.000000 1280.000000 800.000000  
Run Code Online (Sandbox Code Playgroud)

因此[NSScreen mainscreen]每次都会识别 LCD(带有菜单栏的 LCD)。

因此[NSScreen mainscreen]与文档相反,实际上确实产生了带有菜单栏的屏幕。

有人愿意确认这是一个文档错误吗?

Ken*_*ses 6

Xcode 窗口的位置与它有什么关系?查询它的程序可能不是 Xcode 本身,而是您的应用程序。

\n\n

无论如何,这受到系统偏好设置>任务控制>显示器有单独空间的影响。另请参阅10.9 AppKit 发行说明

\n\n
\n

空间和多个屏幕

\n\n

在 10.9 中,我们添加了一项功能,其中每个屏幕都有自己的一组\n 空间,并且可以在一个屏幕上\n 的空间之间切换\n,而不会干扰其他屏幕上的空间。在此模式下,全屏窗口使用一个屏幕,并保持任何其他屏幕的内容不变。

\n\n

现在,每个屏幕都有自己的菜单栏,并且可以在任何屏幕上显示 Dock,前提是您将 Dock 设置为 \n Bottom\xe2\x80\x9d 上的 \xe2\x80\x9cPosition。

\n\n

菜单栏在活动屏幕上具有活动外观,该屏幕通常是包含键窗口的屏幕。其他屏幕上的菜单栏具有非活动外观。

\n\n

在此模式下,需要在活动屏幕上打开新窗口。为了支持此模型,+[NSScreen mainScreen] 现在返回\n 活动屏幕,这与之前的行为略有不同,\n 返回包含 keyWindow 的屏幕(如果有),否则返回零屏幕。

\n\n

在应用程序启动时通过 -restoreStateWithCoder: 恢复的窗口将返回到其之前的位置,与活动屏幕无关。使用 -setFrameAutosaveName: 定位的窗口将首选活动显示。

\n\n

可以通过取消选中“系统偏好设置”中“任务控制”偏好设置窗格中名为\n \xe2\x80\x9c的显示器具有单独的空间\xe2\x80\x9d的首选项来禁用此功能。此设置仅在注销并重新登录或重新启动后生效。NSScreen 有 API 可以查询\n 分隔空间功能是否启用:

\n\n
+ (BOOL)screensHaveSeparateSpaces NS_AVAILABLE_MAC(10_9);\n
Run Code Online (Sandbox Code Playgroud)\n\n

启用此功能后,窗口可能不会明显跨越显示器。如果以编程方式将窗口定位在跨越位置,则窗口将被分配给包含其大部分几何形状的显示。如果用户移动窗口,则该窗口将被分配给包含鼠标的显示器。无论是否有另一个相邻的显示器,窗口都会剪辑到显示器的边缘。

\n
\n\n

不幸的是,许多重要信息仅包含在发行说明中。它并不总是合并到主要文档中。

\n\n

请注意对“旧”行为的稍微不同的解释+mainScreen

\n\n
\n

\xe2\x80\xa6 其之前的行为是返回包含 keyWindow 的屏幕(如果有),否则返回零屏幕。

\n
\n\n

考虑一下,对于不活动的应用程序或没有窗口的应用程序,-[NSApplication keyWindow]将是nil,因此+mainScreen将返回零屏幕。因此,参考您引用的文档:

\n\n
\n

主屏幕是指包含当前正在接收键盘事件的窗口的屏幕。

\n
\n\n

没有说的是“在呼叫应用程序中”。

\n\n

无论如何,如果您想要的是主显示器,即 (0, 0) 处的显示器,只需使用NSScreen.screens[0].

\n