aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--debian/changelog12
-rw-r--r--src/volume-control.vala78
2 files changed, 86 insertions, 4 deletions
diff --git a/debian/changelog b/debian/changelog
index 3519785..ddd21e1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+indicator-sound (12.10.2+14.10.20140509-0ubuntu1) utopic; urgency=low
+
+ [ Michael Terry ]
+ * Added timers to volume changes to settle frequent updates from
+ account services. (LP: #1306499)
+
+ [ Nick Dedekind ]
+ * Added timers to volume changes to settle frequent updates from
+ account services. (LP: #1306499)
+
+ -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Fri, 09 May 2014 14:43:21 +0000
+
indicator-sound (12.10.2+14.04.20140401-0ubuntu1) trusty; urgency=low
[ Michael Terry ]
diff --git a/src/volume-control.vala b/src/volume-control.vala
index 889c2d6..2efa186 100644
--- a/src/volume-control.vala
+++ b/src/volume-control.vala
@@ -47,6 +47,10 @@ public class VolumeControl : Object
private GreeterListInterface _greeter_proxy;
private Cancellable _mute_cancellable;
private Cancellable _volume_cancellable;
+ private uint _local_volume_timer = 0;
+ private uint _accountservice_volume_timer = 0;
+ private bool _send_next_local_volume = false;
+ private double _account_service_volume = 0.0;
public signal void volume_changed (double v);
public signal void mic_volume_changed (double v);
@@ -75,6 +79,8 @@ public class VolumeControl : Object
Source.remove (_reconnect_timer);
_reconnect_timer = 0;
}
+ stop_local_volume_timer();
+ stop_account_service_volume_timer();
}
/* PulseAudio logic*/
@@ -193,7 +199,7 @@ public class VolumeControl : Object
_reconnect_timer = Timeout.add_seconds (2, reconnect_timeout);
break;
- default:
+ default:
this.ready = false;
break;
}
@@ -335,7 +341,7 @@ public class VolumeControl : Object
public void set_volume (double volume)
{
if (set_volume_internal (volume))
- sync_volume_to_accountsservice.begin (volume);
+ start_local_volume_timer();
}
void set_mic_volume_success_cb (Context c, int success)
@@ -377,8 +383,11 @@ public class VolumeControl : Object
Variant volume_variant = changed_properties.lookup_value ("Volume", new VariantType ("d"));
if (volume_variant != null) {
var volume = volume_variant.get_double ();
- if (volume >= 0)
- set_volume_internal (volume);
+ if (volume >= 0) {
+ _account_service_volume = volume;
+ // we need to wait for this to settle.
+ start_account_service_volume_timer();
+ }
}
Variant mute_variant = changed_properties.lookup_value ("Muted", new VariantType ("b"));
@@ -487,4 +496,65 @@ public class VolumeControl : Object
warning ("unable to sync volume to AccountsService: %s", e.message);
}
}
+
+ private void start_local_volume_timer()
+ {
+ // perform a slow sync with the accounts service. max at 1 per second.
+
+ // stop the AS update timer, as since we're going to be setting the volume.
+ stop_account_service_volume_timer();
+
+ if (_local_volume_timer == 0) {
+ sync_volume_to_accountsservice.begin (_volume);
+ _local_volume_timer = Timeout.add_seconds (1, local_volume_changed_timeout);
+ } else {
+ _send_next_local_volume = true;
+ }
+ }
+
+ private void stop_local_volume_timer()
+ {
+ if (_local_volume_timer != 0) {
+ Source.remove (_local_volume_timer);
+ _local_volume_timer = 0;
+ }
+ }
+
+ bool local_volume_changed_timeout()
+ {
+ _local_volume_timer = 0;
+ if (_send_next_local_volume) {
+ _send_next_local_volume = false;
+ start_local_volume_timer ();
+ }
+ return false; // G_SOURCE_REMOVE
+ }
+
+ private void start_account_service_volume_timer()
+ {
+ if (_accountservice_volume_timer == 0) {
+ // If we haven't been messing with local volume recently, apply immediately.
+ if (_local_volume_timer == 0 && !set_volume_internal (_account_service_volume)) {
+ return;
+ }
+ // Else check again in another second if needed.
+ // (if AS is throwing us lots of notifications, we update at most once a second)
+ _accountservice_volume_timer = Timeout.add_seconds (1, accountservice_volume_changed_timeout);
+ }
+ }
+
+ private void stop_account_service_volume_timer()
+ {
+ if (_accountservice_volume_timer != 0) {
+ Source.remove (_accountservice_volume_timer);
+ _accountservice_volume_timer = 0;
+ }
+ }
+
+ bool accountservice_volume_changed_timeout ()
+ {
+ _accountservice_volume_timer = 0;
+ start_account_service_volume_timer ();
+ return false; // G_SOURCE_REMOVE
+ }
}