diff options
author | Lars Uebernickel <lars.uebernickel@canonical.com> | 2014-02-20 18:13:35 +0000 |
---|---|---|
committer | CI bot <ps-jenkins@lists.canonical.com> | 2014-02-20 18:13:35 +0000 |
commit | 8bac377082fb6c31292575a1c79172e9c0519ac6 (patch) | |
tree | c6e79b4782afa73854e4d3a7c2d1e6d103bcfa42 | |
parent | 838ea79ea2ad530c8780f67503a6bd9b31777b47 (diff) | |
parent | bbecb29d344887879e900319eb96cf19d44bde27 (diff) | |
download | ayatana-indicator-sound-8bac377082fb6c31292575a1c79172e9c0519ac6.tar.gz ayatana-indicator-sound-8bac377082fb6c31292575a1c79172e9c0519ac6.tar.bz2 ayatana-indicator-sound-8bac377082fb6c31292575a1c79172e9c0519ac6.zip |
Add support for amplified volumes
Add a settings key "allow-amplified-volume" which controls whether the volume slider stops at 100% or PA_VOLUME_UI_MAX. unity-control-center will provide a ui for this key.
-rw-r--r-- | data/com.canonical.indicator.sound.gschema.xml | 4 | ||||
-rw-r--r-- | src/service.vala | 53 |
2 files changed, 50 insertions, 7 deletions
diff --git a/data/com.canonical.indicator.sound.gschema.xml b/data/com.canonical.indicator.sound.gschema.xml index 102a1db..be759fa 100644 --- a/data/com.canonical.indicator.sound.gschema.xml +++ b/data/com.canonical.indicator.sound.gschema.xml @@ -48,5 +48,9 @@ Whether or not to show the sound indicator in the menu bar. </description> </key> + <key name="allow-amplified-volume" type="b"> + <default>false</default> + <summary>Whether the volume slider allows setting the volume above 100%</summary> + </key> </schema> </schemalist> diff --git a/src/service.vala b/src/service.vala index f7d86bb..b1b5ba9 100644 --- a/src/service.vala +++ b/src/service.vala @@ -17,7 +17,7 @@ * Lars Uebernickel <lars.uebernickel@canonical.com> */ -public class IndicatorSound.Service { +public class IndicatorSound.Service: Object { public Service () { this.settings = new Settings ("com.canonical.indicator.sound"); @@ -54,6 +54,8 @@ public class IndicatorSound.Service { this.notification.set_hint_string ("x-canonical-private-synchronous", "indicator-sound"); } } + + settings.bind ("allow-amplified-volume", this, "allow-amplified-volume", SettingsBindFlags.GET); } public int run () { @@ -71,6 +73,25 @@ public class IndicatorSound.Service { return 0; } + public bool allow_amplified_volume { + get { + return this.max_volume > 1.0; + } + + set { + if (value) { + /* from pulse/volume.h: #define PA_VOLUME_UI_MAX (pa_sw_volume_from_dB(+11.0)) */ + this.max_volume = (double)PulseAudio.Volume.sw_from_dB(11.0) / PulseAudio.Volume.NORM; + } + else { + this.max_volume = 1.0; + } + + /* Normalize volume, because the volume action's state is [0.0, 1.0], see create_volume_action() */ + this.actions.change_action_state ("volume", this.volume_control.get_volume () / this.max_volume); + } + } + const ActionEntry[] action_entries = { { "root", null, null, "@a{sv} {}", null }, { "scroll", activate_scroll_action, "i", null, null }, @@ -88,13 +109,18 @@ public class IndicatorSound.Service { Notify.Notification notification; bool syncing_preferred_players = false; + /* Maximum volume as a scaling factor between the volume action's state and the value in + * this.volume_control. See create_volume_action(). + */ + double max_volume = 1.0; + const double volume_step_percentage = 0.06; void activate_scroll_action (SimpleAction action, Variant? param) { int delta = param.get_int32(); /* positive for up, negative for down */ double v = this.volume_control.get_volume () + volume_step_percentage * delta; - this.volume_control.set_volume (v.clamp (0.0, 1.0)); + this.volume_control.set_volume (v.clamp (0.0, this.max_volume)); if (this.notification != null) { string icon; @@ -201,22 +227,35 @@ public class IndicatorSound.Service { void volume_changed (double volume) { var volume_action = this.actions.lookup_action ("volume") as SimpleAction; - volume_action.set_state (new Variant.double (volume)); + + /* Normalize volume, because the volume action's state is [0.0, 1.0], see create_volume_action() */ + volume_action.set_state (new Variant.double (volume / this.max_volume)); this.update_root_icon (); } Action create_volume_action () { - var volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (this.volume_control.get_volume ())); + /* The action's state is between be in [0.0, 1.0] instead of [0.0, + * max_volume], so that we don't need to update the slider menu item + * every time allow-amplified-volume is changed. Convert between the + * two here, so that we always pass the full range into + * volume_control.set_volume(). + */ + + double volume = this.volume_control.get_volume () / this.max_volume; + + var volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (volume)); volume_action.change_state.connect ( (action, val) => { - volume_control.set_volume (val.get_double ()); + double v = val.get_double () * this.max_volume; + volume_control.set_volume (v.clamp (0.0, this.max_volume)); }); /* activating this action changes the volume by the amount given in the parameter */ volume_action.activate.connect ( (action, param) => { - double v = volume_control.get_volume () + volume_step_percentage * param.get_int32 (); - volume_control.set_volume (v.clamp (0.0, 1.0)); + int delta = param.get_int32 (); + double v = volume_control.get_volume () + volume_step_percentage * delta; + volume_control.set_volume (v.clamp (0.0, this.max_volume)); }); this.volume_control.volume_changed.connect (volume_changed); |