Skip to content

Instantly share code, notes, and snippets.

@soffes
Created November 22, 2019 04:07
Show Gist options
  • Save soffes/da6ea98be4f56bc7b8e75079a5224b37 to your computer and use it in GitHub Desktop.
Save soffes/da6ea98be4f56bc7b8e75079a5224b37 to your computer and use it in GitHub Desktop.
// From https://stackoverflow.com/a/58985069/118631
@available(macOS 10.15, *)
func canRecordScreen() -> Bool {
let runningApplication = NSRunningApplication.current
let processIdentifier = runningApplication.processIdentifier
guard let windows = CGWindowListCopyWindowInfo([.optionOnScreenOnly], kCGNullWindowID)
as? [[String: AnyObject]] else
{
assertionFailure("Invalid window info")
return false
}
for window in windows {
// Get information for each window
guard let windowProcessIdentifier = (window[String(kCGWindowOwnerPID)] as? Int).flatMap(pid_t.init) else {
assertionFailure("Invalid window info")
continue
}
// Don't check windows owned by this process
if windowProcessIdentifier == processIdentifier {
continue
}
// Get process information for each window
guard let windowRunningApplication = NSRunningApplication(processIdentifier: windowProcessIdentifier) else {
// Ignore processes we don't have access to, such as WindowServer, which manages the windows named
// "Menubar" and "Backstop Menubar"
continue
}
if window[String(kCGWindowName)] as? String != nil {
if windowRunningApplication.executableURL?.lastPathComponent == "Dock" {
// Ignore the Dock, which provides the desktop picture
continue
} else {
return true
}
}
}
return false
}
@rudyrichter
Copy link

@ianbytchek it should be, you'll end up getting windows for NSStatusItems, desktop icons and the like. Still would be great if Apple had added an API to query for screen recording authorization.

@iby
Copy link

iby commented Dec 4, 2019

@rudyrichter Or at least a code snippet! Yes, I thought they might be also system-owned, but looks like they are fine. Thanks for the hint!

@soffes
Copy link
Author

soffes commented Dec 4, 2019

@ianbytchek I haven't had any issues with it. Like Rudy said, I think there will always be some windows.

@fhefh2015
Copy link

Working for me

static func permissionCheck() -> Bool {
  if #available(macOS 10.15, *) {
    let runningApplication = NSRunningApplication.current
    let processIdentifier = runningApplication.processIdentifier
    guard
      let windows = CGWindowListCopyWindowInfo([.optionOnScreenOnly], kCGNullWindowID)
        as? [[String: AnyObject]],
      let _ = windows.first(where: { window -> Bool in
        guard
          let windowProcessIdentifier = (window[kCGWindowOwnerPID as String] as? Int).flatMap(
            pid_t.init),
          windowProcessIdentifier != processIdentifier,
          let windowRunningApplication = NSRunningApplication(
            processIdentifier: windowProcessIdentifier),
          windowRunningApplication.executableURL?.lastPathComponent != "Dock",
          let _ = window[String(kCGWindowName)] as? String
        else {
          return false
        }

        return true
      })
    else {
      return false
    }
  }
  return true
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment