If you have ever stared at a floating dialog, a stuck login prompt, or a mystery pop-up on macOS and wondered which process created this window, you are not alone. The answer is not obvious from the Finder or Dock, and Activity Monitor only helps part of the way.
Quick Answer
The most reliable built-in way to find which process owns a specific window on macOS is to query Quartz Window Services with CGWindowListCopyWindowInfo, read the window’s kCGWindowOwnerPID, and then inspect that PID with ps. Activity Monitor can narrow the search, but Quartz gives the precise window-to-process mapping.
Why This Is Harder Than It Looks on macOS
macOS does not expose an obvious “right-click this window and show me the PID” feature. A single app may own multiple windows, multiple helper processes, and several background agents. Some windows also have no visible title, which makes manual guessing unreliable.
Apple’s documentation explains why. In a window information dictionary, kCGWindowOwnerPID is a required key, but kCGWindowOwnerName and kCGWindowName are optional. That means the owning PID is dependable, while the app name and window title may be missing for some windows.
Method 1: Use Activity Monitor When You Already Know the App
If you can already tell which app created the window, Activity Monitor is the fastest built-in GUI tool to confirm the process.
How to narrow the list
- Open Activity Monitor from
/Applications/Utilities/. - Choose View > Windowed Processes to show processes that can create windows.
- If you need parent-child context, choose View > All Processes, Hierarchically.
- Search for the app name, then open its info panel or note its PID.
This is useful for common cases like “Is this popup from Safari, Slack, or a helper app?”
When Activity Monitor falls short
Activity Monitor shows processes that can create windows, not a direct mapping from this exact window to that exact PID. It becomes much less reliable when:
- an app spawns multiple helper processes,
- the window title does not match the app name,
- the window belongs to a background agent,
- or you need to script the lookup.
For exact window ownership, use Quartz.
Method 2: Use Quartz Window Services to Map Windows to PIDs
Apple’s Core Graphics API CGWindowListCopyWindowInfo returns metadata for on-screen windows, including the owning PID. You can call it directly from a short Swift command without creating a full app.
List visible windows with their owning process
swift -e '
import Foundation
import CoreGraphics
let query = CommandLine.arguments.dropFirst().joined(separator: " ").lowercased()
let windows = CGWindowListCopyWindowInfo(
[.optionOnScreenOnly, .excludeDesktopElements],
kCGNullWindowID
) as? [[String: Any]] ?? []
for window in windows {
let owner = (window[kCGWindowOwnerName as String] as? String) ?? ""
let pid = (window[kCGWindowOwnerPID as String] as? Int) ?? 0
let title = (window[kCGWindowName as String] as? String) ?? ""
guard !owner.isEmpty else { continue }
guard query.isEmpty ||
owner.lowercased().contains(query) ||
title.lowercased().contains(query) else { continue }
print("PID: \(pid)\tApp: \(owner)\tWindow: \(title)")
}
' "Safari"
Replace "Safari" with part of the app name or window title you are trying to identify. If you omit the search term, the command prints all currently visible windows it can enumerate.
What the output tells you
- PID: the owning process ID from
kCGWindowOwnerPID - App: the process name from
kCGWindowOwnerName - Window: the title from
kCGWindowNamewhen available
This is the best built-in approach when your real question is “Which process owns this exact window?”
Inspect the process after you have the PID
Once you have the PID, use ps to confirm the executable and command line:
ps -p <PID> -o pid,ppid,comm,args
Example:
ps -p 1234 -o pid,ppid,comm,args
This lets you move from a suspicious window to the exact binary, parent process, and launch arguments.
Important caveats
- Some windows have a blank title because
kCGWindowNameis optional. - System overlays and utility panels can appear as separate windows even when they belong to the same app.
- In practice, protected apps may reveal less metadata until the inspecting tool has the right macOS privacy permissions.
Method 3: Use ProcXray for Interactive Investigation
If you do this often, raw commands become tedious. ProcXray is better when you need to move from a mystery window to the surrounding process context quickly.
Why ProcXray is better for repeated debugging
- Live process tree shows what launched the owning process.
- Command-line inspection helps you distinguish helper processes from the main app.
- Environment variable inspection reveals launch context that
Activity Monitorhides. - Short-lived process capture helps when the suspicious window appears only briefly.
- Code-signature visibility helps you decide whether the process is expected, unsigned, or suspicious.
If the window belongs to a helper process, an updater, or a transient background tool, that surrounding context matters more than the PID alone.
You may also want these related guides:
- How to Check What Processes Are Running on Mac
- How to Monitor Processes on macOS: A Complete Developer Guide
- ProcXray vs Activity Monitor
Activity Monitor vs Quartz vs ProcXray
| Method | Best for | Strengths | Limitations |
|---|---|---|---|
| Activity Monitor | Quick visual confirmation | Built in, easy to use, shows PIDs | Does not map an arbitrary window directly to its owner |
| Quartz window query | Exact window-to-PID lookup | Official API, scriptable, precise | Raw output needs manual follow-up |
| ProcXray | Real investigations and repeated debugging | Adds lineage, env vars, signatures, transient-process visibility | Requires installing another app |
Bottom line: if you need an exact answer once, use the Quartz query. If you investigate windows, helpers, and short-lived processes regularly, use ProcXray.
FAQ
Can Activity Monitor show which process owns a specific window on macOS?
Not directly. Activity Monitor can filter to Windowed Processes and help you inspect likely app processes, but it does not provide a one-click mapping from a single window to its exact PID. Quartz Window Services is the more precise built-in method.
What is the official Apple API for finding a window’s owning process?
Apple documents CGWindowListCopyWindowInfo as the Core Graphics function for retrieving window metadata. The returned dictionary includes kCGWindowOwnerPID as a required key, which makes it the canonical field for mapping a window to its owning process.
Why is a macOS window title sometimes blank?
Because kCGWindowName is optional, not guaranteed. Some windows expose the owner PID but not a user-visible title. This is normal for many utility windows, system overlays, and protected app surfaces.
After I find the PID, what should I do next?
Run ps -p <PID> -o pid,ppid,comm,args to confirm the executable path, parent process, and command-line arguments. If the process still looks suspicious, inspect its file descriptors, network activity, and code signature next.
Sources and References
- Apple Developer:
CGWindowListCopyWindowInfo - Apple Developer: Required Window List Keys
- Apple Developer: Optional Window List Keys
- Apple Support: View information about Mac processes in Activity Monitor
- Apple Support: Activity Monitor User Guide
- macOS built-in reference:
man ps
Download ProcXray free → — a faster way to investigate the process behind a suspicious window.