`[NSScreen mainscreen]`误导性文档

时间:2019-05-23 05:35:53

标签: objective-c

[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](与文档相反)确实会产生带有菜单栏的屏幕。

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

1 个答案:

答案 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]