From 12dacc877d701e024d94d59668e180bf250e954a Mon Sep 17 00:00:00 2001 From: luw2007 Date: Thu, 10 Sep 2026 22:39:55 +0800 Subject: [PATCH] Fix repeated permission prompts when already authorized CGPreflightScreenCaptureAccess() is unreliable on macOS 14+ for ad-hoc signed apps, often returning false even when permission is granted. When the ScreenCaptureKit probe returns an indeterminate (.unknown) result, the app was resetting its 'previously granted' evidence, causing repeated permission prompts on subsequent launches. Fix: - persistResolvedState: don't reset granted evidence on .unknown, only on definitive .denied - resolveState: when probe returns .unknown but persisted 'previouslyGranted' flag is true (or in-memory grant evidence exists), return .granted instead of .unknown This prevents transient probe failures from triggering repeated permission dialogs when the user has already granted screen recording access. --- .../Services/ScreenPermissionService.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/ScreenTextGrab/Services/ScreenPermissionService.swift b/ScreenTextGrab/Services/ScreenPermissionService.swift index 87d637a..da0f660 100644 --- a/ScreenTextGrab/Services/ScreenPermissionService.swift +++ b/ScreenTextGrab/Services/ScreenPermissionService.swift @@ -104,6 +104,16 @@ final class ScreenPermissionService: ScreenPermissionProviding { persistResolvedState(resolvedState) return resolvedState case .unknown: + // Probe returned indeterminate result. If we have prior confirmed grant + // evidence (persisted across launches), trust it — CGPreflightScreenCaptureAccess + // and ScreenCaptureKit probes can be transiently unreliable on macOS 14+ for + // ad-hoc signed apps. + let previouslyGranted = defaults.bool(forKey: Self.permissionPreviouslyGrantedKey) + if lastConfirmedGrantAt != nil || previouslyGranted { + lastResolvedState = .granted + persistResolvedState(.granted) + return .granted + } let resolvedState: ScreenPermissionState = needsRestartAfterGrant ? .requiresRestart : .unknown lastResolvedState = resolvedState persistResolvedState(resolvedState) @@ -266,11 +276,17 @@ final class ScreenPermissionService: ScreenPermissionProviding { case .granted, .requiresRestart: defaults.set(true, forKey: Self.autoPromptAttemptedKey) defaults.set(true, forKey: Self.permissionPreviouslyGrantedKey) - case .denied, .unknown: + case .denied: if previouslyGranted { defaults.set(false, forKey: Self.autoPromptAttemptedKey) defaults.set(false, forKey: Self.permissionPreviouslyGrantedKey) } + case .unknown: + // Probe returned indeterminate result; preserve previously granted state + // instead of resetting. CGPreflightScreenCaptureAccess is unreliable on + // macOS 14+ for ad-hoc signed apps, and transient probe failures should + // not cause repeated permission prompts. + break case .requestInProgress: break }