diff --git a/AudioPriorityBar/AudioPriorityBarApp.swift b/AudioPriorityBar/AudioPriorityBarApp.swift index 3f455e9..5afa34b 100644 --- a/AudioPriorityBar/AudioPriorityBarApp.swift +++ b/AudioPriorityBar/AudioPriorityBarApp.swift @@ -1,5 +1,6 @@ import SwiftUI import CoreAudio +import AVFoundation @main struct AudioPriorityBarApp: App { @@ -171,6 +172,30 @@ class AudioManager: ObservableObject { applyHighestPriorityInput() applyHighestPriorityOutput() } + requestMicrophoneAccess() + } + + /// macOS hides input device streams from apps without Microphone permission, + /// so input devices won't appear until access is granted. Request it on launch + /// and refresh the device list once the user responds. + private func requestMicrophoneAccess() { + switch AVCaptureDevice.authorizationStatus(for: .audio) { + case .authorized: + break + case .notDetermined: + AVCaptureDevice.requestAccess(for: .audio) { [weak self] _ in + Task { @MainActor in + guard let self else { return } + self.refreshDevices() + self.refreshMuteStatus() + if !self.isCustomMode { + self.applyHighestPriorityInput() + } + } + } + default: + break + } } private func setupMuteVolumeListener() { diff --git a/AudioPriorityBar/Info.plist b/AudioPriorityBar/Info.plist index 3aed840..33bf578 100644 --- a/AudioPriorityBar/Info.plist +++ b/AudioPriorityBar/Info.plist @@ -24,5 +24,7 @@ public.app-category.utilities LSUIElement + NSMicrophoneUsageDescription + Audio Priority Bar needs microphone access to list and manage your input (microphone) devices. diff --git a/AudioPriorityBar/Views/MenuBarView.swift b/AudioPriorityBar/Views/MenuBarView.swift index 3ad55c2..4e8ee74 100644 --- a/AudioPriorityBar/Views/MenuBarView.swift +++ b/AudioPriorityBar/Views/MenuBarView.swift @@ -2,8 +2,16 @@ import SwiftUI import CoreAudio import AppKit +private struct ContentHeightKey: PreferenceKey { + static var defaultValue: CGFloat = 0 + static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { + value = max(value, nextValue()) + } +} + struct MenuBarView: View { @EnvironmentObject var audioManager: AudioManager + @State private var contentHeight: CGFloat = 0 var body: some View { VStack(spacing: 0) { @@ -81,8 +89,14 @@ struct MenuBarView: View { } .padding(.horizontal, 16) .padding(.vertical, 14) + .background( + GeometryReader { proxy in + Color.clear.preference(key: ContentHeightKey.self, value: proxy.size.height) + } + ) } - .frame(maxHeight: 420) + .frame(height: min(max(contentHeight, 1), 420)) + .onPreferenceChange(ContentHeightKey.self) { contentHeight = $0 } Divider() .padding(.horizontal, 12)