Detecting screen recording settings on macOS Catalina

后端 未结 7 1524
清歌不尽
清歌不尽 2020-11-30 23:01

What\'s is a reliable way to detect if user has enabled this API?

CGWindowListCreateImage returns a valid object even if screen recording API is disable

7条回答
  •  抹茶落季
    2020-11-30 23:43

    @marek-h posted a good example that can detect the screen recording setting without showing privacy alert. Btw, @jordan-h mentioned that this solution doesn't work when the app presents an alert via beginSheetModalForWindow.

    I found that SystemUIServer process is always creating some windows with names: AppleVolumeExtra, AppleClockExtra, AppleBluetoothExtra ...

    We can't get the names of these windows, before the screen recording is enabled in Privacy preferences. And when we can get one of these names at least, then it means that the user has enabled screen recording.

    So we can check the names of the windows (created by SystemUIServer process) to detect the screen recording preference, and it works fine on macOS Catalina.

    #include 
    #include 
    
    bool isScreenRecordingEnabled()
    {
        if (@available(macos 10.15, *)) {
            bool bRet = false;
            CFArrayRef list = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
            if (list) {
                int n = (int)(CFArrayGetCount(list));
                for (int i = 0; i < n; i++) {
                    NSDictionary* info = (NSDictionary*)(CFArrayGetValueAtIndex(list, (CFIndex)i));
                    NSString* name = info[(id)kCGWindowName];
                    NSNumber* pid = info[(id)kCGWindowOwnerPID];
                    if (pid != nil && name != nil) {
                        int nPid = [pid intValue];
                        char path[PROC_PIDPATHINFO_MAXSIZE+1];
                        int lenPath = proc_pidpath(nPid, path, PROC_PIDPATHINFO_MAXSIZE);
                        if (lenPath > 0) {
                            path[lenPath] = 0;
                            if (strcmp(path, "/System/Library/CoreServices/SystemUIServer.app/Contents/MacOS/SystemUIServer") == 0) {
                                bRet = true;
                                break;
                            }
                        }
                    }
                }
                CFRelease(list);
            }
            return bRet;
        } else {
            return true;
        }
    }
    

提交回复
热议问题