Home > Apple > Mac

How to identify which process is running which window in macOS

In this guide, we will show you a couple of methods that should help you identify which process is running which app window in macOS. Recently I came across an issue wherein a user has sent a screenshot of a blank window that tends to pop up from time to time on his screen. The window doesn’t have any name or content, so it’s next to impossible to identify its source.

With that said, these windows are usually associated with malware and adware, so the earlier you get hold of their originating source and hence get rid of it, the better it is. In this regard, if you head over to Activity Monitor, then while it will give you a list of running processes, however, it won’t be able to pinpoint which process is responsible for that app window.

So what else could be done to catch the culprit? Well, there does exist a couple of nifty workarounds that should help you identify which process is running which app window in macOS. So without further ado, let’s check them out.

How to identify which process is running which window in macOS

identify process window macos

It is recommended that you try out each of the below-mentioned workarounds and then see which one spells out success. So with that in mind, let’s get started.

Method 1: Open Source Tool

You could use the lswin open-source tool from GitHub to get this job done. Before using this tool, make sure to install the dependency via the pip install pyobjc-framework-Quartz command. With that said, the tool consists of the following Python script.

#!/usr/bin/env python

# Install Quartz with 'pip install -U pyobjc-framework-Quartz'
import Quartz

#wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionOnScreenOnly | Quartz.kCGWindowListExcludeDesktopElements, Quartz.kCGNullWindowID)
wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)

wl = sorted(wl, key=lambda k: k.valueForKey_('kCGWindowOwnerPID'))

#print wl

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

for v in wl:
    raw_chars = ( \
        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 '')) \
    )
    print(raw_chars)

Method 2: Using Python Script

You could also use the below Python script to identify which process is running which app window in macOS. Before starting, make sure to install the dependency via the pip install pyobjc-framework-Quartz command [and pip install pyobjc-framework-Quartz if required]. [Credits: SuperUser Member ruzard].

import Quartz
import time
from Foundation import NSSet, NSMutableSet
def transformWindowData(data):
    list1 = []
    for v in data:
        if not v.valueForKey_('kCGWindowIsOnscreen'):
            continue


        row = ( \
            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')
        list1.append(row)

    return list1;

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

    # print textList1
    for v in dataSet:
        print v;

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

#convert into readable format
textList1 = transformWindowData(wl);

#print everything we have on the screen
print 'all windows:'
printBeautifully(textList1)

print 'Move target window'
time.sleep(5)

#grab window data the second time
wl2 = Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)
textList2 = transformWindowData(wl2)

#check the difference
w = NSMutableSet.setWithArray_(textList1)
w.minusSet_(NSSet.setWithArray_(textList2))

#print the difference
printBeautifully(w)

Method 3: Using XCode

Apple’s integrated development environment for macOS should also help you get this job done. Here’s how:

  1. To begin with, download and install XCode from the official website.
  2. Then head over to Xcode Developer Tools > Accessibility Inspector.
  3. Now choose Crosshairs for selecting the desired window of interest.
  4. It should give you all the required information about that window.

Method 4: Using Python Script [New]

Similar to the aforementioned command, the below-listed script will also help you identify which process is running which app window in macOS. Before starting, make sure to install the dependency via the pip install pyobjc-framework-Quartz command. [Credits: SuperUser Member ruzard].

#!/usr/bin/env python

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

wl1 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)
print ('Move target window')
time.sleep(5)
wl2 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)

w = NSMutableSet.setWithArray_(wl1)
w.minusSet_(NSSet.setWithArray_(wl2))
print ('\nList of windows that moved:')
print (w)
print ('\n')

That’s it. These were the four different methods that should help you identify which process is running which app window in macOS. If you have any queries concerning the aforementioned steps, do let us know in the comments. We will get back to you with a solution at the earliest.


Share: