Context: the launcher .app needs (a) a real icon visible in Dock /
Mission Control / Finder when its log window is open, and (b) a binary
that runs on both Intel MBPs (the current target on the 192.168.0.189
machine) and Apple Silicon. Initial build was arm64-only.
Approach: SVG icon rendered via librsvg into a multi-size .iconset,
packed into AppIcon.icns by iconutil (no Xcode asset catalog needed).
build.sh now compiles for both arm64 and x86_64 separately and lipos
them into a fat binary before bundling. The icon is regenerated only
when the SVG is newer than the existing .icns. Also switched the
default oscope-of binary path to look inside the .app bundle that
oF Release produces, with a walk-up-to-bin/ heuristic for the cwd.
Changes:
- Resources/icon.svg : 1024x1024 design — orange electron with
asymmetric googly eyes, sticking-out tongue, three rotated chaotic
orbital ellipses (cyan / purple / pink), radiating yellow lightning
bolts and scattered sparks on a dark purple radial gradient with
Big-Sur rounded-rect mask
- Resources/make_icon.sh : rsvg-convert at 16/32/128/256/512 px @1x
and @2x, then iconutil -c icns
- Resources/Info.plist : CFBundleIconFile = AppIcon
- build.sh : iterate ARCHS (default 'arm64 x86_64'), build each, lipo
-create them, regen icon if SVG is newer, copy AppIcon.icns into
Contents/Resources
- ProcessManager.swift :
* default oscopePath now prefers
.../bin/oscope-of.app/Contents/MacOS/oscope-of (the bundle that
openFrameworks produces) with fallback to bare binary
* new oscopeProjectRoot(from:) walks up the path to find the parent
of 'bin/', so cwd is the oF project root regardless of bundle vs
bare binary, letting oF locate bin/data/
- .gitignore : exclude generated AppIcon.iconset and AppIcon.icns
Impact: ./build.sh now produces a universal .app that launches on both
arm64 and Intel macs (smoke-tested on Big Sur Intel MBP). The icon
appears in the Dock when the log window is open, and oscope-of starts
correctly regardless of how it was built.
Context: AV-Live needs a single-click way to boot its two heavy
components (the SuperCollider sound engine and the openFrameworks
oscope-of visualizer) together, with their logs aggregated in one
place. Running them by hand from terminal during a live set is fragile.
Approach: Swift Package Manager + a small build.sh that wraps the
release binary into a real .app bundle (Info.plist with LSUIElement=true
to keep it out of the Dock). The UI uses NSStatusItem + NSPopover so
it works back to macOS 11 (Big Sur) — MenuBarExtra would require 13+
which the current target MBP can't run.
Changes:
- launcher/Package.swift : SwiftPM manifest, single executable target,
macOS 11 minimum
- AVLiveLauncherApp.swift : @main App + AppDelegate that owns the
status item, popover and lazily-created log window
- ProcessManager.swift : ObservableObject spawning sclang and oscope-of
via Foundation Process, capturing stdout/stderr through Pipe +
readabilityHandler, ring-buffered log array (2000 lines), termination
handlers that flip @Published flags back. Paths persisted in
UserDefaults with sane defaults
- MenuBarContent.swift : popover view with two ProcessRow toggles,
Logs / Paths / Quit, Settings sheet using NSOpenPanel
- LogView.swift : separate window with filter, auto-scroll, color-coded
source column, monospaced font. #available guard for textSelection
- Info.plist : bundle id cc.saillant.AVLiveLauncher, GPL-3 copyright,
LSUIElement true, min macOS 11
- build.sh : swift build -c release, copies binary + Info.plist into
AVLiveLauncher.app, ad-hoc codesigns
- .gitignore + README
Impact: 'cd launcher && ./build.sh && open build/AVLiveLauncher.app'
gives a working .app that brings up the AV stack from the menubar.
Smoke-tested on arm64 — Intel MBP needs a local build or a future
universal -arch x86_64 flag in build.sh.