aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/service.vala24
-rw-r--r--src/sound-menu.vala84
-rw-r--r--src/volume-control.vala19
3 files changed, 88 insertions, 39 deletions
diff --git a/src/service.vala b/src/service.vala
index e69bca8..aa992ff 100644
--- a/src/service.vala
+++ b/src/service.vala
@@ -34,9 +34,9 @@ public class IndicatorSound.Service {
this.actions.add_action (this.create_mic_volume_action ());
this.menus = new HashTable<string, SoundMenu> (str_hash, str_equal);
- this.menus.insert ("desktop_greeter", new SoundMenu (true, null));
- this.menus.insert ("desktop", new SoundMenu (true, "indicator.desktop-settings"));
- this.menus.insert ("phone", new SoundMenu (false, "indicator.phone-settings"));
+ this.menus.insert ("desktop_greeter", new SoundMenu (null, SoundMenu.DisplayFlags.SHOW_MUTE));
+ this.menus.insert ("desktop", new SoundMenu ("indicator.desktop-settings", SoundMenu.DisplayFlags.SHOW_MUTE));
+ this.menus.insert ("phone", new SoundMenu ("indicator.phone-settings", SoundMenu.DisplayFlags.HIDE_INACTIVE_PLAYERS));
this.menus.@foreach ( (profile, menu) => {
this.volume_control.bind_property ("active-mic", menu, "show-mic-volume", BindingFlags.SYNC_CREATE);
@@ -120,9 +120,7 @@ public class IndicatorSound.Service {
void activate_desktop_settings (SimpleAction action, Variant? param) {
var env = Environment.get_variable ("DESKTOP_SESSION");
string cmd;
- if (env == "unity")
- cmd = "gnome-control-center sound-nua";
- else if (env == "xubuntu" || env == "ubuntustudio")
+ if (env == "xubuntu" || env == "ubuntustudio")
cmd = "pavucontrol";
else
cmd = "gnome-control-center sound";
@@ -177,10 +175,10 @@ public class IndicatorSound.Service {
}
Action create_mute_action () {
- var mute_action = new SimpleAction.stateful ("mute", null, this.volume_control.mute);
+ var mute_action = new SimpleAction.stateful ("mute", null, new Variant.boolean (this.volume_control.mute));
mute_action.activate.connect ( (action, param) => {
- action.change_state (!action.get_state ().get_boolean ());
+ action.change_state (new Variant.boolean (!action.get_state ().get_boolean ()));
});
mute_action.change_state.connect ( (action, val) => {
@@ -188,7 +186,7 @@ public class IndicatorSound.Service {
});
this.volume_control.notify["mute"].connect ( () => {
- mute_action.set_state (this.volume_control.mute);
+ mute_action.set_state (new Variant.boolean (this.volume_control.mute));
this.update_root_icon ();
});
@@ -197,13 +195,13 @@ public class IndicatorSound.Service {
void volume_changed (double volume) {
var volume_action = this.actions.lookup_action ("volume") as SimpleAction;
- volume_action.set_state (volume);
+ volume_action.set_state (new Variant.double (volume));
this.update_root_icon ();
}
Action create_volume_action () {
- var volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, this.volume_control.get_volume ());
+ var volume_action = new SimpleAction.stateful ("volume", VariantType.INT32, new Variant.double (this.volume_control.get_volume ()));
volume_action.change_state.connect ( (action, val) => {
volume_control.set_volume (val.get_double ());
@@ -223,14 +221,14 @@ public class IndicatorSound.Service {
}
Action create_mic_volume_action () {
- var volume_action = new SimpleAction.stateful ("mic-volume", null, this.volume_control.get_mic_volume ());
+ var volume_action = new SimpleAction.stateful ("mic-volume", null, new Variant.double (this.volume_control.get_mic_volume ()));
volume_action.change_state.connect ( (action, val) => {
volume_control.set_mic_volume (val.get_double ());
});
this.volume_control.mic_volume_changed.connect ( (volume) => {
- volume_action.set_state (volume);
+ volume_action.set_state (new Variant.double (volume));
});
this.volume_control.bind_property ("ready", volume_action, "enabled", BindingFlags.SYNC_CREATE);
diff --git a/src/sound-menu.vala b/src/sound-menu.vala
index 1641219..e1c5c1f 100644
--- a/src/sound-menu.vala
+++ b/src/sound-menu.vala
@@ -22,14 +22,20 @@ extern Variant? g_icon_serialize (Icon icon);
class SoundMenu: Object
{
- public SoundMenu (bool show_mute, string? settings_action) {
+ public enum DisplayFlags {
+ NONE = 0,
+ SHOW_MUTE = 1,
+ HIDE_INACTIVE_PLAYERS = 2
+ }
+
+ public SoundMenu (string? settings_action, DisplayFlags flags) {
/* A sound menu always has at least two sections: the volume section (this.volume_section)
* at the start of the menu, and the settings section at the end. Between those two,
* it has a dynamic amount of player sections, one for each registered player.
*/
this.volume_section = new Menu ();
- if (show_mute)
+ if ((flags & DisplayFlags.SHOW_MUTE) != 0)
volume_section.append (_("Mute"), "indicator.mute");
volume_section.append_item (this.create_slider_menu_item ("indicator.volume(0)", 0.0, 1.0, 0.01,
"audio-volume-low-zero-panel",
@@ -51,6 +57,9 @@ class SoundMenu: Object
this.root = new Menu ();
root.append_item (root_item);
+
+ this.hide_inactive = (flags & DisplayFlags.HIDE_INACTIVE_PLAYERS) != 0;
+ this.notify_handlers = new HashTable<MediaPlayer, ulong> (direct_hash, direct_equal);
}
public void export (DBusConnection connection, string object_path) {
@@ -81,36 +90,30 @@ class SoundMenu: Object
}
public void add_player (MediaPlayer player) {
- /* Add new players to the end of the player sections, just before the settings */
- var player_item = new MenuItem (player.name, "indicator." + player.id);
- player_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player");
- player_item.set_attribute_value ("icon", g_icon_serialize (player.icon));
+ if (this.notify_handlers.contains (player))
+ return;
- var playback_item = new MenuItem (null, null);
- playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
- playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
- playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
- playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
+ if (player.is_running || !this.hide_inactive)
+ this.insert_player_section (player);
+ this.update_playlists (player);
- var section = new Menu ();
- section.append_item (player_item);
- section.append_item (playback_item);
+ var handler_id = player.notify["is-running"].connect ( () => {
+ if (this.hide_inactive) {
+ if (player.is_running)
+ this.insert_player_section (player);
+ else
+ this.remove_player_section (player);
+ }
+ this.update_playlists (player);
+ });
+ this.notify_handlers.insert (player, handler_id);
player.playlists_changed.connect (this.update_playlists);
- player.notify["is-running"].connect ( () => this.update_playlists (player) );
- update_playlists (player);
-
- if (settings_shown) {
- this.menu.insert_section (this.menu.get_n_items () -1, null, section);
- } else {
- this.menu.append_section (null, section);
- }
}
public void remove_player (MediaPlayer player) {
- int index = this.find_player_section (player);
- if (index >= 0)
- this.menu.remove (index);
+ this.remove_player_section (player);
+ this.notify_handlers.remove (player);
}
Menu root;
@@ -118,6 +121,8 @@ class SoundMenu: Object
Menu volume_section;
bool mic_volume_shown;
bool settings_shown = false;
+ bool hide_inactive;
+ HashTable<MediaPlayer, ulong> notify_handlers;
/* returns the position in this.menu of the section that's associated with @player */
int find_player_section (MediaPlayer player) {
@@ -134,6 +139,35 @@ class SoundMenu: Object
return -1;
}
+ void insert_player_section (MediaPlayer player) {
+ var section = new Menu ();
+
+ var player_item = new MenuItem (player.name, "indicator." + player.id);
+ player_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.media-player");
+ player_item.set_attribute_value ("icon", g_icon_serialize (player.icon));
+ section.append_item (player_item);
+
+ var playback_item = new MenuItem (null, null);
+ playback_item.set_attribute ("x-canonical-type", "s", "com.canonical.unity.playback-item");
+ playback_item.set_attribute ("x-canonical-play-action", "s", "indicator.play." + player.id);
+ playback_item.set_attribute ("x-canonical-next-action", "s", "indicator.next." + player.id);
+ playback_item.set_attribute ("x-canonical-previous-action", "s", "indicator.previous." + player.id);
+ section.append_item (playback_item);
+
+ /* Add new players to the end of the player sections, just before the settings */
+ if (settings_shown) {
+ this.menu.insert_section (this.menu.get_n_items () -1, null, section);
+ } else {
+ this.menu.append_section (null, section);
+ }
+ }
+
+ void remove_player_section (MediaPlayer player) {
+ int index = this.find_player_section (player);
+ if (index >= 0)
+ this.menu.remove (index);
+ }
+
void update_playlists (MediaPlayer player) {
int index = find_player_section (player);
if (index < 0)
diff --git a/src/volume-control.vala b/src/volume-control.vala
index e50e8e6..c6db38c 100644
--- a/src/volume-control.vala
+++ b/src/volume-control.vala
@@ -27,6 +27,8 @@ public class VolumeControl : Object
/* this is static to ensure it being freed after @context (loop does not have ref counting) */
private static PulseAudio.GLibMainLoop loop;
+ private uint _reconnect_timer = 0;
+
private PulseAudio.Context context;
private bool _mute = true;
private double _volume = 0.0;
@@ -49,6 +51,13 @@ public class VolumeControl : Object
this.reconnect_to_pulse ();
}
+ ~VolumeControl ()
+ {
+ if (_reconnect_timer != 0) {
+ Source.remove (_reconnect_timer);
+ }
+ }
+
/* PulseAudio logic*/
private void context_events_cb (Context c, Context.SubscriptionEventType t, uint32 index)
{
@@ -154,7 +163,8 @@ public class VolumeControl : Object
case Context.State.FAILED:
case Context.State.TERMINATED:
- this.reconnect_to_pulse ();
+ if (_reconnect_timer == 0)
+ _reconnect_timer = Timeout.add_seconds (2, reconnect_timeout);
break;
default:
@@ -163,6 +173,13 @@ public class VolumeControl : Object
}
}
+ bool reconnect_timeout ()
+ {
+ _reconnect_timer = 0;
+ reconnect_to_pulse ();
+ return false; // G_SOURCE_REMOVE
+ }
+
void reconnect_to_pulse ()
{
if (this.ready) {