diff options
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/dbus-menu-manager.c | 7 | ||||
-rw-r--r-- | src/indicator-sound.c | 89 | ||||
-rw-r--r-- | src/metadata-menu-item.vala | 24 | ||||
-rw-r--r-- | src/mpris2-controller.vala | 78 | ||||
-rw-r--r-- | src/pulse-manager.c | 10 | ||||
-rw-r--r-- | src/slider-menu-item.c | 3 | ||||
-rw-r--r-- | src/sound-service.c | 4 | ||||
-rw-r--r-- | src/volume-widget.c | 21 | ||||
-rw-r--r-- | src/volume-widget.h | 2 |
10 files changed, 112 insertions, 130 deletions
diff --git a/configure.ac b/configure.ac index f30218d..23c6767 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(indicator-sound, 0.4.4, conor.curran@canonical.com) +AC_INIT(indicator-sound, 0.4.5, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.4.4) +AM_INIT_AUTOMAKE(indicator-sound, 0.4.5) AM_MAINTAINER_MODE diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 5ea561f..63e91b4 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -50,9 +50,11 @@ static gdouble volume_percent = 0.0; static void set_global_mute_from_ui(); static gboolean idle_routine (gpointer data); -static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service); +static void rebuild_sound_menu(DbusmenuMenuitem *root, + SoundServiceDbus *service); static void refresh_menu(); + /*-------------------------------------------------------------------------*/ // Public Methods /*-------------------------------------------------------------------------*/ @@ -75,7 +77,6 @@ DbusmenuMenuitem* dbus_menu_manager_setup() return root_menuitem; } - void dbus_menu_manager_update_volume(gdouble volume) { GValue value = {0}; @@ -213,7 +214,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service // Sound preferences dialog DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Sound Preferences...")); -//_("Sound Preferences...")); + //_("Sound Preferences...")); dbusmenu_menuitem_child_append(root, settings_mi); g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_sound_settings_dialog), NULL); diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 7f3b94b..35045d7 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -156,7 +156,9 @@ indicator_sound_init (IndicatorSound *self) IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); priv->volume_widget = NULL; - g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); + g_signal_connect(G_OBJECT(self->service), + INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, + G_CALLBACK(connection_changed), self); return; } @@ -307,7 +309,7 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, volume_widget = volume_widget_new (newitem); io = g_object_get_data (G_OBJECT (client), "indicator"); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - priv->volume_widget = volume_widget; + priv->volume_widget = volume_widget; GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); @@ -321,47 +323,67 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_item, - parent); - - fetch_mute_value_from_dbus(); - fetch_sink_availability_from_dbus(INDICATOR_SOUND (io)); - + parent); return TRUE; } static void -connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata) +connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer user_data) { if (connected) { - if (sound_dbus_proxy == NULL) { - GError * error = NULL; + gboolean service_restart = FALSE; + if (sound_dbus_proxy != NULL) { + g_object_unref (sound_dbus_proxy); + sound_dbus_proxy = NULL; + service_restart = TRUE; + } + GError * error = NULL; - DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); + DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SESSION, NULL); - sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus, - INDICATOR_SOUND_DBUS_NAME, - INDICATOR_SOUND_SERVICE_DBUS_OBJECT, - INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, - &error); + sound_dbus_proxy = dbus_g_proxy_new_for_name_owner(sbus, + INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_SERVICE_DBUS_OBJECT, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, + &error); - if (error != NULL) { - g_warning("Unable to get status proxy: %s", error->message); - g_error_free(error); + if (error != NULL) { + g_warning("Unable to get status proxy: %s", error->message); + g_error_free(error); + } + g_debug("about to connect to the signals"); + dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL); + dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), user_data, NULL); + dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL); + if( service_restart == TRUE){ + fetch_mute_value_from_dbus(); + // Ensure UI is in sync with service again. + IndicatorSound* indicator = INDICATOR_SOUND(user_data); + fetch_sink_availability_from_dbus(indicator); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + if(priv->volume_widget != NULL){ + determine_state_from_volume (volume_widget_get_current_volume(priv->volume_widget)); } - g_debug("about to connect to the signals"); - dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL); - dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), userdata, NULL); - dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); - dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL); - - g_return_if_fail(IS_INDICATOR_SOUND(userdata)); - } + } + else{ + g_warning("Indicator has been disconnected from the service -> SHOCK HORROR"); + IndicatorSound* indicator = INDICATOR_SOUND(user_data); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(indicator); + + if(priv->volume_widget != NULL){ + g_warning("indicator still has a slider, service must have crashed"); + volume_widget_tidy_up(priv->volume_widget); + g_object_unref(G_OBJECT(priv->volume_widget)); + priv->volume_widget = NULL; + } + device_available = FALSE; + update_state(STATE_SINKS_NONE); } - return; } /* @@ -537,8 +559,11 @@ fetch_sink_availability_from_dbus(IndicatorSound* self) } IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(self); - GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); - gtk_widget_set_sensitive(slider_widget, device_available); + + if(priv->volume_widget != NULL){ + GtkWidget* slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + gtk_widget_set_sensitive(slider_widget, device_available); + } g_free(available_input); g_debug("IndicatorSound::fetch_sink_availability_from_dbus ->%i", device_available); diff --git a/src/metadata-menu-item.vala b/src/metadata-menu-item.vala index b616a7b..3f71653 100644 --- a/src/metadata-menu-item.vala +++ b/src/metadata-menu-item.vala @@ -19,7 +19,6 @@ with this program. If not, see <http://www.gnu.org/licenses/>. using Gee; using DbusmenuMetadata; -using Dbusmenu; using Gdk; public class MetadataMenuitem : PlayerItem @@ -96,29 +95,6 @@ public class MetadataMenuitem : PlayerItem return result; } - public void determine_visibility() - { - try{ - if(property_get_int(MENUITEM_TITLE) == -1){ - this.property_set_bool(MENUITEM_PROP_VISIBLE, false); - return; - } - } - catch(Error e){ - warning("determine_visibility - %s", e.message); - } - try{ - string title = property_get(MENUITEM_TITLE); - if(title.length == 0){ - this.property_set_bool(MENUITEM_PROP_VISIBLE, false); - return; - } - } - catch(Error e){ - warning("determine_visibility - %s", e.message); - } - } - public void fetch_art(string uri, string prop) { File art_file = File.new_for_uri(uri); diff --git a/src/mpris2-controller.vala b/src/mpris2-controller.vala index 86665ea..54e1868 100644 --- a/src/mpris2-controller.vala +++ b/src/mpris2-controller.vala @@ -17,7 +17,7 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ using DBus; - +using Dbusmenu; [DBus (name = "org.mpris.MediaPlayer2")] public interface MprisRoot : DBus.Object { @@ -28,8 +28,8 @@ public interface MprisRoot : DBus.Object { public abstract string Identity{owned get; set;} public abstract string DesktopEntry{owned get; set;} // methods - public abstract void Quit() throws DBus.Error; - public abstract void Raise() throws DBus.Error; + public abstract async void Quit() throws DBus.Error; + public abstract async void Raise() throws DBus.Error; } [DBus (name = "org.mpris.MediaPlayer2.Player")] @@ -40,11 +40,9 @@ public interface MprisPlayer : DBus.Object { public abstract int32 Position{owned get; set;} public abstract string PlaybackStatus{owned get; set;} // methods - public abstract void SetPosition(DBus.ObjectPath path, int64 pos) throws DBus.Error; - public abstract void PlayPause() throws DBus.Error; - public abstract void Pause() throws DBus.Error; - public abstract void Next() throws DBus.Error; - public abstract void Previous() throws DBus.Error; + public abstract async void PlayPause() throws DBus.Error; + public abstract async void Next() throws DBus.Error; + public abstract async void Previous() throws DBus.Error; // signals public signal void Seeked(int64 new_position); } @@ -83,7 +81,7 @@ public class Mpris2Controller : GLib.Object this.player = (MprisPlayer) connection.get_object (root_interface.concat(".").concat(this.owner.name.down()), "/org/mpris/MediaPlayer2", root_interface.concat(".Player")); - this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged",//root_interface.concat(".").concat(this.owner.name.down()), + this.properties_interface = (FreeDesktopProperties) connection.get_object("org.freedesktop.Properties.PropertiesChanged", "/org/mpris/MediaPlayer2"); this.properties_interface.PropertiesChanged += property_changed_cb; @@ -103,25 +101,19 @@ public class Mpris2Controller : GLib.Object Value? play_v = changed_properties.lookup("PlaybackStatus"); if(play_v != null){ string state = this.player.PlaybackStatus; - debug("new playback state = %s", state); TransportMenuitem.state p = (TransportMenuitem.state)this.determine_play_state(state); (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(p); } - Value? pos_v = changed_properties.lookup("Position"); - if(pos_v != null){ - int64 pos = pos_v.get_int64(); - debug("new position = %i", (int)pos); - } - Value? meta_v = changed_properties.lookup("Metadata"); if(meta_v != null){ - GLib.HashTable<string, Value?> changed_updates = clean_metadata(); - this.owner.custom_items[PlayerController.widget_order.METADATA].reset(MetadataMenuitem.attributes_format()); - this.owner.custom_items[PlayerController.widget_order.METADATA].update(changed_updates, - MetadataMenuitem.attributes_format()); - MetadataMenuitem metadata_item = this.owner.custom_items[PlayerController.widget_order.METADATA] as MetadataMenuitem; - metadata_item.determine_visibility(); + GLib.HashTable<string, Value?> changed_updates = clean_metadata(); + PlayerItem metadata = this.owner.custom_items[PlayerController.widget_order.METADATA]; + metadata.reset(MetadataMenuitem.attributes_format()); + metadata.update(changed_updates, + MetadataMenuitem.attributes_format()); + metadata.property_set_bool(MENUITEM_PROP_VISIBLE, + metadata.populated(MetadataMenuitem.attributes_format())); } } @@ -143,13 +135,11 @@ public class Mpris2Controller : GLib.Object return changed_updates; } - private TransportMenuitem.state determine_play_state(string status){ if(status == null) return TransportMenuitem.state.PAUSED; if(status != null && status == "Playing"){ - debug("determine play state - state = %s", status); return TransportMenuitem.state.PLAYING; } return TransportMenuitem.state.PAUSED; @@ -163,9 +153,7 @@ public class Mpris2Controller : GLib.Object } else{ update = determine_play_state(this.player.PlaybackStatus); - } - debug("initial update - play state %i", (int)update); - + } (this.owner.custom_items[PlayerController.widget_order.TRANSPORT] as TransportMenuitem).change_play_state(update); GLib.HashTable<string, Value?> cleaned_metadata = this.clean_metadata(); this.owner.custom_items[PlayerController.widget_order.METADATA].update(cleaned_metadata, @@ -176,32 +164,13 @@ public class Mpris2Controller : GLib.Object { debug("transport_event input = %i", (int)command); if(command == TransportMenuitem.action.PLAY_PAUSE){ - debug("transport_event PLAY_PAUSE"); - try{ - this.player.PlayPause(); - } - catch(DBus.Error error){ - warning("DBus Error calling the player objects PlayPause method %s", - error.message); - } + this.player.PlayPause.begin(); } else if(command == TransportMenuitem.action.PREVIOUS){ - try{ - this.player.Previous(); - } - catch(DBus.Error error){ - warning("DBus Error calling the player objects Previous method %s", - error.message); - } + this.player.Previous.begin(); } else if(command == TransportMenuitem.action.NEXT){ - try{ - this.player.Next(); - } - catch(DBus.Error error){ - warning("DBus Error calling the player objects Next method %s", - error.message); - } + this.player.Next.begin(); } } @@ -212,21 +181,16 @@ public class Mpris2Controller : GLib.Object public bool was_successfull(){ - if(this.mpris2_root == null ||this.player == null){ + if(this.mpris2_root == null || this.player == null){ return false; } return true; } - + public void expose() { if(this.connected() == true){ - try{ - this.mpris2_root.Raise(); - } - catch(DBus.Error e){ - error("Exception thrown while calling function Raise - %s", e.message); - } + this.mpris2_root.Raise.begin(); } } } diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 4ff9e1d..f93368e 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -50,8 +50,8 @@ static pa_cvolume construct_mono_volume(const pa_cvolume* vol); /** Future Refactoring notes - - Push all UI updates out through update PA state in the service. - - Collapse 3 update_sink_info into one. The essentially do the same thing from different contexts. + - rewrite in vala. + - make sure all state is kept in the service for volume icon switching. **/ /** @@ -147,7 +147,7 @@ static gboolean determine_sink_availability() // Firstly check to see if we have any sinks // if not get the hell out of here ! if (g_hash_table_size(sink_hash) < 1) { - /* g_debug("Sink_available returning false because sinks_hash is empty !!!"); */ + g_debug("Sink_available returning false because sinks_hash is empty !!!"); DEFAULT_SINK_INDEX = -1; return FALSE; } @@ -163,7 +163,7 @@ static gboolean determine_sink_availability() // Thirdly ensure the default sink index does not have the name "auto_null" sink_info* s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX)); - // Up until now the most rebust method to test this is to manually remove the available sink device + // Up until now the most robust method to test this is to manually remove the available sink device // kernel module and then reload (rmmod & modprobe). // TODO: Edge case of dynamic loading and unloading of sinks should be handled also. /* g_debug("About to test for to see if the available sink is null - s->name = %s", s->name);*/ @@ -211,7 +211,6 @@ static void mute_each_sink(gpointer key, gpointer value, gpointer user_data) if (GPOINTER_TO_INT(user_data) == 1) { sound_service_dbus_update_sink_mute(dbus_service, TRUE); } else { - //sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume()); dbus_menu_manager_update_volume(get_default_sink_volume()); } @@ -411,7 +410,6 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v pa_volume_t vol = pa_cvolume_max(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; /* g_debug("Updating volume from PA manager with volume = %f", volume_percent);*/ - //sound_service_dbus_update_sink_volume(dbus_service, volume_percent); dbus_menu_manager_update_volume(volume_percent); } } diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c index 77c8635..c850cdc 100644 --- a/src/slider-menu-item.c +++ b/src/slider-menu-item.c @@ -88,8 +88,7 @@ handle_event (DbusmenuMenuitem * mi, const gchar * name, const GValue * value, g SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_volume) -{ - +{ SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_VOLUME_MENUITEM_TYPE); diff --git a/src/sound-service.c b/src/sound-service.c index 51f5f37..f19379d 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -41,8 +41,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); //TODO: uncomment for release !! - //close_pulse_activites(); - //g_main_loop_quit(mainloop); + close_pulse_activites(); + g_main_loop_quit(mainloop); } return; } diff --git a/src/volume-widget.c b/src/volume-widget.c index 5e7cf9f..1cfdcc4 100644 --- a/src/volume-widget.c +++ b/src/volume-widget.c @@ -61,6 +61,7 @@ static void volume_widget_parent_changed (GtkWidget *widget, gpointer user_data) G_DEFINE_TYPE (VolumeWidget, volume_widget, G_TYPE_OBJECT); + static void volume_widget_class_init (VolumeWidgetClass *klass) { @@ -201,8 +202,6 @@ volume_widget_update(VolumeWidget* self, gdouble update) dbusmenu_menuitem_handle_event (priv->twin_item, "update", &value, 0); } - - GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self) { @@ -234,6 +233,24 @@ volume_widget_slider_released(GtkWidget *widget, gpointer user_data) priv->grabbed = FALSE; } +void +volume_widget_tidy_up (GtkWidget *widget) +{ + VolumeWidget* mitem = VOLUME_WIDGET(widget); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + gtk_widget_destroy (priv->ido_volume_slider); +} + +gdouble +volume_widget_get_current_volume ( GtkWidget *widget ) +{ + VolumeWidget* mitem = VOLUME_WIDGET(widget); + VolumeWidgetPrivate * priv = VOLUME_WIDGET_GET_PRIVATE(mitem); + gdouble vol = g_value_get_double ( dbusmenu_menuitem_property_get_value( priv->twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL)); + return vol; +} + /** * volume_widget_new: * @returns: a new #VolumeWidget. diff --git a/src/volume-widget.h b/src/volume-widget.h index d4929ec..202bbb3 100644 --- a/src/volume-widget.h +++ b/src/volume-widget.h @@ -47,6 +47,8 @@ GType volume_widget_get_type (void) G_GNUC_CONST; GtkWidget* volume_widget_new(DbusmenuMenuitem* twin_item); GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self); void volume_widget_update(VolumeWidget* self, gdouble update); +void volume_widget_tidy_up (GtkWidget *widget); +gdouble volume_widget_get_current_volume ( GtkWidget *widget ); G_END_DECLS |