forked from 1b-agent/opencadstudio-upstream
macOS: add a launcher shim so a cold Finder open also works (#1039)
The previous commit's Apple Event handler only ever catches an open sent to an already-running process. A cold double-click (app not running yet) still failed: every registration point tried inside the real binary — before app::run(), on the Subscription's first poll, even the literal first statement of main() — reliably caught a warm open but never the original cold-launch event. A raw AEInstallEventHandler in a separate, minimal, non-AppKit process (no winit/iced, just a manual CFRunLoopRunInMode pump) still missed it too, ruling out "the real binary's heavy dependency graph loading before main() wins the race" as the explanation. What does reliably catch a cold launch, verified against real Finder-equivalent opens: a from-scratch NSApplication with its own delegate implementing application:openURLs: — in a process where we own setDelegate: from the start, with no contention over the single delegate slot winit already claims. That has to be a separate process from the real GUI binary (only one -[NSApplication run] call can own a process), so src/bin/ocs_launcher.rs is now the .app's actual CFBundleExecutable: a small, dependency-light binary (no iced, wgpu, or cadkernel) whose only job is to catch the open and relay it. Relaying by replacing this process's image (exec, same PID) or by spawning a child and exiting turned out to both be dead ends: Launch Services tracks "the running instance of this bundle" by the Application Serial Number it handed out to whichever process it actually launched — this launcher, not whatever it execs into or spawns. Once the launcher's own ASN stopped pointing at a live, listening process, every later open Finder tried to deliver silently went nowhere (measured with lsappinfo against a real second "Open With", not assumed). So the launcher now stays running for the app's session — invisible, via NSApplicationActivationPolicyAccessory, since it owns no window — and relays every open (cold or warm) over the same channel a second CLI invocation already uses: io::single_instance. That relay only worked once single_instance's rendezvous key stopped being computed from the running executable's own path. That was fine when one binary always did the job, but the launcher and the real binary are different executables and independently computed different ports, so they could never find each other. Anchor the key on the enclosing .app bundle instead, shared by both. packaging/build_macos_signed.sh and .github/workflows/release.yml now build ocs_launcher and place it at Contents/MacOS/OpenCADStudio (the CFBundleExecutable Info.plist already names), with the real GUI binary renamed to Contents/MacOS/OpenCADStudio-App alongside it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b617734d5c
commit
e767507850
6 files changed
+249
-14
No files matched your search
@@ -337,6 +337,9 @@ jobs:
|
||||
run: |
|
||||
cargo build --locked --release --target aarch64-apple-darwin
|
||||
cargo build --locked --release --target aarch64-apple-darwin -p dwg-thumbnailer
|
||||
# The launcher shim is the .app's actual CFBundleExecutable (#1039)
|
||||
# — see src/bin/ocs_launcher.rs for why.
|
||||
cargo build --locked --release --target aarch64-apple-darwin --bin ocs_launcher
|
||||
|
||||
- name: Build .icns from SVG
|
||||
run: |
|
||||
@@ -395,8 +398,13 @@ jobs:
|
||||
APP=OpenCADStudio.app
|
||||
rm -rf "$APP"
|
||||
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" "$APP/Contents/PlugIns"
|
||||
cp target/aarch64-apple-darwin/release/OpenCADStudio "$APP/Contents/MacOS/OpenCADStudio"
|
||||
chmod +x "$APP/Contents/MacOS/OpenCADStudio"
|
||||
# The launcher is CFBundleExecutable (Finder always launches it,
|
||||
# for both document opens and plain launches); it execs into the
|
||||
# real GUI binary, renamed alongside it, over argv. See
|
||||
# src/bin/ocs_launcher.rs.
|
||||
cp target/aarch64-apple-darwin/release/ocs_launcher "$APP/Contents/MacOS/OpenCADStudio"
|
||||
cp target/aarch64-apple-darwin/release/OpenCADStudio "$APP/Contents/MacOS/OpenCADStudio-App"
|
||||
chmod +x "$APP/Contents/MacOS/OpenCADStudio" "$APP/Contents/MacOS/OpenCADStudio-App"
|
||||
cp AppIcon.icns "$APP/Contents/Resources/AppIcon.icns"
|
||||
cp DWG.icns DXF.icns "$APP/Contents/Resources/"
|
||||
# QuickLook thumbnail extension.
|
||||
|
||||
Reference in new issue
Block a user