Skip to content

feat(settings): Launch at login via SMAppService in Settings#5

Merged
cuiko merged 4 commits into
mainfrom
feat/launch-at-login-setting
Jun 5, 2026
Merged

feat(settings): Launch at login via SMAppService in Settings#5
cuiko merged 4 commits into
mainfrom
feat/launch-at-login-setting

Conversation

@cuiko

@cuiko cuiko commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a Launch at login checkbox to Settings → General → Application.
  • Back it with SMAppService.mainApp (macOS 13+) instead of a hand-written LaunchAgent plist, so the entry lands in System Settings → Login Items under "Open at Login" with the real app icon and name — not in "Allow in the Background" as a raw exec from an "unidentified developer".
  • Remove the now-redundant "Launch at Login" item from the status menu; the Settings checkbox is the single entry point, so there's nothing to keep in sync.
  • setEnabled clears any stale ~/Library/LaunchAgents/top.cuiko.termims.plist from older builds so migrating users aren't launched twice.

Why

Launch-at-login was only reachable from the status menu, which vanishes when "Hide menu bar icon" is on. Moving it to Settings fixes the access gap; switching to SMAppService fixes the wrong-section / wrong-icon / unidentified-developer presentation that the legacy plist caused.

Test plan

  • make build clean
  • make run — Settings → General shows "Launch at login" under Application
  • Tick it → TermIMS appears under Open at Login (top section) in System Settings → General → Login Items, with the TermIMS icon
  • Untick → entry disappears
  • Upgrading from a build that wrote the LaunchAgent plist: ticking once removes the stale ~/Library/LaunchAgents/top.cuiko.termims.plist

Note

Ad-hoc signing means macOS may still surface an approval prompt on first registration (toggle the switch in System Settings if so). A clean "identified developer" label needs Developer ID signing + notarization, which is out of scope here.

cuiko added 3 commits June 5, 2026 17:23
Launch-at-login was only reachable from the status-bar menu, which is
hidden entirely when the user enables "Hide menu bar icon" — leaving no
way to change the setting from the UI. Surface it as a checkbox in
Settings → General → Application alongside the hide-icon option.

Extract the LaunchAgent plist read/write out of AppDelegate into a
shared LaunchAtLogin helper so the menu item and the new checkbox read
and mutate the same source of truth (the plist's presence), keeping the
two controls in agreement without a separate stored flag.
Ticking the new Settings checkbox wrote the LaunchAgent plist but left
the status menu's "Launch at Login" item showing its stale state until
the next unrelated menu rebuild. Unlike the RuleStore-backed settings,
launch-at-login has no setter that posts a change notification.

Post .rulesDidChange after the toggle so AppDelegate rebuilds the menu
and re-reads LaunchAtLogin.isEnabled, matching how the store-backed
toggles already keep the menu in sync. The extra FocusMonitor.reload
this triggers is a cheap no-op when the observed bundle set is unchanged.
The plist-based LaunchAgent put TermIMS in System Settings' "Allow in
the Background" list as a raw exec entry attributed to an "unidentified
developer", because the agent pointed at the inner Mach-O rather than
the app bundle. Switch to SMAppService.mainApp (macOS 13+), which
registers the bundle itself so it shows up under "Open at Login" with
the real icon and name. setEnabled also clears any stale LaunchAgent
plist from older builds so migrating users aren't launched twice.

With the Settings checkbox now the single entry point, remove the
"Launch at Login" item (and its toggleLogin handler / loginItem
property) from the status menu so there's nothing to keep in sync.
@cuiko cuiko changed the title feat(settings): Add Launch at login toggle to General tab feat(settings): Launch at login via SMAppService in Settings Jun 5, 2026
The General tab is built once and the window controller is cached, so a
launch-at-login change made outside the app — most notably the user
removing TermIMS from System Settings → Login Items — left the checkbox
showing a stale state on the next open. macOS posts no notification when
our login item is toggled externally, so there's nothing to observe.

Re-read the live SMAppService status on NSWindow.didBecomeKeyNotification
so the checkbox reflects reality every time the Settings window comes
forward.
@cuiko
cuiko merged commit 8589f94 into main Jun 5, 2026
1 check passed
@cuiko
cuiko deleted the feat/launch-at-login-setting branch June 5, 2026 14:06
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