import Cocoa import SwiftUI class HUDPanel { private var panel: NSPanel? private var hideTimer: Timer? private let hudSize = NSSize(width: 200, height: 200) func show(volume: Float, isMuted: Bool) { hideTimer?.invalidate() if panel == nil { createPanel() } guard let panel = panel else { return } // Update content let hostingView = NSHostingView(rootView: HUDView(volume: volume, isMuted: isMuted)) hostingView.frame = NSRect(origin: .zero, size: hudSize) panel.contentView = hostingView // Center on main screen if let screen = NSScreen.main { let screenFrame = screen.visibleFrame let x = screenFrame.midX - hudSize.width / 2 let y = screenFrame.midY - hudSize.height / 2 panel.setFrameOrigin(NSPoint(x: x, y: y)) } // Show panel.alphaValue = 1.0 panel.orderFrontRegardless() // Auto-hide after 1.5s hideTimer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in self?.fadeOut() } } private func createPanel() { let panel = NSPanel( contentRect: NSRect(origin: .zero, size: hudSize), styleMask: [.borderless, .nonactivatingPanel], backing: .buffered, defer: false ) panel.level = .floating panel.isOpaque = false panel.backgroundColor = .clear panel.hasShadow = true panel.hidesOnDeactivate = false panel.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary, .ignoresCycle] panel.isMovableByWindowBackground = false panel.ignoresMouseEvents = true self.panel = panel } private func fadeOut() { guard let panel = panel else { return } NSAnimationContext.runAnimationGroup({ context in context.duration = 0.4 panel.animator().alphaValue = 0.0 }, completionHandler: { [weak self] in self?.panel?.orderOut(nil) }) } }