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:
commit
cee343dd96
9 changed files with 497 additions and 0 deletions
70
Sources/HUDini/AppDelegate.swift
Normal file
70
Sources/HUDini/AppDelegate.swift
Normal 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)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue