fix not detecting volume keys when non-monitor sound is default

- fixed an issue where the default volume controls would be intercepted (and thus not work) when an external display was connected and the output set to a device that allows volume control by default.
- refactor some of the code
This commit is contained in:
JoniVR 2018-12-16 19:41:11 +01:00
parent 79bd48166e
commit e63c81681f
5 changed files with 80 additions and 15 deletions

View file

@ -313,11 +313,13 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-MonitorControl/Pods-MonitorControl-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/AMCoreAudio/AMCoreAudio.framework",
"${BUILT_PRODUCTS_DIR}/MASPreferences/MASPreferences.framework",
"${BUILT_PRODUCTS_DIR}/MediaKeyTap/MediaKeyTap.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AMCoreAudio.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MASPreferences.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MediaKeyTap.framework",
);

View file

@ -11,6 +11,7 @@ import Cocoa
import Foundation
import MediaKeyTap
import MASPreferences
import AMCoreAudio
var app: AppDelegate! = nil
let prefs = UserDefaults.standard
@ -36,12 +37,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
func applicationDidFinishLaunching(_ aNotification: Notification) {
app = self
let listenFor = prefs.integer(forKey: Utils.PrefKeys.listenFor.rawValue)
if listenFor == Utils.ListenForKeys.brightnessOnlyKeys.rawValue {
keysListenedFor.removeSubrange(2...4)
} else if listenFor == Utils.ListenForKeys.volumeOnlyKeys.rawValue {
keysListenedFor.removeSubrange(0...1)
}
setVolumeKeysMode()
mediaKeyTap = MediaKeyTap.init(delegate: self, for: keysListenedFor, observeBuiltIn: false)
let storyboard: NSStoryboard = NSStoryboard.init(name: "Main", bundle: Bundle.main)
@ -55,6 +51,9 @@ class AppDelegate: NSObject, NSApplicationDelegate {
NotificationCenter.default.addObserver(self, selector: #selector(handleListenForChanged), name: NSNotification.Name.init(Utils.PrefKeys.listenFor.rawValue), object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(handleShowContrastChanged), name: NSNotification.Name.init(Utils.PrefKeys.showContrast.rawValue), object: nil)
// subscribe Audio output detector (AMCoreAudio)
NotificationCenter.defaultCenter.subscribe(self, eventType: AudioHardwareEvent.self, dispatchQueue: DispatchQueue.main)
statusItem.image = NSImage.init(named: "status")
statusItem.menu = statusMenu
@ -203,8 +202,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
extension AppDelegate: MediaKeyTapDelegate {
func handle(mediaKey: MediaKey, event: KeyEvent?) {
guard let currentDisplay = Utils.getCurrentDisplay(from: displays) else { return }
let allDisplays = prefs.bool(forKey: Utils.PrefKeys.allScreens.rawValue) ? displays : [currentDisplay]
for display in allDisplays {
if (prefs.object(forKey: "\(display.identifier)-state") as? Bool) ?? true {
switch mediaKey {
@ -222,6 +223,7 @@ extension AppDelegate: MediaKeyTapDelegate {
case .volumeDown:
let value = display.calcNewValue(for: AUDIO_SPEAKER_VOLUME, withRel: -step)
display.setVolume(to: value)
default:
return
}
@ -233,6 +235,22 @@ extension AppDelegate: MediaKeyTapDelegate {
// MARK: - Prefs notification
@objc func handleListenForChanged() {
readKeyListenPreferences()
setKeysToListenFor()
}
@objc func handleShowContrastChanged() {
self.updateDisplays()
}
private func setKeysToListenFor() {
mediaKeyTap?.stop()
mediaKeyTap = MediaKeyTap.init(delegate: self, for: keysListenedFor, observeBuiltIn: false)
mediaKeyTap?.start()
}
private func readKeyListenPreferences() {
let listenFor = prefs.integer(forKey: Utils.PrefKeys.listenFor.rawValue)
keysListenedFor = [.brightnessUp, .brightnessDown, .mute, .volumeUp, .volumeDown]
if listenFor == Utils.ListenForKeys.brightnessOnlyKeys.rawValue {
@ -240,13 +258,49 @@ extension AppDelegate: MediaKeyTapDelegate {
} else if listenFor == Utils.ListenForKeys.volumeOnlyKeys.rawValue {
keysListenedFor.removeSubrange(0...1)
}
mediaKeyTap?.stop()
mediaKeyTap = MediaKeyTap.init(delegate: self, for: keysListenedFor, observeBuiltIn: false)
mediaKeyTap?.start()
}
@objc func handleShowContrastChanged() {
self.updateDisplays()
}
}
extension AppDelegate: EventSubscriber {
/**
Fires off when a change in default audio device is detected.
*/
func eventReceiver(_ event: Event) {
switch event {
case let event as AudioHardwareEvent:
switch event {
case .defaultOutputDeviceChanged(let audioDevice):
#if DEBUG
print("Default output device changed to \(audioDevice)")
print("Can device set its own volume? \(audioDevice.canSetVirtualMasterVolume(direction: .playback))")
#endif
setVolumeKeysMode()
default: break
}
default: break
}
}
/**
We check if the current default audio output device can change the volume,
if not, we know for sure that we don't need to interact with it.
*/
func setVolumeKeysMode() {
readKeyListenPreferences()
if let defaultOutputDevice = AudioDevice.defaultOutputDevice() {
if defaultOutputDevice.canSetVirtualMasterVolume(direction: .playback) {
// Remove volume related keys
let keysToDelete: [MediaKey] = [.volumeUp, .volumeDown, .mute]
keysListenedFor = keysListenedFor.filter({ !keysToDelete.contains($0) })
} else {
// load keys to listen to from prefs like normal
readKeyListenPreferences()
}
setKeysToListenFor()
}
}
}

View file

@ -7,4 +7,5 @@ target 'MonitorControl' do
pod 'MediaKeyTap', :git => 'https://github.com/JoniVR/MediaKeyTap.git'
pod 'MASPreferences', :git => 'https://github.com/JoniVR/MASPreferences.git'
pod 'AMCoreAudio', '~> 3.2'
end

View file

@ -1,11 +1,17 @@
PODS:
- AMCoreAudio (3.2.1)
- MASPreferences (1.3)
- MediaKeyTap (2.1.0)
DEPENDENCIES:
- AMCoreAudio (~> 3.2)
- MASPreferences (from `https://github.com/JoniVR/MASPreferences.git`)
- MediaKeyTap (from `https://github.com/JoniVR/MediaKeyTap.git`)
SPEC REPOS:
https://github.com/cocoapods/specs.git:
- AMCoreAudio
EXTERNAL SOURCES:
MASPreferences:
:git: https://github.com/JoniVR/MASPreferences.git
@ -21,9 +27,10 @@ CHECKOUT OPTIONS:
:git: https://github.com/JoniVR/MediaKeyTap.git
SPEC CHECKSUMS:
AMCoreAudio: 7fa6b718dc93acc29f849d60c3ad680ae1bf07b5
MASPreferences: c08b8622dd17b47da87669e741efd7c92e970e8c
MediaKeyTap: b652877e9ae2d52ca4f5310fa5152945ad3f0798
PODFILE CHECKSUM: ef3a41f0dd719b389cc8241f6f5dd5fe52e55556
PODFILE CHECKSUM: 947d8968124719d712379b2dbc0a24b1595515fe
COCOAPODS: 1.5.3

View file

@ -43,6 +43,7 @@ You're all set ! Now open the `MonitorControl.xcworkspace` with Xcode
- [MediaKeyTap](https://github.com/JoniVR/MediaKeyTap)
- [MASPreferences](https://github.com/JoniVR/MASPreferences)
- [ddcctl](https://github.com/kfix/ddcctl)
- [AMCoreAudio](https://github.com/rnine/AMCoreAudio)
## Support
- macOS Sierra (`10.12`) and up.