Разделение реальных и фиктивных окон, возвращаемых CGWindowListCopyWindowInfo - PullRequest
3 голосов
/ 18 октября 2019

Я создаю переключатель окон для macOS.

Я использую CGWindowListCopyWindowInfo, чтобы получить список открытых окон.

    let windows = CGWindowListCopyWindowInfo([.excludeDesktopElements], kCGNullWindowID)

Я не являюсьиспользование опции optionOnScreenOnly вместе с CGWindowListCopyWindowInfo, поскольку это исключает отключение - пробел окон.

Однако это приводит к тому, что некоторые фиктивные окна также включаются всписок окон. Например, есть окно для каждой открытой вкладки в XCode. Существует также дополнительное невидимое окно для плеера VLC, кроме самого окна. Этих окон нет, если я использую optionOnScreenOnly.

Есть ли способ отделить эти фиктивные окна от реальных окон?

Я исследовал kCGWindowLayer и kCGWindowStoreType ключи в словарях, возвращенных CGWindowListCopyWindowInfo, но не могли различить окна.

Редактировать :

Я открыт и для Swift, и дляРешения Objective-C, а также частные вызовы API.

Edit 2 :

Я знаю, что это возможно сделать, потому что приложение Witch правильно обрабатывает эти случаи.

Ответы [ 2 ]

0 голосов
/ 28 октября 2019

Как насчет использования другого подхода, проверяя, какие приложения запущены и видны, используя следующее:

let runningApps = NSWorkspace.shared.runningApplications.filter{ $0.activationPolicy == .regular }

Если вы print(runningApps), вы получите список приложений, которые в данный момент выполняются в вашей рабочей области.

Надеюсь, это поможет.

0 голосов
/ 24 октября 2019

Я не уверен, что это охватывает все интересующие вас случаи, но если мы возьмем массив словарей, возвращаемых CGWindowListCopyWindowInfo(), и сгруппируем записи по kCGWindowNumber (идентификатор окна), это выглядит такв итоге мы получим один из трех случаев:

  • Только у одной словарной записи есть этот номер окна (это простая вдова, которая может быть включена или выключена на экране)
  • Несколько словарейиметь этот идентификатор окна, и только один из них в группе имеет ключ kCGWindowIsOnscreen, установленный в 1: у других либо отсутствует ключ, либо он имеет значение 0. Это означает, что у нас есть окно с несколькими вкладками и запись сkCGWindowIsOnscreen set - это видимая вкладка.
  • У нескольких словарей этот идентификатор окна установлен, и ни в одном из них ключ kCGWindowIsOnscreen не установлен в 1 (он отсутствует или во всех случаях равен 0). Это означает, что у нас есть окно с несколькими вкладками, которое в данный момент находится за пределами экрана.

Я предполагаю, что вы, вероятно, уже отфильтровываете все, что не находится в слое 0 (kCGWindowLayer = 0). Похоже, что большинство вещей, которые мы визуально воспринимаем как «окно», находятся на уровне 0 (элементы меню состояния, кажется, находятся в слоях с одной или двумя двойными цифрами; виджеты, кажется, расположены выше уровня 100 ...).

Я не вижу простого, прямого способа достичь этого, но вы должны быть в состоянии встроить эту логику в нечто работоспособное.

...