From c28f0617995ec958c9079fcaf3b69bbf8dc25187 Mon Sep 17 00:00:00 2001 From: Samuel Zielke Date: Wed, 21 Oct 2026 16:14:29 +0200 Subject: [PATCH] fix: start at launch, not when the main window appears As a login item macOS launched Musubi without its window, so the SwiftUI .task never ran: no outputs, no remote control after a reboot. An app delegate now starts discovery and the coordinator in applicationDidFinishLaunching. Co-Authored-By: Claude Opus 5.5 --- App/Sources/MusubiApp.swift | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/App/Sources/MusubiApp.swift b/App/Sources/MusubiApp.swift index 72fc566..f29a36e 100644 --- a/App/Sources/MusubiApp.swift +++ b/App/Sources/MusubiApp.swift @@ -1,3 +1,4 @@ +import AppKit import DesignSystem import NDIKit import OSLog @@ -5,31 +6,35 @@ import SwiftUI @main struct MusubiApp: App { - @State private var sourceList = SourceListModel() - @State private var coordinator: Coordinator = { - MainActor.assumeIsolated { - Coordinator(settings: AppSettings(), outputs: OutputController(), audio: AudioController()) - } - }() + @NSApplicationDelegateAdaptor private var appDelegate: AppDelegate var body: some SwiftUI.Scene { Window("Musubi", id: "main") { - ContentView(sourceList: sourceList, coordinator: coordinator) + ContentView(sourceList: appDelegate.sourceList, coordinator: appDelegate.coordinator) .preferredColorScheme(.dark) - .task { - sourceList.start() - await coordinator.start() - } } .defaultSize(width: 960, height: 600) Settings { - SettingsView(coordinator: coordinator) + SettingsView(coordinator: appDelegate.coordinator) .preferredColorScheme(.dark) } } } +/// Starts discovery, outputs, audio and remote control at launch – independent of any window. +/// As a login item macOS may launch Musubi without opening its window. +@MainActor +final class AppDelegate: NSObject, NSApplicationDelegate { + let sourceList = SourceListModel() + let coordinator = Coordinator(settings: AppSettings(), outputs: OutputController(), audio: AudioController()) + + func applicationDidFinishLaunching(_ notification: Notification) { + sourceList.start() + Task { await coordinator.start() } + } +} + enum Log { static let ndi = Logger(subsystem: "studio.zielke.musubi", category: "ndi") static let audio = Logger(subsystem: "studio.zielke.musubi", category: "audio")