aboutsummaryrefslogtreecommitdiff
path: root/src/service.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/service.vala')
-rw-r--r--src/service.vala444
1 files changed, 385 insertions, 59 deletions
diff --git a/src/service.vala b/src/service.vala
index 1173194..9127f05 100644
--- a/src/service.vala
+++ b/src/service.vala
@@ -40,10 +40,14 @@ public class IndicatorSound.Service: Object {
warn_notification.set_hint ("x-canonical-non-shaped-icon", "true");
warn_notification.set_hint ("x-canonical-snap-decisions", "true");
warn_notification.set_hint ("x-canonical-private-affirmative-tint", "true");
- warn_notification.closed.connect((n) => { n.clear_actions(); });
+ warn_notification.closed.connect((n) => {
+ n.clear_actions();
+ waiting_user_approve_warn=false;
+ increment_volume_sync_action();
+ });
BusWatcher.watch_namespace (GLib.BusType.SESSION,
"org.freedesktop.Notifications",
- () => { debug("Notifications name appeared"); notify_server_caps_checked = false; },
+ () => { debug("Notifications name appeared"); },
() => { debug("Notifications name vanshed"); notify_server_caps_checked = false; });
this.settings = new Settings ("com.canonical.indicator.sound");
@@ -53,6 +57,8 @@ public class IndicatorSound.Service: Object {
this.notify["visible"].connect ( () => this.update_root_icon () );
this.volume_control = volume;
+ this.volume_control.active_output_changed.connect (this.update_root_icon);
+ this.volume_control.active_output_changed.connect (this.update_notification);
this.accounts_service = accounts;
/* If we're on the greeter, don't export */
@@ -76,6 +82,7 @@ public class IndicatorSound.Service: Object {
this.actions.add_action (this.create_volume_action ());
this.actions.add_action (this.create_mic_volume_action ());
this.actions.add_action (this.create_high_volume_action ());
+ this.actions.add_action (this.create_volume_sync_action ());
this.menus = new HashTable<string, SoundMenu> (str_hash, str_equal);
this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE | SoundMenu.DisplayFlags.HIDE_PLAYERS | SoundMenu.DisplayFlags.GREETER_PLAYERS));
@@ -91,6 +98,10 @@ public class IndicatorSound.Service: Object {
this.volume_control.bind_property ("high-volume", menu, "show-high-volume-warning", BindingFlags.SYNC_CREATE);
});
+ this.menus.@foreach ( (profile, menu) => {
+ this.volume_control.active_output_changed.connect (menu.update_volume_slider);
+ });
+
this.sync_preferred_players ();
this.settings.changed["interested-media-players"].connect ( () => {
this.sync_preferred_players ();
@@ -271,17 +282,7 @@ public class IndicatorSound.Service: Object {
void update_root_icon () {
double volume = this.volume_control.volume.volume;
- string icon;
- if (this.volume_control.mute || volume <= 0.0)
- icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
- else if (this.accounts_service != null && this.accounts_service.silentMode)
- icon = "audio-volume-muted-panel";
- else if (volume <= 0.3)
- icon = "audio-volume-low-panel";
- else if (volume <= 0.7)
- icon = "audio-volume-medium-panel";
- else
- icon = "audio-volume-high-panel";
+ string icon = get_volume_root_icon (volume, this.volume_control.mute, volume_control.active_output);
string accessible_name;
if (this.volume_control.mute) {
@@ -307,21 +308,342 @@ public class IndicatorSound.Service: Object {
private bool notify_server_supports_actions = false;
private bool notify_server_supports_sync = false;
private bool block_info_notifications = false;
+ private bool waiting_user_approve_warn = false;
- private void update_notification () {
+ private string get_volume_icon (double volume, VolumeControl.ActiveOutput active_output)
+ {
+ string icon = "";
+ switch (active_output)
+ {
+ case VolumeControl.ActiveOutput.SPEAKERS:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.USB_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.USB_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium";
+ else
+ icon = "audio-volume-high";
+ break;
+ }
+ return icon;
+ }
- if (!notify_server_caps_checked) {
- List<string> caps = Notify.get_server_caps ();
- notify_server_supports_actions = caps.find_custom ("actions", strcmp) != null;
- notify_server_supports_sync = caps.find_custom ("x-canonical-private-synchronous", strcmp) != null;
- notify_server_caps_checked = true;
+ private string get_volume_root_icon_by_volume (double volume, VolumeControl.ActiveOutput active_output)
+ {
+ string icon = "";
+ switch (active_output)
+ {
+ case VolumeControl.ActiveOutput.SPEAKERS:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.USB_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.USB_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_SPEAKER:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_HEADPHONES:
+ if (volume <= 0.0)
+ icon = "audio-volume-muted-panel";
+ else if (volume <= 0.3)
+ icon = "audio-volume-low-panel";
+ else if (volume <= 0.7)
+ icon = "audio-volume-medium-panel";
+ else
+ icon = "audio-volume-high-panel";
+ break;
}
+ return icon;
+ }
+
+ private string get_volume_notification_icon (double volume, bool loud, VolumeControl.ActiveOutput active_output) {
+ string icon = "";
+ if (loud) {
+ switch (active_output)
+ {
+ case VolumeControl.ActiveOutput.SPEAKERS:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HEADPHONES:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_HEADPHONES:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_SPEAKER:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.USB_SPEAKER:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.USB_HEADPHONES:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_SPEAKER:
+ icon = "audio-volume-high";
+ break;
+ case VolumeControl.ActiveOutput.HDMI_HEADPHONES:
+ icon = "audio-volume-high";
+ break;
+ }
+ } else {
+ icon = get_volume_icon (volume, active_output);
+ }
+ return icon;
+ }
+
+ private string get_volume_root_icon (double volume, bool mute, VolumeControl.ActiveOutput active_output) {
+ string icon = "";
+ switch (active_output)
+ {
+ case VolumeControl.ActiveOutput.SPEAKERS:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.HEADPHONES:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_HEADPHONES:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_SPEAKER:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.USB_SPEAKER:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.USB_HEADPHONES:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.HDMI_SPEAKER:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ case VolumeControl.ActiveOutput.HDMI_HEADPHONES:
+ if (mute || volume <= 0.0)
+ icon = this.mute_blocks_sound ? "audio-volume-muted-blocking-panel" : "audio-volume-muted-panel";
+ else if (this.accounts_service != null && this.accounts_service.silentMode)
+ icon = "audio-volume-muted-panel";
+ else
+ icon = get_volume_root_icon_by_volume (volume, active_output);
+ break;
+ }
+ return icon;
+ }
+
+ private string get_notification_label () {
+ string volume_label = "";
+ switch (volume_control.active_output)
+ {
+ case VolumeControl.ActiveOutput.SPEAKERS:
+ volume_label = _("Speakers");
+ break;
+ case VolumeControl.ActiveOutput.HEADPHONES:
+ volume_label = _("Headphones");
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_HEADPHONES:
+ volume_label = _("Bluetooth headphones");
+ break;
+ case VolumeControl.ActiveOutput.BLUETOOTH_SPEAKER:
+ volume_label = _("Bluetooth speaker");
+ break;
+ case VolumeControl.ActiveOutput.USB_SPEAKER:
+ volume_label = _("Usb speaker");
+ break;
+ case VolumeControl.ActiveOutput.USB_HEADPHONES:
+ volume_label = _("Usb headphones");
+ break;
+ case VolumeControl.ActiveOutput.HDMI_SPEAKER:
+ volume_label = _("HDMI speaker");
+ break;
+ case VolumeControl.ActiveOutput.HDMI_HEADPHONES:
+ volume_label = _("HDMI headphones");
+ break;
+ }
+
+ return volume_label;
+ }
+
+ private void update_notification () {
+
+ List<string> caps = Notify.get_server_caps ();
+ notify_server_supports_actions = caps.find_custom ("actions", strcmp) != null;
+ notify_server_supports_sync = caps.find_custom ("x-canonical-private-synchronous", strcmp) != null;
+ notify_server_caps_checked = true;
var loud = volume_control.high_volume;
var warn = loud
&& this.notify_server_supports_actions
&& !this.volume_control.high_volume_approved;
-
+ if (waiting_user_approve_warn && volume_control.below_warning_volume) {
+ volume_control.set_warning_volume();
+ close_notification(warn_notification);
+ }
if (warn) {
close_notification(info_notification);
if (_pre_warn_volume == null) {
@@ -333,52 +655,44 @@ public class IndicatorSound.Service: Object {
warn_notification.add_action ("ok", _("OK"), (n, a) => {
stop_clamp_to_high_timeout();
volume_control.approve_high_volume ();
- if (_pre_warn_volume != null) {
- var tmp = _pre_warn_volume;
- _pre_warn_volume = null;
- volume_control.volume = tmp;
- }
+ // restore the volume the user introduced
+ VolumeControl.Volume vol = new VolumeControl.Volume();
+ vol.volume = volume_control.get_pre_clamped_volume();
+ vol.reason = VolumeControl.VolumeReasons.USER_KEYPRESS;
+ _pre_warn_volume = null;
+ volume_control.volume = vol;
+
+ waiting_user_approve_warn = false;
});
warn_notification.add_action ("cancel", _("Cancel"), (n, a) => {
_pre_warn_volume = null;
+ waiting_user_approve_warn = false;
+ increment_volume_sync_action();
});
+ waiting_user_approve_warn = true;
show_notification(warn_notification);
} else {
- close_notification(warn_notification);
-
- if (notify_server_supports_sync && !block_info_notifications) {
-
- /* Determine Label */
- unowned string volume_label = loud
- ? _("High volume can damage your hearing.")
- : "";
-
- /* Choose an icon */
- unowned string icon;
- if (loud) {
- icon = "audio-volume-high";
- } else {
- var volume = volume_control.volume.volume;
-
- if (volume <= 0.0)
- icon = "audio-volume-muted";
- else if (volume <= 0.3)
- icon = "audio-volume-low";
- else if (volume <= 0.7)
- icon = "audio-volume-medium";
- else
- icon = "audio-volume-high";
+ if (!waiting_user_approve_warn) {
+ close_notification(warn_notification);
+
+ if (notify_server_supports_sync && !block_info_notifications) {
+
+ /* Determine Label */
+ string volume_label = get_notification_label ();
+
+ /* Choose an icon */
+ string icon = get_volume_notification_icon (volume_control.volume.volume, loud, volume_control.active_output);
+
+ /* Reset the notification */
+ var n = this.info_notification;
+ n.update (_("Volume"), volume_label, icon);
+ n.clear_hints();
+ n.set_hint ("x-canonical-non-shaped-icon", "true");
+ n.set_hint ("x-canonical-private-synchronous", "true");
+ n.set_hint ("x-canonical-value-bar-tint", loud ? "true" : "false");
+ n.set_hint ("value", (int32)Math.round(get_volume_percent() * 100.0));
+ show_notification(n);
}
-
- /* Reset the notification */
- var n = this.info_notification;
- n.update (_("Volume"), volume_label, icon);
- n.clear_hints();
- n.set_hint ("x-canonical-non-shaped-icon", "true");
- n.set_hint ("x-canonical-private-synchronous", "true");
- n.set_hint ("x-canonical-value-bar-tint", loud ? "true" : "false");
- n.set_hint ("value", (int32)Math.round(get_volume_percent() * 100.0));
- show_notification(n);
}
}
}
@@ -538,6 +852,18 @@ public class IndicatorSound.Service: Object {
return high_volume_action;
}
+ SimpleAction volume_sync_action;
+ uint64 volume_sync_number_ = 0;
+ Action create_volume_sync_action () {
+ volume_sync_action = new SimpleAction.stateful("volume-sync", VariantType.UINT64, new Variant.uint64 (volume_sync_number_));
+
+ return volume_sync_action;
+ }
+
+ void increment_volume_sync_action () {
+ volume_sync_action.set_state(new Variant.uint64 (++volume_sync_number_));
+ }
+
uint export_actions = 0;
Variant action_state_for_player (MediaPlayer player, bool show_track = true) {