Skip to content

feat: route links from a menu-bar popover as the default browser - #1

Merged
TerrifiedBug merged 8 commits into
mainfrom
feat/v2-menu-router
Aug 27, 2026
Merged

TerrifiedBug merged 8 commits into
mainfrom
feat/v2-menu-router

Conversation

@TerrifiedBug

@TerrifiedBug TerrifiedBug commented Aug 27, 2026 •

Copy link
Copy Markdown
Owner

Route http/https as the macOS default browser from a menu-bar popover. Chrome BrowserSwitcher and ~/.config/browseroute/config.json are gone.

This branch also:

  • Adds Sparkle 2.9.6 as an SPM dependency and embeds Sparkle.framework at package time. Check for Updates stays disabled until a real SUPublicEDKey is baked in (the placeholder still starts with REPLACE_).
  • Retargets Scripts/package_app.sh at Scripts/build-release.sh.
  • Sizes the popover from a macOS 14-safe GeometryReader + PreferenceKey so the Routing toggle does not stretch the browser-config screen.

Verified locally:

  • make check — lint, app swift build, 19 tests.
  • SKIP_NOTARIZE=1 dry-run of ./Scripts/build-release.sh — universal build, Sparkle inside-out sign, codesign --verify passes, zip in dist/.

Not in this PR (needed before tagging v*):

  • GitHub release environment + secrets (DEVELOPER_ID_APP_P12_BASE64, DEV_ID_P12_PASSWORD, APP_IDENTITY, NOTARY_KEY_P8_BASE64, NOTARY_KEY_ID, NOTARY_ISSUER_ID, HOMEBREW_TAP_TOKEN).
  • Real Sparkle EdDSA key in SUPublicEDKey + SPARKLE_PRIVATE_KEY for appcast signing.

Add Sparkle as an SPM dependency so Check for Updates can compile,
point package_app.sh at build-release.sh, and hug popover height from
onGeometryChange instead of fittingSize.
onGeometryChange is macOS 15+. The popover already uses fixedSize, so a
background GeometryReader reports the same intrinsic height. make check
now also swift-builds the app target so this cannot slip past tests.
swift test only compiles BrowserouteCore. CI also swift-builds the app
target, so check must too — otherwise MenuView/Router never hit the
pre-push gate.
Render the charcoal squircle at 1024, emit a classic Icon.iconset
(16 through 512@2x), and compile Icon.icns so About/Finder stop using
the generic executable glyph. package_app.sh rebuilds the icns from
the iconset. README uses the same mark.

Settings shows a checked Default Browser row when Browseroute already
owns https, instead of a greyed-out button. Claiming https first avoids
a second confirmation dialog for http.
The checkmark used only https, so accepting that dialog and cancelling
http still showed Default Browser while http:// links stayed in Chrome.
Both schemes must match. After a successful https claim, always request
http too — probing LaunchServices immediately is a race.
Clicking Set as Default Browser called setDefaultApplication while the
transient popover was closing. LaunchServices cancelled in ~12ms, so
the system prompt never appeared. Claim from a long-lived helper,
switch to a regular activation policy for the prompt, and ignore
resign-active / click-outside until it finishes.
macOS treats http and https as one default-browser setting. Claiming
https first failed with NSCocoaErrorDomain 256 ("The file couldn’t be
opened.") and never showed the confirmation dialog. Claim http only;
the checkmark still requires both schemes.
urlForApplication(withBundleIdentifier:) can return build/ or dist/
instead of the process that is actually running. Claim Bundle.main so
the checkmark and the handler point at the same app.
@TerrifiedBug
TerrifiedBug merged commit f6d2a00 into main Aug 27, 2026
1 check passed
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