diff --git a/src/logic/SystemPermissions.swift b/src/logic/SystemPermissions.swift index aa3b3a76..162b8228 100644 --- a/src/logic/SystemPermissions.swift +++ b/src/logic/SystemPermissions.swift @@ -2,6 +2,8 @@ import Cocoa // macOS has some privacy restrictions. The user needs to grant certain permissions, app by app, in System Preferences > Security & Privacy class SystemPermissions { + static var accessibilityIsGranted = PermissionStatus.notGranted + static var screenRecordingIsGranted = PermissionStatus.notGranted static var preStartupPermissionsPassed = false static var flakyCounter = 0 static var timerPermissionsToUpdatePermissionsWindow: Timer? @@ -12,7 +14,7 @@ class SystemPermissions { pollPermissionsRemovedWhileAltTabIsRunning() continueAppStartup() } - if accessibilityIsGranted() != .notGranted && screenRecordingIsGranted() != .notGranted { + if updateAccessibilityIsGranted() != .notGranted && updateScreenRecordingIsGranted() != .notGranted { preStartupPermissionsPassed = true startupBlock() } else { @@ -40,14 +42,26 @@ class SystemPermissions { CFRunLoopAddTimer(BackgroundWork.systemPermissionsThread.runLoop, timerPermissionsRemovedWhileAltTabIsRunning!, .commonModes) } - static func accessibilityIsGranted() -> PermissionStatus { + @discardableResult + static func updateAccessibilityIsGranted() -> PermissionStatus { + accessibilityIsGranted = detectAccessibilityIsGranted() + return accessibilityIsGranted + } + + @discardableResult + static func updateScreenRecordingIsGranted() -> PermissionStatus { + screenRecordingIsGranted = detectScreenRecordingIsGranted() + return screenRecordingIsGranted + } + + private static func detectAccessibilityIsGranted() -> PermissionStatus { if #available(macOS 10.9, *) { return AXIsProcessTrustedWithOptions([kAXTrustedCheckOptionPrompt.takeRetainedValue(): false] as CFDictionary) ? .granted : .notGranted } return .granted } - static func screenRecordingIsGranted() -> PermissionStatus { + private static func detectScreenRecordingIsGranted() -> PermissionStatus { if #available(macOS 10.15, *) { return screenRecordingIsGranted_() ? .granted : (Preferences.screenRecordingPermissionSkipped ? .skipped : .notGranted) @@ -56,14 +70,14 @@ class SystemPermissions { } private static func checkPermissionsWhileAltTabIsRunning() { - let accessibility = accessibilityIsGranted() - let screenRecording = screenRecordingIsGranted() - Logger.debug(accessibility, screenRecording, preStartupPermissionsPassed) - Menubar.togglePermissionCallout(screenRecording == .skipped) - if accessibility == .notGranted { + SystemPermissions.updateAccessibilityIsGranted() + SystemPermissions.updateScreenRecordingIsGranted() + Logger.debug(accessibilityIsGranted, screenRecordingIsGranted, preStartupPermissionsPassed) + Menubar.togglePermissionCallout(screenRecordingIsGranted == .skipped) + if accessibilityIsGranted == .notGranted { App.app.restart() } - if screenRecording == .notGranted { + if screenRecordingIsGranted == .notGranted { // permission check may yield a false negative during wake-up // we restart after 2 negative checks if flakyCounter >= 2 { @@ -77,24 +91,24 @@ class SystemPermissions { } private static func checkPermissionsToUpdatePermissionsWindow(_ startupBlock: @escaping () -> Void) { - let accessibility = accessibilityIsGranted() - let screenRecording = screenRecordingIsGranted() - Logger.debug(accessibility, screenRecording, preStartupPermissionsPassed) - Menubar.togglePermissionCallout(screenRecording == .skipped) - if accessibility != App.app.permissionsWindow?.accessibilityView?.permissionStatus { - App.app.permissionsWindow?.accessibilityView.updatePermissionStatus(accessibility) + updateAccessibilityIsGranted() + updateScreenRecordingIsGranted() + Logger.debug(accessibilityIsGranted, screenRecordingIsGranted, preStartupPermissionsPassed) + Menubar.togglePermissionCallout(screenRecordingIsGranted == .skipped) + if accessibilityIsGranted != App.app.permissionsWindow?.accessibilityView?.permissionStatus { + App.app.permissionsWindow?.accessibilityView.updatePermissionStatus(accessibilityIsGranted) } - if #available(macOS 10.15, *), screenRecording != App.app.permissionsWindow?.screenRecordingView?.permissionStatus { - App.app.permissionsWindow?.screenRecordingView?.updatePermissionStatus(screenRecording) + if #available(macOS 10.15, *), screenRecordingIsGranted != App.app.permissionsWindow?.screenRecordingView?.permissionStatus { + App.app.permissionsWindow?.screenRecordingView?.updatePermissionStatus(screenRecordingIsGranted) } if !preStartupPermissionsPassed { - if accessibility != .notGranted && screenRecording != .notGranted { + if accessibilityIsGranted != .notGranted && screenRecordingIsGranted != .notGranted { preStartupPermissionsPassed = true App.app.permissionsWindow?.close() startupBlock() } } else { - if accessibility == .notGranted || screenRecording == .notGranted { + if accessibilityIsGranted == .notGranted || screenRecordingIsGranted == .notGranted { App.app.restart() } } diff --git a/src/ui/App.swift b/src/ui/App.swift index c9c90efe..0573f42b 100644 --- a/src/ui/App.swift +++ b/src/ui/App.swift @@ -196,7 +196,7 @@ class App: AppCenterApplication { } func refreshOpenUi(_ windowsToScreenshot: [Window], skipUpdatesBeforeShowing: Bool = false, onlyUpdateScreenshots: Bool = false) { - if !Appearance.hideThumbnails && !windowsToScreenshot.isEmpty { + if !Appearance.hideThumbnails && !windowsToScreenshot.isEmpty && SystemPermissions.screenRecordingIsGranted == .granted { Windows.refreshThumbnails(windowsToScreenshot, onlyUpdateScreenshots) return } diff --git a/src/ui/permission-window/PermissionsWindow.swift b/src/ui/permission-window/PermissionsWindow.swift index 695d62d1..64b1c061 100644 --- a/src/ui/permission-window/PermissionsWindow.swift +++ b/src/ui/permission-window/PermissionsWindow.swift @@ -12,9 +12,9 @@ class PermissionsWindow: NSWindow { } func show(_ startupBlock: @escaping () -> Void) { - accessibilityView.updatePermissionStatus(SystemPermissions.accessibilityIsGranted()) + accessibilityView.updatePermissionStatus(SystemPermissions.updateAccessibilityIsGranted()) if #available(macOS 10.15, *) { - screenRecordingView.updatePermissionStatus(SystemPermissions.screenRecordingIsGranted()) + screenRecordingView.updatePermissionStatus(SystemPermissions.updateScreenRecordingIsGranted()) } center() App.shared.activate(ignoringOtherApps: true) @@ -47,7 +47,7 @@ class PermissionsWindow: NSWindow { NSLocalizedString("This permission is needed to focus windows after you release the shortcut", comment: ""), NSLocalizedString("Open Accessibility Preferences…", comment: ""), "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility", - SystemPermissions.accessibilityIsGranted + SystemPermissions.updateAccessibilityIsGranted ) var rows = [ [header], @@ -60,7 +60,7 @@ class PermissionsWindow: NSWindow { NSLocalizedString("This permission is needed to show screenshots and titles of open windows", comment: ""), NSLocalizedString("Open Screen Recording Preferences…", comment: ""), "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture", - SystemPermissions.screenRecordingIsGranted, + SystemPermissions.updateScreenRecordingIsGranted, StackView(LabelAndControl.makeLabelWithCheckbox(NSLocalizedString("Use the app without this permission. Thumbnails won’t show.", comment: ""), "screenRecordingPermissionSkipped", labelPosition: .right)) ) rows.append([screenRecordingView]) @@ -76,7 +76,7 @@ extension PermissionsWindow: NSWindowDelegate { func windowWillClose(_ notification: Notification) { Logger.debug(SystemPermissions.preStartupPermissionsPassed) if !SystemPermissions.preStartupPermissionsPassed { - if SystemPermissions.accessibilityIsGranted() == .notGranted || SystemPermissions.screenRecordingIsGranted() == .notGranted { + if SystemPermissions.updateAccessibilityIsGranted() == .notGranted || SystemPermissions.updateScreenRecordingIsGranted() == .notGranted { Logger.error("Before using this app, you need to give permission in System Preferences > Security & Privacy > Privacy > Accessibility.", "Please authorize and re-launch.", "See https://help.rescuetime.com/article/59-how-do-i-enable-accessibility-permissions-on-mac-osx")