Skip to content

fix: request location permission on the main thread so SSIDs are not redacted - #22

Open
eliran-zada-evalon wants to merge 1 commit into
nolze:masterfrom
eliran-zada-evalon:fix/location-permission-main-thread
Open

fix: request location permission on the main thread so SSIDs are not redacted#22
eliran-zada-evalon wants to merge 1 commit into
nolze:masterfrom
eliran-zada-evalon:fix/location-permission-main-thread

Conversation

@eliran-zada-evalon

Copy link
Copy Markdown

What was the problem?

On macOS 14 Sonoma and later, Location permission is required to read Wi-Fi SSIDs. The app requested authorization in main() before webview.start() was called — i.e. before NSApplication's run loop was running.

CLLocationManager only shows the system authorization prompt and delivers its delegate callbacks while the main run loop is active. Because the request happened too early (and the wait loop used sleep(), which never pumps the run loop), the prompt never appeared, authorizationStatus() stayed at NotDetermined (0), and macOS kept returning redacted SSIDs (n/a, "MAC hidden"). The app also never registered in System Settings → Privacy & Security → Location Services, so the user couldn't grant access manually either.

A second, smaller bug: the delegate showed the "Location Services are disabled" dialog for both Denied and NotDetermined. NotDetermined simply means the user hasn't answered the system prompt yet, so the app's own dialog fired spuriously on first launch.

How we fixed it

  • Move the location-permission request out of main() and into startup(), and dispatch it onto the main thread via performSelectorOnMainThread: once NSApplication's run loop is live. This lets macOS actually present the system prompt and fire locationManagerDidChangeAuthorization:.
  • Keep the CLLocationManager and its delegate alive for the process lifetime (module-level references) so callbacks aren't lost to GC.
  • Short-circuit when the status is already AuthorizedAlways / AuthorizedWhenInUse.
  • Only show the custom "permission required" dialog on an actual Denied status — not on the transient NotDetermined state.

How we validated the fixes

  • Built the signed .app bundle (which carries NSLocationWhenInUseUsageDescription) via PyInstaller and launched it; the app now triggers the system location prompt / appears in Location Services, after which real SSIDs populate.
  • Verified that running the unbundled python -m dev entry point still behaves correctly (no spurious dialog on first launch).

Notes

  • SSID reading fundamentally requires the bundled .app (the Info.plist usage-description key); the unbundled python -m dev run cannot be granted location on Sonoma+. This PR makes the in-app request flow correct for the bundle.

Made with Cursor

CLLocationManager only shows the system authorization prompt and fires
its delegate callbacks while the main run loop is running. Requesting
authorization in main() before webview.start() meant the prompt never
appeared and authorizationStatus stayed NotDetermined, so macOS kept
redacting Wi-Fi SSIDs.

Move the request into startup() and dispatch it onto the main thread via
performSelectorOnMainThread once NSApplication's loop is live. Also
short-circuit when already authorized and only show the custom
"permission required" dialog on an actual Denied status (not on the
transient NotDetermined state).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant