volume: fix sink switching after card profile change

parent 1f8e7a35
...@@ -526,6 +526,8 @@ namespace XimperShellNotificationCenter.Widgets { ...@@ -526,6 +526,8 @@ namespace XimperShellNotificationCenter.Widgets {
return; return;
} }
bool is_input = device.direction == Direction.INPUT; bool is_input = device.direction == Direction.INPUT;
// Snapshot target names before async operations
string target_port = device.port_name;
// Only set port and card profile if the device is attached to a card // Only set port and card profile if the device is attached to a card
if (device.has_card) { if (device.has_card) {
...@@ -542,13 +544,13 @@ namespace XimperShellNotificationCenter.Widgets { ...@@ -542,13 +544,13 @@ namespace XimperShellNotificationCenter.Widgets {
} }
if (profile_name != device.card_active_profile) { if (profile_name != device.card_active_profile) {
string old_name = device.device_name;
yield set_card_profile_by_index (profile_name, device); yield set_card_profile_by_index (profile_name, device);
yield wait_for_update<string> (device, "device-name"); yield wait_for_name_change (device, old_name);
} }
if (!is_input) { if (!is_input) {
if (device.port_name != device.card_sink_port_name) { if (target_port != device.card_sink_port_name) {
debug ("Setting port to: %s", device.port_name);
yield set_sink_port_by_name (device); yield set_sink_port_by_name (device);
} }
} }
...@@ -559,43 +561,86 @@ namespace XimperShellNotificationCenter.Widgets { ...@@ -559,43 +561,86 @@ namespace XimperShellNotificationCenter.Widgets {
} }
if (!is_input) { if (!is_input) {
if (device.device_name != default_sink_name) { yield set_default_sink (device);
debug ("Setting default sink to: %s", device.device_name); }
yield set_default_sink (device); }
}
private async void wait_for_name_change (
PulseDevice device, string ?old_name) {
if (device.device_name != null
&& device.device_name != old_name) {
return;
} }
SourceFunc callback = wait_for_name_change.callback;
ulong handler_id = 0;
uint timeout_id = 0;
handler_id = device.notify["device-name"].connect ((s, p) => {
if (device.device_name != null
&& device.device_name != old_name) {
if (timeout_id != 0) {
Source.remove (timeout_id);
}
device.disconnect (handler_id);
Idle.add ((owned) callback);
}
});
timeout_id = Timeout.add (200, () => {
timeout_id = 0;
device.disconnect (handler_id);
Idle.add ((owned) callback);
return Source.REMOVE;
});
yield;
} }
private async void wait_for_update<T> (PulseDevice device, private async void wait_for_update<T> (PulseDevice device,
string prop_name) { string prop_name) {
T current_value;
device.get (prop_name, out current_value);
if (current_value != null) return;
SourceFunc callback = wait_for_update.callback; SourceFunc callback = wait_for_update.callback;
ulong handler_id = 0; ulong handler_id = 0;
uint timeout_id = 0;
handler_id = device.notify[prop_name].connect ((s, p) => { handler_id = device.notify[prop_name].connect ((s, p) => {
T prop_value; T prop_value;
device.get (prop_name, out prop_value); device.get (prop_name, out prop_value);
if (prop_value != null) { if (prop_value != null) {
if (timeout_id != 0) {
Source.remove (timeout_id);
}
device.disconnect (handler_id); device.disconnect (handler_id);
Idle.add ((owned) callback); Idle.add ((owned) callback);
} }
}); });
timeout_id = Timeout.add (2000, () => {
timeout_id = 0;
device.disconnect (handler_id);
Idle.add ((owned) callback);
return Source.REMOVE;
});
yield; yield;
} }
public async void set_bluetooth_card_profile (PulseCardProfile profile, public async void set_bluetooth_card_profile (PulseCardProfile profile,
PulseDevice device) { PulseDevice device) {
string old_name = device.device_name;
context.set_card_profile_by_index (device.card_index, context.set_card_profile_by_index (device.card_index,
profile.name, profile.name,
(c, success) => { (c, success) => {
if (success == 1) { if (success != 1) {
set_bluetooth_card_profile.callback (); warning ("setting the card %s profile to %s failed",
} else { device.card_name, profile.name);
stderr.printf ("setting the card %s profile to %s failed\n",
device.card_name, profile.name);
} }
set_bluetooth_card_profile.callback ();
}); });
yield; yield;
// Wait until the device has been updated yield wait_for_name_change (device, old_name);
yield wait_for_update<string> (device, "device-name");
} }
private async void set_card_profile_by_index (string profile_name, private async void set_card_profile_by_index (string profile_name,
...@@ -603,12 +648,11 @@ namespace XimperShellNotificationCenter.Widgets { ...@@ -603,12 +648,11 @@ namespace XimperShellNotificationCenter.Widgets {
context.set_card_profile_by_index (device.card_index, context.set_card_profile_by_index (device.card_index,
profile_name, profile_name,
(c, success) => { (c, success) => {
if (success == 1) { if (success != 1) {
set_card_profile_by_index.callback (); warning ("setting the card %s profile to %s failed",
} else { device.card_name, profile_name);
stderr.printf ("setting the card %s profile to %s failed\n",
device.card_name, profile_name);
} }
set_card_profile_by_index.callback ();
}); });
yield; yield;
} }
...@@ -617,24 +661,22 @@ namespace XimperShellNotificationCenter.Widgets { ...@@ -617,24 +661,22 @@ namespace XimperShellNotificationCenter.Widgets {
context.set_sink_port_by_name (device.device_name, context.set_sink_port_by_name (device.device_name,
device.port_name, device.port_name,
(c, success) => { (c, success) => {
if (success == 1) { if (success != 1) {
set_sink_port_by_name.callback (); warning ("setting sink port to %s failed",
} else { device.port_name);
stderr.printf ("setting sink port to %s failed\n",
device.port_name);
} }
set_sink_port_by_name.callback ();
}); });
yield; yield;
} }
private async void set_default_sink (PulseDevice device) { private async void set_default_sink (PulseDevice device) {
context.set_default_sink (device.device_name, (c, success) => { context.set_default_sink (device.device_name, (c, success) => {
if (success == 1) { if (success != 1) {
set_default_sink.callback (); warning ("setting default sink to %s failed",
} else { device.device_name);
stderr.printf ("setting default sink to %s failed\n",
device.device_name);
} }
set_default_sink.callback ();
}); });
yield; yield;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment