Skip to content

macOS: Dock icon visible when app installed from .app bundle, but not in dev mode (menu-bar-only app) #15005

@gitvzz

Description

@gitvzz

Problem

We are building a menu-bar-only app (system tray, no windows). The app should NOT appear in the macOS Dock. This works in development but fails when running the installed app.

  • Dev mode (cargo tauri dev): Dock does NOT show icon ✓
  • Installed app (installed from DMG to Applications, launched by double-click): Dock DOES show icon ✗

Environment

  • Tauri v2
  • macOS (tested on Sequoia / Sonoma; exact version TBD)
  • App uses tray icon only (windows: [] in config), no webview windows

Root Cause Analysis

The difference comes from how the process is launched:

Dev mode (cargo tauri dev) Installed (double-click .app)
Launch path Binary executed directly by cargo (equivalent to terminal ./app) Launched via macOS Launch Services
Uses .app bundle No (runs from target/debug or target/release) Yes (from *.app/Contents/MacOS/)
Info.plist applied No Yes
Dock behavior Process launched as terminal subprocess → typically no Dock slot Launched as standard GUI app → Dock icon appears

Conclusion: In dev mode, the process is a child of cargo, so macOS does not assign a Dock slot. When launched via Finder/Launch Services, the system treats it as a normal GUI app and shows the Dock icon unless LSUIElement/activation policy is applied before Launch Services makes that decision.

Attempted Solutions (All Failed)

1. LSUIElement in Info.plist

  • Added LSUIElement = true in src-tauri/Info.plist (merged into built .app)
  • Verified with plutil -p that the built app contains LSUIElement => true
  • Result: Still shows in Dock when launched from Applications

2. set_activation_policy(ActivationPolicy::Accessory) in setup

  • Result: Works in dev, fails when installed

3. Early setActivationPolicy in main() via objc2 (before any Tauri init)

  • Result: Debug logs show policy is correctly set to Accessory, but Dock still shows

4. Call activateIgnoringOtherApps(true) after setActivationPolicy

  • Result: No effect

5. Reapply activation policy after 300ms (in case Tao resets it)

  • Result: Policy remains Accessory, not reset; Dock still shows

6. ActivationPolicy::Prohibited instead of Accessory

  • Result: No effect

7. app.set_dock_visibility(false) in setup

  • Result: No effect

8. TransformProcessType(..., kProcessTransformToUIElementApplication) at the very start of main()

  • Result: No effect

Hypothesis

  • LSUIElement should work at the OS level (e.g. Electron docs state it does), but it does not for this Tauri build. Possible causes:
    • Tao/WRY creates something (hidden webview for tray?) that triggers Dock registration before plist is honored
    • Initialization order issue
  • Runtime APIs (set_activation_policy, set_dock_visibility) run too late relative to Launch Services’ decision

Request

Could the Tauri/Tao team investigate and add proper support for menu-bar-only apps that should never show in the Dock when launched from the .app bundle? This is a common pattern (e.g. Dropbox, many menu bar utilities).

Related

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions