Определение положения курсора мыши X на экране NSS, когда в macOS присутствует несколько экранов NSS Catalina - PullRequest
0 голосов
/ 22 января 2020

Моя Ма c настроена следующим образом: дисплей 5K расположен сверху встроенного дисплея Ма c.

Image of display arrangement in macOS System Preferences

Если мой курсор мыши находится на дисплее 5K, и я пытаюсь получить положение мыши следующим образом:

CGEventRef ourEvent = CGEventCreate(NULL);
NSPoint point = CGEventGetLocation(ourEvent);
CFRelease(ourEvent);

Я получаю неожиданное возвращаемое значение для point.x. Например, если курсор находится в этой позиции:

Image showing where mouse cursor is on screen

NSLog(@"MOUSE POSITION X: %.0f px", point.x);

Тогда я вернусь MOUSE POSITION X: 1950 px. Однако такое приложение, как Xscope, сообщает об этой позиции x как 3900 px .

Image showing mouse cursor X,Y position as reported by app Xscope

Ни одно из этих значений не кажется правильным, так как экран имеет ширину 2560:

NSScreen *currentScreen = [NSScreen currentScreenForMouseLocation];
NSLog(@"SCREEN WIDTH: %f", currentScreen.frame.size.width);

Примечание: currentScreenForMouseLocation исходит из NSScreen-PointConversion .

И если я переместу расположение 13 ", встроенный дисплей от центра, но все еще под дисплеем 5K, значение point.x еще более неточно. Я вижу, что здесь есть некоторая математическая зависимость между различиями в размерах / разрешении экрана, но мне трудно вычислить точно, что происходит и как в конечном итоге превратить это в код, где я могу получить реальное point.x значение для позиции курсора мыши.

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

Image showing misplaced NSStatusItem menu

1 Ответ

1 голос
/ 22 января 2020

Встроенный дисплей установлен в качестве основного дисплея. Вы можете сказать на скриншоте панели «Дисплеи» Системных настроек, потому что на ней находится строка меню symboli c.

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

Я предлагаю, во-первых, использовать Какао, а не Core Graphics, чтобы получить текущую позицию мыши. Затем вам нужно настроить его так, чтобы он соответствовал началу экрана, на котором он включен (если это то, что вас интересует):

NSPoint pt = [NSEvent mouseLocation];
NSScreen* currentScreen = [NSScreen currentScreenForMouseLocation];
pt.x -= currentScreen.frame.origin.x;
pt.y -= currentScreen.frame.origin.y;

Тем не менее, похоже, что вы просто собираетесь сравните точку с правым краем экрана, о котором также будет сообщено относительно источника основного дисплея. Итак, почему бы просто не сравнить исходную точку с MaxX () кадра кадра экрана?

NSPoint pt = [NSEvent mouseLocation];
NSScreen* currentScreen = [NSScreen currentScreenForMouseLocation];
if (pt.x + menuWidth >= NSMaxX(currentScreen.frame))
    ...;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...