Следующий код Python 2 выводит список всех окон в текущей рабочей области:

#!/usr/bin/python
import Quartz
for window in Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionOnScreenOnly, Quartz.kCGNullWindowID):
    print("%s - %s" % (window['kCGWindowOwnerName'], window.get('kCGWindowName', u'Unknown').encode('ascii','ignore')))

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

Как мне изменить вышеупомянутый скрипт, чтобы вывести список всех окон со всех рабочих столов?

4
kenorb 29 Май 2017 в 01:00

2 ответа

Лучший ответ

Следующий скрипт должен возвращать информацию об окне на любом рабочем столе / рабочем пространстве / дисплее, полноэкранном режиме и подробную информацию (координаты, pid, заголовки и т. Д.):

#!/usr/bin/python

import Quartz
import time
from Quartz import CGWindowListCopyWindowInfo, kCGWindowListExcludeDesktopElements, kCGNullWindowID
from Foundation import NSSet, NSMutableSet

def windowList(wl):
    for v in wl:
        print ( 
        str(v.valueForKey_('kCGWindowOwnerPID') or '?').rjust(7) + 
            ' ' + str(v.valueForKey_('kCGWindowNumber') or '?').rjust(5) + 
            ' {' + ('' if v.valueForKey_('kCGWindowBounds') is None else ( 
                    str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('X')))     + ',' + 
                    str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Y')))     + ',' + 
                    str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Width'))) + ',' + 
                    str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Height'))) 
                ) ).ljust(21) + '}' + 
            '\t[' + ((v.valueForKey_('kCGWindowOwnerName') or '') + ']') + 
            ('' if v.valueForKey_('kCGWindowName') is None else (' ' + 
            v.valueForKey_('kCGWindowName') or '')) 
        ).encode('utf8') # remove 'encode' for Python 3.x

wl1 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)
print('Move target window (or ignore)\n')
time.sleep(5)

print('PID'.rjust(7) + ' ' + 'WinID'.rjust(5) + '  ' + 'x,y,w,h'.ljust(21) + ' ' + '\t[Title] SubTitle')
print('-'.rjust(7,'-') + ' ' + '-'.rjust(5,'-') + '  ' + '-'.ljust(21,'-') + ' ' + '\t-------------------------------------------')

wl2 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)

w = NSMutableSet.setWithArray_(wl1)
w.minusSet_(NSSet.setWithArray_(wl2))

wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)
wl = sorted(wl, key=lambda k: k.valueForKey_('kCGWindowOwnerPID'))

windowList(wl)

print('\nDetailed window information: {0}\n'.format(w))
4
l'L'l 23 Авг 2019 в 02:22

Ключ здесь, чтобы использовать правильный параметр для 1-го аргумента CGWindowListCopyWindowInfo. Таким образом, кроме использования optionOnScreenOnly свойства (в котором перечислены все окна, которые в данный момент находятся на экране), excludeDesktopElements требуются свойства быть добавленным.

excludeDesktopElements: исключить все окна из списка, которые элементы рабочего стола, в том числе фоновая картинка и значки рабочего стола.

Например.

list = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly, kCGNullWindowID)

В качестве альтернативы для всех окон также можно использовать свойство kCGWindowListOptionAll.

kCGWindowListOptionAll: список всех окон, включая как экранные, так и внеэкранные окна , При получении списка с помощью этой опции параметр relativeToWindow должен быть установлен в kCGNullWindowID.

Для других свойств проверьте CGWindow.h в CoreGraphics } }.


Таким образом, исходный код может быть изменен на:

#!/usr/bin/python
# Prints list of all windows.
# See: https://stackoverflow.com/q/44232433/55075
import Quartz
for window in Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionOnScreenOnly | Quartz.kCGWindowListExcludeDesktopElements, Quartz.kCGNullWindowID):
    print("%s - %s" % (window['kCGWindowOwnerName'], window.get('kCGWindowName', u'Unknown').encode('ascii','ignore')))
1
ManuelSchneid3r 31 Янв 2020 в 12:41