How to list all windows from all workspaces in Python on Mac?

后端 未结 2 1210
囚心锁ツ
囚心锁ツ 2020-12-19 15:25

The following Python 2 code prints list of all windows in the current workspace:

#!/usr/bin/python
import Quartz
for window in Quartz.CGWindowListCopyWindowI         


        
相关标签:
2条回答
  • 2020-12-19 16:12

    The key is here to use the right option for the 1st argument of CGWindowListCopyWindowInfo. So apart of using optionOnScreenOnly property (which list all windows that are currently onscreen), excludeDesktopElements property needs to be added.

    excludeDesktopElements: Exclude any windows from the list that are elements of the desktop, including the background picture and desktop icons.

    E.g.

    list = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements | kCGWindowListOptionOnScreenOnly, kCGNullWindowID)
    

    Alternatively for all windows, kCGWindowListOptionAll property can be also used.

    kCGWindowListOptionAll: List all windows, including both onscreen and offscreen windows. When retrieving a list with this option, the relativeToWindow parameter should be set to kCGNullWindowID.

    For other properties, check CGWindow.h in CoreGraphics.


    So the original code can be changed to:

    #!/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')))
    
    0 讨论(0)
  • 2020-12-19 16:14

    The following script should return window information on any desktop/workspace/display, fullscreen, and detailed information (coordinates, pid, titles, 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') # 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))
    
    0 讨论(0)
提交回复
热议问题