Skip to content

Commit e6eb471

Browse files
committed
Highlighting the running state of the mic with red tint
1 parent 2266f95 commit e6eb471

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

micSwitch/AppDelegate.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,18 @@ class AppDelegate: NSObject, NSApplicationDelegate {
6666

6767
private func updateMicStatus() {
6868
guard let button = statusItem.button else { return }
69-
button.image = Audio.shared.micMuted ? micOff : micOn
69+
switch Audio.shared.micMuted, Audio.shared.isRunning) {
70+
case (true, false): button.image = micOff
71+
case (true, true): button.image = micOffActive
72+
case (false, false): button.image = micOn
73+
case (false, true): button.image = micOnActive
74+
}
7075
}
7176

7277
private let micOn = NSImage(named: NSImage.Name("micOn"))
7378
private let micOff = NSImage(named: NSImage.Name("micOff"))?.tint(color: NSColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.5))
79+
private let micOnActive = NSImage(named: NSImage.Name("micOn"))?.tint(color: NSColor(red: 1.0, green: 0.3, blue: 0.3, alpha: 1))
80+
private let micOffActive = NSImage(named: NSImage.Name("micOff"))?.tint(color: NSColor(red: 1.0, green: 0.3, blue: 0.3, alpha: 0.5))
7481
private var preferences: PreferencesViewController?
7582
private let statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
7683
private var muteListenerId: Int = -1

micSwitch/Classes/AudioUtils.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ struct AudioObjectAddress {
2424
mSelector: kAudioDevicePropertyDeviceNameCFString,
2525
mScope: kAudioObjectPropertyScopeGlobal,
2626
mElement: kAudioObjectPropertyElementMaster)
27+
28+
static var isRunning = AudioObjectPropertyAddress(
29+
mSelector: kAudioDevicePropertyDeviceIsRunningSomewhere,
30+
mScope: kAudioObjectPropertyScopeGlobal,
31+
mElement: kAudioObjectPropertyElementMaster)
2732
}
2833

2934
class Audio {
@@ -64,6 +69,20 @@ class Audio {
6469
}
6570
}
6671

72+
var isRunning: Bool {
73+
guard let inputDevice = inputDevice else { return false }
74+
75+
var value: UInt32 = 0
76+
var size = UInt32(MemoryLayout.size(ofValue: value))
77+
78+
let error = AudioObjectGetPropertyData(
79+
inputDevice, &AudioObjectAddress.isRunning,
80+
0, nil,
81+
&size, &value)
82+
83+
return error == kAudioHardwareNoError ? value == 1 : false
84+
}
85+
6786
func toggleMicMute() {
6887
micMuted = !micMuted
6988
}
@@ -114,12 +133,14 @@ class Audio {
114133
private func registerDeviceStateListener() {
115134
guard let inputDevice = self.inputDevice else { return }
116135
AudioObjectAddPropertyListenerBlock(inputDevice, &AudioObjectAddress.muteState, DispatchQueue.main, self.deviceStateListener)
136+
AudioObjectAddPropertyListenerBlock(inputDevice, &AudioObjectAddress.isRunning, DispatchQueue.main, self.deviceStateListener)
117137

118138
listeners.forEach { $0.value() }
119139
}
120140

121141
private func unregisterDeviceStateListener() {
122142
guard let inputDevice = self.inputDevice else { return }
143+
AudioObjectRemovePropertyListenerBlock(inputDevice, &AudioObjectAddress.isRunning, DispatchQueue.main, self.deviceStateListener)
123144
AudioObjectRemovePropertyListenerBlock(inputDevice, &AudioObjectAddress.muteState, DispatchQueue.main, self.deviceStateListener)
124145
}
125146

0 commit comments

Comments
 (0)