diff --git a/MonitorControl/Display.swift b/MonitorControl/Display.swift index 1b43003..c3cca81 100644 --- a/MonitorControl/Display.swift +++ b/MonitorControl/Display.swift @@ -1,5 +1,7 @@ +import AVFoundation import Cocoa import DDC +import os.log class Display { let identifier: CGDirectDisplayID @@ -12,6 +14,7 @@ class Display { var ddc: DDC? private let prefs = UserDefaults.standard + private var audioPlayer: AVAudioPlayer? init(_ identifier: CGDirectDisplayID, name: String, isEnabled: Bool = true) { self.identifier = identifier @@ -67,6 +70,7 @@ class Display { self.hideDisplayOsd() self.showOsd(command: .audioSpeakerVolume, value: value) + self.playVolumeChangedSound() } if let slider = volumeSliderHandler?.slider { @@ -158,4 +162,26 @@ class Display { totalChiclets: UInt32(maxValue / step), locked: false) } + + private func playVolumeChangedSound() { + let soundPath = "/System/Library/LoginPlugins/BezelServices.loginPlugin/Contents/Resources/volume.aiff" + let soundUrl = URL(fileURLWithPath: soundPath) + + // Check if user has enabled "Play feedback when volume is changed" in Sound Preferences + guard let preferences = Utils.getSystemPreferences(), + let hasSoundEnabled = preferences["com.apple.sound.beep.feedback"] as? Int, + hasSoundEnabled == 1 else { + os_log("sound not enabled", type: .info) + return + } + + do { + self.audioPlayer = try AVAudioPlayer(contentsOf: soundUrl) + self.audioPlayer?.volume = 1 + self.audioPlayer?.prepareToPlay() + self.audioPlayer?.play() + } catch { + os_log("%{public}@", type: .error, error.localizedDescription) + } + } } diff --git a/MonitorControl/Info.plist b/MonitorControl/Info.plist index 7c01efa..943ac7b 100644 --- a/MonitorControl/Info.plist +++ b/MonitorControl/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.5.1 CFBundleVersion - 495 + 509 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/MonitorControl/Support/Utils.swift b/MonitorControl/Support/Utils.swift index 5ca7cd1..1482d09 100644 --- a/MonitorControl/Support/Utils.swift +++ b/MonitorControl/Support/Utils.swift @@ -94,6 +94,20 @@ class Utils: NSObject { return } + static func getSystemPreferences() -> [String: AnyObject]? { + var propertyListFormat = PropertyListSerialization.PropertyListFormat.xml + let plistPath = NSString(string: "~/Library/Preferences/.GlobalPreferences.plist").expandingTildeInPath + guard let plistXML = FileManager.default.contents(atPath: plistPath) else { + return nil + } + do { + return try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as? [String: AnyObject] + } catch { + os_log("Error reading system prefs plist: %{public}@", type: .info, error.localizedDescription) + return nil + } + } + // MARK: - Display Infos /// Get the name of a display diff --git a/MonitorControlHelper/Info.plist b/MonitorControlHelper/Info.plist index 40b28ab..182c009 100644 --- a/MonitorControlHelper/Info.plist +++ b/MonitorControlHelper/Info.plist @@ -19,7 +19,7 @@ CFBundleShortVersionString 1.5.1 CFBundleVersion - 495 + 509 LSApplicationCategoryType public.app-category.utilities LSBackgroundOnly