Skip to content

fix(auto-launch): clean up legacy macOS login items left by pre-#462 builds#2361

Open
marovole wants to merge 1 commit intofarion1231:mainfrom
marovole:fix/auto-launch-legacy-migration
Open

fix(auto-launch): clean up legacy macOS login items left by pre-#462 builds#2361
marovole wants to merge 1 commit intofarion1231:mainfrom
marovole:fix/auto-launch-legacy-migration

Conversation

@marovole
Copy link
Copy Markdown

Problem

#462 fixed auto_launch.rs to register the .app bundle path on macOS so login items don't open via Terminal.app. However, users who had auto-launch enabled before that fix still have a broken login item that points at the inner Unix executable:

/Applications/CC Switch.app/Contents/MacOS/cc-switch

That path makes LaunchServices treat the entry as a Unix Executable File, so every login spawns a Terminal window full of cc-switch's startup logs. The legacy entry also uses the old display name cc-switch (lowercase, hyphen) while current code uses CC Switch — meaning:

  • is_auto_launch_enabled() returns false (the in-app toggle shows "off"), and
  • disable_auto_launch() can't see the legacy item to remove it,

so the broken state is invisible from inside the app and persists indefinitely. Reproduced on cc-switch 3.14.1 upgraded from a pre-#462 install:

$ osascript -e 'tell application "System Events" to get the path of login item "cc-switch"'
/Applications/CC Switch.app/Contents/MacOS/cc-switch
$ osascript -e 'tell application "System Events" to get the kind of login item "cc-switch"'
Unix Executable File

Fix

Add a one-shot self-heal called from the Tauri setup hook:

src-tauri/src/auto_launch.rs — new migrate_legacy_macos_login_items():

  1. Runs an AppleScript that looks for login items named cc-switch or CC Switch whose path contains /Contents/MacOS/. That path shape is unambiguously the buggy one — no .app bundle ever has its bundle path inside Contents/MacOS/.
  2. Deletes the matching entries.
  3. If anything was removed, calls enable_auto_launch() to re-register with the proper .app bundle path so the user keeps their original auto-launch preference.

The AppleScript uses try blocks so a missing item is not an error. On non-macOS targets the function is a no-op.

src-tauri/src/lib.rs — invoke once from setup, right after the log plugin is configured so the migration log line is captured.

The migration only fires when a buggy entry is actually found (returns early otherwise), and it never touches login items that don't match the cc-switch display names.

Tests

running 5 tests
test auto_launch::tests::test_migrate_legacy_login_items_compiles_on_macos ... ok
test auto_launch::tests::test_get_macos_app_bundle_path_not_in_bundle ... ok
test auto_launch::tests::test_get_macos_app_bundle_path_dev_build ... ok
test auto_launch::tests::test_get_macos_app_bundle_path_valid ... ok
test auto_launch::tests::test_get_macos_app_bundle_path_with_spaces ... ok

test result: ok. 5 passed; 0 failed

The AppleScript path itself is intentionally not exercised in cargo test because it would mutate the developer's actual login items; the test ensures the function stays compileable and reachable.

Manual verification plan for reviewer

On a macOS host that has the buggy state (or simulated via osascript -e 'tell application "System Events" to make login item at end with properties {name:"cc-switch", path:"/Applications/CC Switch.app/Contents/MacOS/cc-switch", hidden:false}'):

  1. Launch the dev build → log shows ✓ Removed legacy macOS login item … and ✓ Re-registered auto-launch using the .app bundle path.
  2. Verify osascript -e 'tell application "System Events" to get the path of every login item whose name is "CC Switch"' now returns the .app bundle path.
  3. Re-launch → migration is silent (no false repeat).

Note on UX choice

The migration runs silently rather than prompting the user — the buggy state is unambiguously wrong and the heal preserves the user's intent (enable_auto_launch after delete). Happy to swap in a one-time toast/notification if you'd prefer something more visible.

…n1231#462 builds

PR farion1231#462 made auto-launch register the .app bundle path on macOS, which
prevents login items from being opened via Terminal.app. However, users
who had auto-launch enabled before that fix retain a stale login item
that points at the inner Unix executable
(/Applications/CC Switch.app/Contents/MacOS/cc-switch). Every login
keeps spawning a Terminal window full of cc-switch's startup logs.

The stale item also uses the legacy display name "cc-switch" while the
current code looks it up under "CC Switch", so:

  * is_auto_launch_enabled() returns false (UI shows "off")
  * the broken item is invisible to disable_auto_launch()
  * the user has no in-app way to clean it up

This adds migrate_legacy_macos_login_items(), called once during the
Tauri setup hook. It uses System Events / AppleScript to look for any
login item named "cc-switch" or "CC Switch" whose path contains
/Contents/MacOS/ (the only path shape that triggers the bug), removes
it, then re-registers auto-launch via the existing enable path so the
user keeps their preference. On non-macOS targets it's a no-op.
Copy link
Copy Markdown
Owner

@codex review

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db7e4e8285

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +142 to +143
match enable_auto_launch() {
Ok(()) => log::info!("✓ Re-registered auto-launch using the .app bundle path"),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve user-off state when repairing legacy login items

After any legacy entry is deleted, the migration unconditionally calls enable_auto_launch(). This can flip auto-launch back on for users who had previously tried to turn it off in newer builds (e.g., they toggled on/off, which removes only the new CC Switch item but leaves the old cc-switch item). In that scenario, startup-on-login is reintroduced without user consent, so migration should avoid re-enabling unless there is a reliable signal that the current preference is still enabled.

Useful? React with 👍 / 👎.

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.

2 participants