Re-enumerate outputs through a fresh enumerator on each hotkey press
The enumerator created at startup could go stale and keep reporting the device set from back then, so an unplugged DAC stayed in the cycle and a replugged one never came back. A failed enumeration now empties the list instead of keeping the old one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
19
src/main.rs
19
src/main.rs
@@ -171,7 +171,7 @@ unsafe extern "system" fn wndproc(
|
||||
LRESULT(0)
|
||||
}
|
||||
notify::WM_DEVICES_CHANGED => {
|
||||
with_app(App::refresh_outputs);
|
||||
with_app(|app| app.refresh_outputs(&app.enumerator.clone()));
|
||||
LRESULT(0)
|
||||
}
|
||||
WM_SETTINGCHANGE => {
|
||||
@@ -208,9 +208,13 @@ impl App {
|
||||
/// The hotkey press.
|
||||
fn advance(&mut self) {
|
||||
self.reload_config_if_changed();
|
||||
self.refresh_outputs();
|
||||
|
||||
let current = audio::default_output(&self.enumerator);
|
||||
// A fresh enumerator per press: the one created at startup can go stale (the audio
|
||||
// service restarting is enough) and would keep reporting the devices from back then.
|
||||
let enumerator = audio::enumerator().unwrap_or_else(|_| self.enumerator.clone());
|
||||
self.refresh_outputs(&enumerator);
|
||||
|
||||
let current = audio::default_output(&enumerator);
|
||||
let candidates = cycle::candidates(&self.outputs, &self.config.devices);
|
||||
|
||||
let Some(target) = cycle::next(&candidates, current.as_ref().map(|c| c.id.as_str())) else {
|
||||
@@ -224,14 +228,13 @@ impl App {
|
||||
}
|
||||
|
||||
// Report what Windows actually ended up with, not what we asked for.
|
||||
let confirmed = audio::default_output(&self.enumerator).unwrap_or(target);
|
||||
let confirmed = audio::default_output(&enumerator).unwrap_or(target);
|
||||
self.osd.show(&confirmed.name, confirmed.form);
|
||||
}
|
||||
|
||||
fn refresh_outputs(&mut self) {
|
||||
if let Ok(outputs) = audio::outputs(&self.enumerator) {
|
||||
self.outputs = outputs;
|
||||
}
|
||||
/// A failed enumeration empties the list: an old list would offer an unplugged device.
|
||||
fn refresh_outputs(&mut self, enumerator: &IMMDeviceEnumerator) {
|
||||
self.outputs = audio::outputs(enumerator).unwrap_or_default();
|
||||
}
|
||||
|
||||
/// Picks up edits to the config file without a restart, but only re-reads when the
|
||||
|
||||
Reference in New Issue
Block a user