`[NSScreen mainscreen]` вводящая в заблуждение документация - PullRequest
0 голосов
/ 23 мая 2019

Документация для [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 );
}

Я перетаскиваю окно Xcode на свой собственный дисплей MacBook, проверяю, что оно имеет фокус клавиатуры, и выполняю:

0x1006aaac0 
0x1006aaac0    0.000000 0.000000 2560.000000 1440.000000  
0x1006ab3d0    0.000000 -800.000000 1280.000000 800.000000  

Теперь я перетаскиваю его на свой ЖК-дисплей, проверяю фокусировку на клавиатуре и выполняю:

0x1005a15e0 
0x1005a15e0    0.000000 0.000000 2560.000000 1440.000000  
0x1005a64c0    0.000000 -800.000000 1280.000000 800.000000  

То есть [NSScreen mainscreen] каждый раз идентифицирует ЖК-дисплей (тот, что с меню).

Похоже, что [NSScreen mainscreen], вопреки документации на самом деле дает экран с меню.

Кто-нибудь захочет подтвердить это как ошибку документации?

1 Ответ

2 голосов
/ 23 мая 2019

Какое отношение имеет к этому положение окна Xcode? Программа, запрашивающая его, предположительно, не сама Xcode, а ваше приложение.

В любом случае, на это влияют Системные настройки> Управление полетом> Дисплеи имеют отдельные пробелы. Также см. Примечания к выпуску 10.9 AppKit :

Пробелы и несколько экранов

В 10.9 мы добавили функцию, где каждый экран получает свой собственный набор пробелы, и можно переключаться между пробелами на одном экране не нарушая пространства на других экранах. В этом режиме Полноэкранное окно использует один экран и оставляет содержимое любого другие экраны без изменений.

Каждый экран теперь имеет свою собственную строку меню, и можно показать Стыковка на любом экране, если вы установили Dock на «Положение на Bottom».

Строка меню имеет активный вид на активном экране, который обычно экран, содержащий окно ключа. Строки меню на других экраны неактивны.

В этом режиме желательно, чтобы новые окна открывались на активном экран. В поддержку этой модели + [NSScreen mainScreen] теперь возвращает активный экран, который немного отличается от предыдущего поведения возврата экрана, содержащего keyWindow, если оно есть, и ноль иначе экран.

Окно, восстановленное при запуске приложения через -restoreStateWithCoder: will вернуться на прежнее место, независимо от активного экрана. окно, расположенное с помощью -setFrameAutosaveName: предпочтет активный дисплей.

Эту функцию можно отключить, сняв флажок с предпочтения «Дисплеи имеют отдельные пробелы» на панели настроек управления полетом в системных настройках. Этот параметр вступает в силу только после регистрации и обратно, или перезапуск. NSScreen имеет API для запроса функция отдельного пространства включена:

+ (BOOL)screensHaveSeparateSpaces NS_AVAILABLE_MAC(10_9);

Когда эта функция включена, окна могут не отображаться видимым образом. Окно будет назначено на дисплей, содержащий большинство его геометрия, если программно расположена в остовном положении. окно будет назначено на дисплей, содержащий мышь, если окно перемещается пользователем. Окно прикрепляется к краю дисплей, есть ли другой соседний дисплей.

К сожалению, много важной информации есть только в заметках о выпуске. Это не всегда включено в основную документацию.

Обратите внимание на немного другое объяснение "старого" поведения +mainScreen:

… его предшествующее поведение возврата экрана, содержащего keyWindow, если оно есть, и ноль в противном случае экран.

Учтите, что для неактивного приложения или приложения без окон -[NSApplication keyWindow] будет nil, поэтому +mainScreen вернет нулевой экран. Итак, со ссылкой на указанную вами документацию:

Главный экран относится к экрану, содержащему окно, в котором в данный момент принимаются события клавиатуры.

то, что было оставлено невысказанным, это «в приложении вызова».

В любом случае, если вам нужен основной дисплей (0, 0), просто используйте NSScreen.screens[0].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...