diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/service.vala | 24 | ||||
-rw-r--r-- | src/sound-menu.vala | 84 | ||||
-rw-r--r-- | src/volume-control.vala | 19 |
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) { |