Add media key interception, preferences UI, dynamic menu bar icon

- Play key (F8) launches preferred player when no player is running
- Blocks Apple Music auto-launch (hide + forceTerminate, like noTunes)
- Preferences window: player picker with app icons, "Choose Other App..."
- Known players: Spotify, Apple Music, Yandex Music, VLC, IINA, Vox
- Start at login via LaunchAgent
- Menu bar icon dynamically reflects current volume level and mute state

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
johnfrum1234 2026-03-10 14:07:09 +02:00
parent de21639c24
commit 056c79d15e
4 changed files with 600 additions and 7 deletions

View file

@ -0,0 +1,41 @@
import Foundation
struct LoginItemManager {
private static let plistPath: String = {
let home = FileManager.default.homeDirectoryForCurrentUser.path
return "\(home)/Library/LaunchAgents/com.grosfrumos.hudini.plist"
}()
static var isEnabled: Bool {
FileManager.default.fileExists(atPath: plistPath)
}
static func setEnabled(_ enabled: Bool, appPath: String? = nil) {
if enabled {
let path = appPath ?? Bundle.main.bundlePath
let plist = """
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.grosfrumos.hudini</string>
<key>ProgramArguments</key>
<array>
<string>open</string>
<string>\(path)</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
"""
// Ensure LaunchAgents dir exists
let dir = (plistPath as NSString).deletingLastPathComponent
try? FileManager.default.createDirectory(atPath: dir, withIntermediateDirectories: true)
try? plist.write(toFile: plistPath, atomically: true, encoding: .utf8)
} else {
try? FileManager.default.removeItem(atPath: plistPath)
}
}
}