fix: stop SCShareableContent polling loop that spammed screen recording prompt#20
Merged
Merged
Conversation
…ng prompt PermissionCenter.refreshAsync() was calling SCShareableContent.excludingDesktopWindows() every 3 seconds in the background polling task. On macOS, calling that API when screen recording hasn't been granted yet triggers the TCC permission dialog. On a fresh install or a non-dev machine this created an infinite loop: a new permission dialog every 3 seconds. Fix: - refreshAsync() now polls with CGPreflightScreenCaptureAccess() only. This reads the live TCC database state without triggering any dialog. The macOS 15+ per-process cache is invalidated by TCC database changes, so a grant made in System Settings appears within one polling cycle (≤3 s) without needing SCShareableContent. - Rename checkScreenCapturePermission() → checkScreenCapturePermissionLive() and add a prominent WARNING in the doc comment: this function triggers the TCC dialog and must only be called from a direct user action, never from a polling loop. - In openScreenCaptureSettings(), keep the one-shot post-grant check (it's user-initiated so it's safe) but: (a) try the fast sync path first, (b) increase the delay from 1 s to 3 s so the SCShareableContent call fires after the user has returned from System Settings, not mid-interaction. https://claude.ai/code/session_01XVfXe31wxQrYWMnQaTpAcy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PermissionCenter.refreshAsync() was calling SCShareableContent.excludingDesktopWindows()
every 3 seconds in the background polling task. On macOS, calling that API when screen
recording hasn't been granted yet triggers the TCC permission dialog. On a fresh install
or a non-dev machine this created an infinite loop: a new permission dialog every 3 seconds.
Fix:
refreshAsync() now polls with CGPreflightScreenCaptureAccess() only. This reads the
live TCC database state without triggering any dialog. The macOS 15+ per-process cache
is invalidated by TCC database changes, so a grant made in System Settings appears
within one polling cycle (≤3 s) without needing SCShareableContent.
Rename checkScreenCapturePermission() → checkScreenCapturePermissionLive() and add a
prominent WARNING in the doc comment: this function triggers the TCC dialog and must
only be called from a direct user action, never from a polling loop.
In openScreenCaptureSettings(), keep the one-shot post-grant check (it's user-initiated
so it's safe) but: (a) try the fast sync path first, (b) increase the delay from 1 s
to 3 s so the SCShareableContent call fires after the user has returned from System
Settings, not mid-interaction.
https://claude.ai/code/session_01XVfXe31wxQrYWMnQaTpAcy