CGWindowListCopyWindowInfo returns kCGWindowOwnerName for other apps without Screen Recording permission on macOS 27 Golden Gate (regression vs. Tahoe)

I'm seeing a behavior difference in CGWindowListCopyWindowInfo between macOS 26 Tahoe and macOS 27 Golden Gate beta regarding the Screen Recording / System Audio Recording privacy permission, and I'd like to confirm whether this is intentional or a beta regression.

Environment

macOS 26 Tahoe (26.x) — tested behavior below macOS 27 Golden Gate beta 4 (26A5388g) — tested behavior below

Expected behavior (matches Tahoe) When my app does NOT have permission under System Settings > Privacy & Security > Screen & System Audio Recording:

CGWindowListCopyWindowInfo still returns window list entries for other running apps. However, kCGWindowOwnerName for windows owned by processes other than my own app is nil.

When permission IS granted, kCGWindowOwnerName is populated correctly for all windows.

Actual behavior on Golden Gate Even without Screen Recording permission granted (verified in System Settings, and via CGPreflightScreenCaptureAccess() returning false), kCGWindowOwnerName is populated for windows owned by other running apps — i.e., the same as if permission had been granted.

Repro

swift let options: CGWindowListOption = [.optionOnScreenOnly, .excludeDesktopElements] let windowList = CGWindowListCopyWindowInfo(options, kCGNullWindowID) as? [[String: AnyObject]] for window in windowList ?? [] { let owner = window[kCGWindowOwnerName as String] as? String print(owner ?? "nil") } On Tahoe without permission: prints nil for other apps' windows. On Golden Gate beta 4 without permission: prints the actual owner name for other apps' windows.

Question

Is this a known/intentional change in Golden Gate, or a beta regression in the TCC enforcement path for this API? Since Apple has been steadily tightening screen-capture-adjacent APIs (Sonoma/Sequoia/Tahoe) and recommending migration to ScreenCaptureKit, should we treat any reliance on kCGWindowOwnerName's permission-gated nil behavior as unsupported going forward, and use a different API to check whether the process has Screen Recording access?

Any guidance from DTS would be appreciated. Happy to file a Feedback Assistant report with a sample project if useful — let me know the FB number format expected.

Answered by DTS Engineer in 898801022

Thanks for the detailed comparison and the repro.

Start with the approach itself, because that is the fragile part. Using whether kCGWindowOwnerName comes back nil as a signal for "this process does not have Screen Recording permission" relies on undocumented behavior. The CGWindowListCopyWindowInfo reference does not document any permission gating of its keys. So which keys are populated without permission is undocumented and may change at any time.

The supported approaches are:

  • To check Screen Recording authorization, use CGPreflightScreenCaptureAccess(), which reports the current state without prompting. To request it, use CGRequestScreenCaptureAccess(), which prompts. These are the documented APIs for the permission state, which is what the nil check was approximating. Use them rather than inferring permission from which keys are populated.
  • For enumerating windows and apps going forward, SCShareableContent in ScreenCaptureKit is the modern surface. The older Core Graphics screen-capture image APIs are deprecated in favor of ScreenCaptureKit.

Since there is a documented API for checking Screen Recording authorization, I do not think a Feedback report is justified in this case.

For reference:

Thanks for the detailed comparison and the repro.

Start with the approach itself, because that is the fragile part. Using whether kCGWindowOwnerName comes back nil as a signal for "this process does not have Screen Recording permission" relies on undocumented behavior. The CGWindowListCopyWindowInfo reference does not document any permission gating of its keys. So which keys are populated without permission is undocumented and may change at any time.

The supported approaches are:

  • To check Screen Recording authorization, use CGPreflightScreenCaptureAccess(), which reports the current state without prompting. To request it, use CGRequestScreenCaptureAccess(), which prompts. These are the documented APIs for the permission state, which is what the nil check was approximating. Use them rather than inferring permission from which keys are populated.
  • For enumerating windows and apps going forward, SCShareableContent in ScreenCaptureKit is the modern surface. The older Core Graphics screen-capture image APIs are deprecated in favor of ScreenCaptureKit.

Since there is a documented API for checking Screen Recording authorization, I do not think a Feedback report is justified in this case.

For reference:

CGWindowListCopyWindowInfo returns kCGWindowOwnerName for other apps without Screen Recording permission on macOS 27 Golden Gate (regression vs. Tahoe)
 
 
Q