Skip to content

Commit 1aa622a

Browse files
committed
feat: improve menu performance
1 parent 7a5cc2c commit 1aa622a

File tree

4 files changed

+235
-116
lines changed

4 files changed

+235
-116
lines changed
Binary file not shown.

Micmute/MicmuteApp.swift

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,17 +338,24 @@ final class AppDelegate: NSObject, NSApplicationDelegate, NSWindowDelegate {
338338
// MARK: - Device selection helpers
339339

340340
func updateSelectedDevice(to deviceID: AudioDeviceID) {
341+
// Natychmiast zaznacz w UI
341342
contentViewModel.selectedDeviceID = deviceID
343+
// Zaktualizuj gain dla nowego urządzenia
342344
contentViewModel.loadInputGain(for: deviceID)
345+
// Ustaw systemowy default (jeśli się nie powiedzie – nie cofaj wyboru w UI)
343346
contentViewModel.changeDefaultInputDevice(to: deviceID)
344-
contentViewModel.loadAudioDevices()
347+
// Nie wywołuj tutaj loadAudioDevices(), żeby nie nadpisać świeżo wybranego urządzenia
348+
// (odświeżenia i tak przyjdą z listenerów/timera)
345349
}
346350

347351
func updateSelectedOutputDevice(to deviceID: AudioDeviceID) {
352+
// Natychmiast zaznacz w UI
348353
contentViewModel.selectedOutputDeviceID = deviceID
354+
// Ustaw systemowy default (i ewentualnie efekty dźwiękowe)
349355
contentViewModel.changeDefaultOutputDevice(to: deviceID)
356+
// Odśwież lokalny stan głośności dla nowego urządzenia
350357
contentViewModel.refreshOutputVolumeState()
351-
contentViewModel.loadAudioDevices()
358+
// Nie wywołuj tutaj loadAudioDevices(), aby nie przywracać starego wyboru
352359
}
353360

354361
// MARK: - Lifecycle hooks for menu content

Micmute/Models/ContentViewModel.swift

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ class ContentViewModel: ObservableObject {
9797
func toggleMute(deviceID: AudioDeviceID) {
9898
let resolvedDeviceID = syncSelectedInputDeviceWithSystemDefault() ?? selectedDeviceID
9999

100-
// Ustal aktualny stan mute z urządzenia, jeśli to możliwe,
101-
// aby przełączenie było zgodne ze stanem systemowym.
102100
let currentMute = currentDeviceMuteState(deviceID: resolvedDeviceID, scope: kAudioObjectPropertyScopeInput) ?? isMuted
103101
let targetMute = !currentMute
104102

@@ -190,7 +188,6 @@ class ContentViewModel: ObservableObject {
190188
return
191189
}
192190

193-
// Fallback do gain, jeśli brak właściwości mute
194191
let threshold: Float = 0.0001
195192
if fallbackGain <= threshold {
196193
if !isMuted {
@@ -310,14 +307,16 @@ class ContentViewModel: ObservableObject {
310307
availableDevices = updatedInputDevices
311308
availableOutputDevices = updatedOutputDevices
312309

310+
// Preferuj aktualnie wybrane urządzenie; dopiero potem system default; na końcu pierwsze dostępne.
313311
let systemInputDefault = systemDefaultDeviceID(selector: kAudioHardwarePropertyDefaultInputDevice)
314312
var resolvedInputDevice = selectedDeviceID
315313

316-
if let systemInputDefault,
317-
updatedInputDevices.keys.contains(systemInputDefault) {
318-
resolvedInputDevice = systemInputDefault
319-
} else if !updatedInputDevices.keys.contains(resolvedInputDevice) {
320-
resolvedInputDevice = updatedInputDevices.keys.first ?? kAudioObjectUnknown
314+
if !updatedInputDevices.keys.contains(resolvedInputDevice) {
315+
if let sys = systemInputDefault, updatedInputDevices.keys.contains(sys) {
316+
resolvedInputDevice = sys
317+
} else {
318+
resolvedInputDevice = updatedInputDevices.keys.first ?? kAudioObjectUnknown
319+
}
321320
}
322321

323322
if selectedDeviceID != resolvedInputDevice {
@@ -328,11 +327,12 @@ class ContentViewModel: ObservableObject {
328327
let systemOutputDefault = systemDefaultDeviceID(selector: kAudioHardwarePropertyDefaultOutputDevice)
329328
var resolvedOutputDevice = selectedOutputDeviceID
330329

331-
if let systemOutputDefault,
332-
updatedOutputDevices.keys.contains(systemOutputDefault) {
333-
resolvedOutputDevice = systemOutputDefault
334-
} else if !updatedOutputDevices.keys.contains(resolvedOutputDevice) {
335-
resolvedOutputDevice = updatedOutputDevices.keys.first ?? kAudioObjectUnknown
330+
if !updatedOutputDevices.keys.contains(resolvedOutputDevice) {
331+
if let sys = systemOutputDefault, updatedOutputDevices.keys.contains(sys) {
332+
resolvedOutputDevice = sys
333+
} else {
334+
resolvedOutputDevice = updatedOutputDevices.keys.first ?? kAudioObjectUnknown
335+
}
336336
}
337337

338338
if selectedOutputDeviceID != resolvedOutputDevice {
@@ -633,7 +633,6 @@ class ContentViewModel: ObservableObject {
633633
func loadInputGain(for deviceID: AudioDeviceID) {
634634
guard availableDevices.keys.contains(deviceID) else {
635635
inputGain = 0.0
636-
// Jeśli urządzenie nie jest dostępne, ustaw stan mute na podstawie braku urządzenia
637636
reconcileMuteState(deviceID: deviceID, fallbackGain: 0.0)
638637
return
639638
}
@@ -678,7 +677,6 @@ class ContentViewModel: ObservableObject {
678677
}
679678
}
680679

681-
// Preferowany mechanizm: kAudioDevicePropertyMute
682680
private func deviceSupportsMute(deviceID: AudioDeviceID, scope: AudioObjectPropertyScope) -> Bool {
683681
var address = AudioObjectPropertyAddress(
684682
mSelector: kAudioDevicePropertyMute,
@@ -731,11 +729,9 @@ class ContentViewModel: ObservableObject {
731729

732730
if deviceSupportsMute(deviceID: selectedDevice, scope: kAudioObjectPropertyScopeInput) {
733731
if setDeviceMute(deviceID: selectedDevice, scope: kAudioObjectPropertyScopeInput, mute: true) {
734-
// Po skutecznym mute flagą nie zmieniamy gain (zachowujemy poprzedni)
735732
return
736733
}
737734
}
738-
// Fallback: stare zachowanie
739735
setInputGain(for: selectedDevice, gain: 0.0)
740736
}
741737

@@ -744,12 +740,10 @@ class ContentViewModel: ObservableObject {
744740

745741
if deviceSupportsMute(deviceID: selectedDevice, scope: kAudioObjectPropertyScopeInput) {
746742
_ = setDeviceMute(deviceID: selectedDevice, scope: kAudioObjectPropertyScopeInput, mute: false)
747-
// Opcjonalnie przywróć głośność po unmute (zachowanie aplikacji)
748743
setInputGain(for: selectedDevice, gain: unmuteGain)
749744
return
750745
}
751746

752-
// Fallback: stare zachowanie
753747
setInputGain(for: selectedDevice, gain: unmuteGain)
754748
}
755749

@@ -775,4 +769,3 @@ class ContentViewModel: ObservableObject {
775769
AudioObjectRemovePropertyListener(AudioObjectID(kAudioObjectSystemObject), &address, deviceChangeListener, nil)
776770
}
777771
}
778-

0 commit comments

Comments
 (0)