¿Cómo listar todas las ventanas de todos los espacios de trabajo en Python en Mac?

El siguiente código de Python 2 imprime la lista de todas las ventanas en el área de trabajo actual:

#!/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'))) 

Aunque no imprime las aplicaciones que están en pantalla completa (ya que está en otra área de trabajo).

¿Cómo modifico el script anterior para enumerar todas las ventanas de todos los escritorios?

El siguiente script debe devolver la información de la ventana en cualquier escritorio / área de trabajo / pantalla, pantalla completa e información detallada (coordenadas, pid, títulos, etc.):

 #!/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') 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)) 

La clave está aquí para usar la opción correcta para el primer argumento de CGWindowListCopyWindowInfo . Entonces, aparte de usar la propiedad optionOnScreenOnly (que enumera todas las ventanas que están actualmente en pantalla), se debe excludeDesktopElements propiedad excludeDesktopElements .

excludeDesktopElements : excluye cualquier ventana de la lista que sean elementos del escritorio, incluidos la imagen de fondo y los icons del escritorio.

P.ej

 list = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements & kCGWindowListOptionOnScreenOnly, kCGNullWindowID) 

Alternativamente, para todas las ventanas, kCGWindowListOptionAll se puede utilizar la propiedad kCGWindowListOptionAll .

kCGWindowListOptionAll : kCGWindowListOptionAll todas las ventanas, incluidas las ventanas en pantalla y fuera de pantalla. Al recuperar una lista con esta opción, el parámetro relativeToWindow debe establecerse en kCGNullWindowID .

Para otras propiedades, verifique CGWindow.h en CGWindow.h .


Así que el código original se puede cambiar a:

 #!/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')))