Initial commit: HUDini — classic volume HUD for macOS

Menu bar utility that shows a centered HUD overlay with volume bars
when system volume changes. CoreAudio monitoring, auto-fade, works
on all spaces and fullscreen.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
johnfrum1234 2026-03-10 13:28:41 +02:00
commit cee343dd96
9 changed files with 497 additions and 0 deletions

View file

@ -0,0 +1,70 @@
import Cocoa
import SwiftUI
class AppDelegate: NSObject, NSApplicationDelegate {
private var statusItem: NSStatusItem!
private var volumeMonitor: VolumeMonitor!
private var hudPanel: HUDPanel!
func applicationDidFinishLaunching(_ notification: Notification) {
// Hide from Dock
NSApp.setActivationPolicy(.accessory)
setupStatusBar()
setupHUD()
setupVolumeMonitor()
}
private func setupStatusBar() {
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.squareLength)
if let button = statusItem.button {
button.image = NSImage(systemSymbolName: "speaker.wave.2.fill", accessibilityDescription: "HUDini")
button.image?.size = NSSize(width: 18, height: 18)
}
let menu = NSMenu()
menu.addItem(NSMenuItem(title: "HUDini", action: nil, keyEquivalent: ""))
menu.addItem(NSMenuItem.separator())
let enabledItem = NSMenuItem(title: "Enabled", action: #selector(toggleEnabled(_:)), keyEquivalent: "e")
enabledItem.state = .on
enabledItem.target = self
menu.addItem(enabledItem)
menu.addItem(NSMenuItem.separator())
let quitItem = NSMenuItem(title: "Quit", action: #selector(quit), keyEquivalent: "q")
quitItem.target = self
menu.addItem(quitItem)
statusItem.menu = menu
}
private func setupHUD() {
hudPanel = HUDPanel()
}
private func setupVolumeMonitor() {
volumeMonitor = VolumeMonitor { [weak self] volume, isMuted in
DispatchQueue.main.async {
self?.hudPanel.show(volume: volume, isMuted: isMuted)
}
}
volumeMonitor.start()
}
@objc private func toggleEnabled(_ sender: NSMenuItem) {
if sender.state == .on {
sender.state = .off
volumeMonitor.stop()
} else {
sender.state = .on
volumeMonitor.start()
}
}
@objc private func quit() {
volumeMonitor.stop()
NSApp.terminate(nil)
}
}