Skip to content

Dock icon stays after launch on macOS 27.0: accessory demotion silently fails #4101

Description

@tobihagemann

CodexBar shows up in the Dock on every launch since I'm on macOS 27.0 (26A428), and it stays there. CodexBar 0.68.0 (159), installed in /Applications, LSUIElement is true and LaunchServices has it registered as ui-element.

It happens on a clean quit and relaunch, not only after a Sparkle update. Polling NSWorkspace.runningApplications from a separate process right after open -a CodexBar:

0.53s policy=1   (accessory)
0.67s policy=0   (regular, Dock icon appears)
... stays 0 for the rest of the 40s poll

With CODEXBAR_STATUS_ITEM_DIAGNOSTICS=1, the startup trace reports activationPolicy: 1 on every line from will-finish-launching to startup-check, while lsappinfo reports the process as type="Foreground". The SwiftUI Settings placeholder ({{840, 580}, {900, 450}}) is visible: true from did-finish-launching through rendered, and false at startup-check.

So my reading is: the visible placeholder qualifies for promotion in shouldPromoteForPresentedWindow, the app goes .regular, and the later setActivationPolicy(.accessory) doesn't take effect.

That last part looks like an OS bug rather than CodexBar's logic. A minimal AppKit app with LSUIElement = true reproduces it on 27.0:

func applicationDidFinishLaunching(_ n: Notification) {
    NSApp.setActivationPolicy(.regular)       // returns true, Dock icon appears
    print(NSApp.activationPolicy().rawValue)  // still prints 1 (accessory)
    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
        print(NSApp.setActivationPolicy(.accessory))  // false, Dock icon stays
    }
}

The in-process getter never leaves .accessory, and the switch back to .accessory returns false. I also tried re-setting .regular first, calling NSApp.activate first, and going through .prohibited (with and without a delay). .prohibited takes effect, but .accessory never does. Peekaboo shows the same symptom for the same reason. I haven't compared against an older macOS, so I can't say for sure it's new in 27.0, but it only started for me after updating.

Since the demotion can't be relied on, avoiding the promotion in the first place would sidestep it. For example, not counting the empty SwiftUI Settings placeholder as a presented Settings window at launch. Happy to test a build if that helps.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal priority bug or improvement with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:queueable-fixClawSweeper marked this issue as an existing queue_fix_pr work candidate.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:ux-frictionUser-facing flow adds avoidable confusion or support burden without fully blocking progress.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.no-staleExempts this issue from stale automation.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions