"The app launched. The window appeared. But no dock icon, nothing in the app switcher, and it never came to the front. The app was fine — it just wasn't registered as an app."
The Triple Symptom
During development, the native window opened — but wrong in three linked ways. No icon in the dock. Missing from the application switcher. And it never became frontmost: it opened behind the terminal, and keystrokes kept routing to whatever app had focus before. Three symptoms, one cause, and the cause was not in the app's code at all. The app was correct; the way it was being launched was the problem.
A Bare Binary Is Not an App
The development command builds and runs a bare executable — a raw binary file — not a proper application bundle (the structured folder the operating system recognizes as 'an app'). The OS treats those two very differently. A bundle gets registered with the system's launch services as a normal, foreground-capable application. A bare binary skips all of that: the OS never registers it as a real app, so it gets no dock presence, no switcher entry, and no normal right to come to the front.
Why the Framework's Own Setting Didn't Help
The natural fix is to set the app's activation policy to 'regular' (foreground app) through the framework's configuration. But here's the trap: that framework-level setting didn't propagate to the live application object when the launch shape was a bare binary. The setting assumes it's running inside a proper bundle context; outside that context, it quietly fails to take effect. The configuration was correct and still didn't work, because the precondition it depends on wasn't there.
The Two Real Fixes
There are two ways out. The direct one: make a native call, at the system layer below the framework, that forces the activation policy to 'regular' and explicitly brings the app forward — bypassing the framework setting that wasn't propagating. The other: stop launching a bare binary and build a real application bundle, then run that, so the OS registers it properly from the start. The first fixes the dev loop in place; the second makes the dev artifact match the real one.
Don't Reach for the Wrong Knobs First
Under this kind of confusion, it's tempting to try every related-sounding configuration flag — force-focus this, always-on-top that. But those don't address the root cause (the app isn't a registered app), and at least one of them actively makes things worse: forcing always-on-top can break keyboard focus on top of the existing problem. The discipline is to fix the root (registration / activation policy) before touching cosmetic window flags that only paper over it.