Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix permissions for macos 15 #3497

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
19 changes: 2 additions & 17 deletions src/logic/SystemPermissions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,11 @@ class SystemPermissions {

static func screenRecordingIsGranted() -> Bool {
if #available(OSX 10.15, *) {
return screenRecordingIsGranted_()
return CGPreflightScreenCaptureAccess()
}
return true
}

// workaround: public API CGPreflightScreenCaptureAccess and private API SLSRequestScreenCaptureAccess exist, but
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you seen this? We were not using this API because it wasn't the best in the past.

Copy link
Author

@DominicVonk DominicVonk Jul 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I read it, I will make it that it uses it for MacOS 15+, I tested it yesterday and it works like a charm

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AltTab checks permissions continuously. The user could remove permissions at any point. We check for that on a repeating timer.

As the comment says, CGPreflightScreenCaptureAccess was returning a value which was not updated. It was a snapshot of the permissions at the time the app was launched, but didn't update after that initial snapshot.

Has this behavior changed in macOS 15? If it hasn't, then we should change other parts of the app doing the repeating timer checks. Either find another way to check there, or remove the check. But if we remove the check, we need another way to notice when the screenshot() and the AX calls start failing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to the canRecordScreen, this is updated during runtime

// their return value is not updated during the app lifetime
// note: shows the system prompt if there's no permission
private static func screenRecordingIsGranted_() -> Bool {
return CGDisplayStream(
dispatchQueueDisplay: CGMainDisplayID(),
outputWidth: 1,
outputHeight: 1,
pixelFormat: Int32(kCVPixelFormatType_32BGRA),
properties: nil,
queue: .global(),
handler: { _, _, _, _ in }
) != nil
}

static func observePermissionsPostStartup() {
var counter = 0
Expand All @@ -58,8 +44,7 @@ class SystemPermissions {

static func observePermissionsPreStartup(_ startupBlock: @escaping () -> Void) {
if #available(OSX 10.15, *) {
// this call triggers the permission prompt, however it's the only way to force the app to be listed with a checkbox
SLSRequestScreenCaptureAccess()
CGRequestScreenCaptureAccess()
}
timer = Timer(timeInterval: 0.1, repeats: true) { _ in
let accessibility = accessibilityIsGranted()
Expand Down