diff --git a/Sources/Heard/MTApp.swift b/Sources/Heard/MTApp.swift index 6ab4172..a18c628 100644 --- a/Sources/Heard/MTApp.swift +++ b/Sources/Heard/MTApp.swift @@ -89,7 +89,7 @@ struct HeardApp: App { var body: some Scene { MenuBarExtra { MenuBarView(model: appModel) - .preferredColorScheme(appModel.settingsStore.settings.appearance.colorScheme) + .heardAppearance(appModel.settingsStore.settings.appearance) } label: { MenuBarIcon(model: appModel) } @@ -97,7 +97,7 @@ struct HeardApp: App { Window("Heard Settings", id: "settings") { SettingsView(model: appModel) - .preferredColorScheme(appModel.settingsStore.settings.appearance.colorScheme) + .heardAppearance(appModel.settingsStore.settings.appearance) .onAppear { WindowActivationCoordinator.begin("settings") } .onDisappear { WindowActivationCoordinator.end("settings") } } @@ -106,7 +106,7 @@ struct HeardApp: App { Window("Name Speakers", id: "speaker-naming") { SpeakerNamingView(model: appModel) - .preferredColorScheme(appModel.settingsStore.settings.appearance.colorScheme) + .heardAppearance(appModel.settingsStore.settings.appearance) .onAppear { WindowActivationCoordinator.begin("speaker-naming") } .onDisappear { WindowActivationCoordinator.end("speaker-naming") diff --git a/Sources/HeardCore/Views.swift b/Sources/HeardCore/Views.swift index 91d540b..5c942bf 100644 --- a/Sources/HeardCore/Views.swift +++ b/Sources/HeardCore/Views.swift @@ -37,6 +37,41 @@ public extension AppAppearance { } } +// MARK: - Appearance Modifier + +private struct AppearanceModifier: ViewModifier { + let appearance: AppAppearance + @State private var systemIsDark = NSApp.effectiveAppearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua + + func body(content: Content) -> some View { + content + .preferredColorScheme(resolvedScheme) + .onReceive( + DistributedNotificationCenter.default() + .publisher(for: NSNotification.Name("AppleInterfaceThemeChangedNotification")) + ) { _ in + // Short delay: effectiveAppearance may not yet reflect the change + DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { + systemIsDark = NSApp.effectiveAppearance.bestMatch(from: [.darkAqua, .aqua]) == .darkAqua + } + } + } + + private var resolvedScheme: ColorScheme? { + switch appearance { + case .system: systemIsDark ? .dark : .light + case .light: .light + case .dark: .dark + } + } +} + +public extension View { + func heardAppearance(_ appearance: AppAppearance) -> some View { + modifier(AppearanceModifier(appearance: appearance)) + } +} + // MARK: - Theme enum HeardTheme { @@ -2150,7 +2185,6 @@ public struct SpeakerNamingView: View { } .frame(width: 560) .background(HeardTheme.Paper.bg) - .preferredColorScheme(.light) .onAppear { startCountdown() } .onDisappear { stopAudio()