From c879c510dbef95deea70687d59c2013005bf946d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 24 Feb 2010 14:19:01 +0000 Subject: unit tests for the indicator side added --- src/indicator-sound.c | 282 ++++++++++++++++++++++++++------------------------ 1 file changed, 144 insertions(+), 138 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index acacddc..ffe7acb 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -100,13 +100,15 @@ static void fetch_mute_value_from_dbus(); static void prepare_state_machine(); static void determine_state_from_volume(gdouble volume_percent); static void update_state(const gint state); + static const gint STATE_MUTED = 0; static const gint STATE_ZERO = 1; static const gint STATE_LOW = 2; static const gint STATE_MEDIUM = 3; static const gint STATE_HIGH = 4; static const gint STATE_MUTED_WHILE_INPUT = 5; -static const gint STATE_SINKS_NONE = 5; +static const gint STATE_SINKS_NONE = 6; + static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; static GtkWidget* primary_image = NULL; @@ -115,6 +117,7 @@ static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +// Construction static void indicator_sound_class_init (IndicatorSoundClass *klass) { @@ -147,21 +150,91 @@ static void indicator_sound_init (IndicatorSound *self) return; } +static void +indicator_sound_dispose (GObject *object) +{ + IndicatorSound * self = INDICATOR_SOUND(object); -/* -Prepare states Array. -*/ -static void prepare_state_machine() + if (self->service != NULL) { + g_object_unref(G_OBJECT(self->service)); + self->service = NULL; + } + g_hash_table_destroy(volume_states); + G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); + return; +} + +static void +indicator_sound_finalize (GObject *object) { - // TODO we need three more images - volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-zero-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); + G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object); + return; +} + +static GtkLabel * +get_label (IndicatorObject * io) +{ + return NULL; +} + +static GtkImage * +get_icon (IndicatorObject * io) +{ + gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); + //g_debug("At start-up attempting to set the image to %s", current_name); + speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + gtk_widget_show(GTK_WIDGET(speaker_image)); + return speaker_image; +} + +/* Indicator based function to get the menu for the whole + applet. This starts up asking for the parts of the menu + from the various services. */ +static GtkMenu * +get_menu (IndicatorObject * io) +{ + DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); + DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item); + + // register Key-press listening on the menu widget as the slider does not allow this. + g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); + + return GTK_MENU(menu); +} + +/** +new_slider_item: +Create a new dBusMenu Slider item. +**/ +static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + + volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5); + g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL); + + GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); + + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); + g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); + + // register slider changes listening on the range + GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); + // alternative callback mechanism which i could use again at some point. +/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ + + // Set images on the ido + primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); + gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); + gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + + gtk_widget_show_all(volume_slider); + + return TRUE; } static void @@ -205,6 +278,63 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u return; } + + + +/* +Prepare states Array. +*/ +static void prepare_state_machine() +{ + // TODO we need three more images + volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); +} + + + +static void update_state(const gint state) +{ +/* g_debug("update state beginning - previous_state = %i", previous_state);*/ + + previous_state = current_state; + +/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/ + + current_state = state; + gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); + gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); +} + + +static void determine_state_from_volume(gdouble volume_percent) +{ +/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ + + gint state = previous_state; + if (volume_percent < 30.0 && volume_percent > 0){ + state = STATE_LOW; + } + else if(volume_percent < 70.0 && volume_percent >= 30.0){ + state = STATE_MEDIUM; + } + else if(volume_percent >= 70.0){ + state = STATE_HIGH; + } + else if(volume_percent == 0.0){ + state = STATE_ZERO; + } + update_state(state); +} + + + static void fetch_volume_percent_from_dbus() { GError * error = NULL; @@ -270,130 +400,6 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } - - -static void -indicator_sound_dispose (GObject *object) -{ - IndicatorSound * self = INDICATOR_SOUND(object); - - if (self->service != NULL) { - g_object_unref(G_OBJECT(self->service)); - self->service = NULL; - } - g_hash_table_destroy(volume_states); - G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); - return; -} - -static void -indicator_sound_finalize (GObject *object) -{ - G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object); - return; -} - -static GtkLabel * -get_label (IndicatorObject * io) -{ - return NULL; -} - -static GtkImage * -get_icon (IndicatorObject * io) -{ - gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); - gtk_widget_show(GTK_WIDGET(speaker_image)); - return speaker_image; -} - -static void update_state(const gint state) -{ -/* g_debug("update state beginning - previous_state = %i", previous_state);*/ - - previous_state = current_state; - -/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/ - - current_state = state; - gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); -} - - -static void determine_state_from_volume(gdouble volume_percent) -{ -/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ - - gint state = previous_state; - if (volume_percent < 30.0 && volume_percent > 0){ - state = STATE_LOW; - } - else if(volume_percent < 70.0 && volume_percent > 30.0){ - state = STATE_MEDIUM; - } - else if(volume_percent > 70.0){ - state = STATE_HIGH; - } - else if(volume_percent == 0.0){ - state = STATE_ZERO; - } - update_state(state); -} - - -/* Indicator based function to get the menu for the whole - applet. This starts up asking for the parts of the menu - from the various services. */ -static GtkMenu * -get_menu (IndicatorObject * io) -{ - DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); - DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item); - - // register Key-press listening on the menu widget as the slider does not allow this. - g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); - - return GTK_MENU(menu); -} - -/** -new_slider_item: -Create a new dBusMenu Slider item, register the -**/ -static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) -{ - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5); - g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL); - - GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); - - // register slider changes listening on the range - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - // alternative callback mechanism which i could use again at some point. -/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - - // Set images on the ido - primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); - GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); - - gtk_widget_show_all(volume_slider); - - return TRUE; -} - /** slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. -- cgit v1.2.3 From be2b2e73044d5ba0c656431f0d19723af6b55946 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 2 Mar 2010 10:20:25 +0000 Subject: refactored the indicator tests so as no c file needs to be included --- src/indicator-sound.c | 11 +++++++++++ src/indicator-sound.h | 5 +++-- 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 546f404..3aca517 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -300,11 +300,22 @@ gint get_state() return current_state; } +gchar* get_state_image_name(gint state) +{ + return g_hash_table_lookup(volume_states, GINT_TO_POINTER(state)); +} + void prepare_for_tests(IndicatorObject *io) { + prepare_state_machine(); get_icon(io); } +void tidy_up_hash() +{ + g_hash_table_destroy(volume_states); +} + static void update_state(const gint state) { /* g_debug("update state beginning - previous_state = %i", previous_state);*/ diff --git a/src/indicator-sound.h b/src/indicator-sound.h index eaf8948..6d0c85c 100644 --- a/src/indicator-sound.h +++ b/src/indicator-sound.h @@ -21,9 +21,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - +// Essentially these are all exported to faciltiate testing void prepare_state_machine(); void determine_state_from_volume(gdouble volume_percent); gint get_state(); -// Not nice +gchar* get_state_image_name(gint state); void prepare_for_tests(IndicatorObject * io); +void tidy_up_hash(); -- cgit v1.2.3 From 4bde209ef0f8ad381d70b2ade7eb3cf834eed074 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 2 Mar 2010 19:36:53 +0000 Subject: one big refactor --- src/Makefile.am | 2 + src/dbus-menu-manager.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++ src/dbus-menu-manager.h | 31 +++++++ src/indicator-sound.h | 5 ++ src/pulse-manager.c | 79 +++++++++++++---- src/pulse-manager.h | 4 +- src/sound-service.c | 134 +++------------------------- src/sound-service.h | 11 +-- 8 files changed, 344 insertions(+), 152 deletions(-) create mode 100644 src/dbus-menu-manager.c create mode 100644 src/dbus-menu-manager.h (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 5abacda..40a8fdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,8 @@ indicator_sound_service_SOURCES = \ common-defs.h \ sound-service.h \ sound-service.c \ + dbus-menu-manager.c \ + dbus-menu-manager.h \ pulse-manager.h \ pulse-manager.c \ sound-service-dbus.h \ diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c new file mode 100644 index 0000000..652e6b2 --- /dev/null +++ b/src/dbus-menu-manager.c @@ -0,0 +1,230 @@ +/* +This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel. +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#include +#include + +#include +#include +#include + +#include "dbus-menu-manager.h" +#include "sound-service-dbus.h" +#include "pulse-manager.h" +#include "slider-menu-item.h" + +#include "dbus-shared-names.h" + +// DBUS items +static DbusmenuMenuitem *root_menuitem = NULL; +static DbusmenuMenuitem *mute_all_menuitem = NULL; +static SliderMenuItem *volume_slider_menuitem = NULL; +static SoundServiceDbus *dbus_interface = NULL; + +// PULSEAUDIO +static gboolean b_sink_available = FALSE; +static gboolean b_all_muted = FALSE; +static gboolean b_pulse_ready = FALSE; +static gboolean b_startup = TRUE; +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 refresh_menu(); + +/*-------------------------------------------------------------------------*/ +// Public Methods +/*-------------------------------------------------------------------------*/ + +/** +setup: +**/ +void dbus_menu_manager_setup() +{ + root_menuitem = dbusmenu_menuitem_new(); + g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); + + g_idle_add(idle_routine, root_menuitem); + + dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); + + DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT); + dbusmenu_server_set_root(server, root_menuitem); + establish_pulse_activities(dbus_interface); +} + +/** +teardown: +**/ +void dbus_menu_manager_teardown() +{ + //TODO tidy up dbus_interface and items! +} + +/** +update_pa_state: +**/ +void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent) +{ + b_sink_available = sink_available; + b_all_muted = sink_muted; + b_pulse_ready = pa_state; + volume_percent = percent; + g_debug("update pa state with state %i, availability of %i, mute value of %i and a volume percent is %f", pa_state, sink_available, sink_muted, volume_percent); + // Only rebuild the menu on start up... + if(b_startup == TRUE){ + rebuild_sound_menu(root_menuitem, dbus_interface); + b_startup = FALSE; + } + else{ + refresh_menu(); + } + // Emit the signals after the menus are setup/torn down + sound_service_dbus_update_sink_volume(dbus_interface, percent); + sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); + dbus_menu_manager_update_mute_ui(b_all_muted); +} + +/** +update_mute_ui: +'public' method allowing the pa manager to update the mute menu item. +**/ +void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) +{ + b_all_muted = incoming_mute_value; + dbusmenu_menuitem_property_set(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_LABEL, + (b_all_muted == FALSE ? "Mute All" : "Unmute")); + //dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? _("Mute All") : _("Unmute"))); +} + + +/*-------------------------------------------------------------------------*/ +// Private Methods +/*-------------------------------------------------------------------------*/ + +static void refresh_menu() +{ + g_debug("in the refresh menu method"); + if(b_sink_available == FALSE || b_pulse_ready == FALSE) + { + + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + FALSE); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + FALSE); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_ENABLED, + FALSE); + + } + else if(b_sink_available == TRUE && b_pulse_ready == TRUE){ + + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + TRUE); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + TRUE); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_ENABLED, + TRUE); + } +} + + + +/** + +**/ +static gboolean idle_routine (gpointer data) +{ + return FALSE; +} + + + +/** +show_sound_settings_dialog: +Bring up the gnome volume preferences dialog +**/ +static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async("gnome-volume-control", &error)) + { + g_warning("Unable to show dialog: %s", error->message); + g_error_free(error); + } +} + +/** +rebuild_sound_menu: +Build the DBus menu items, mute/unmute, slider, separator and sound preferences 'link' +**/ +static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service) +{ + // Mute button + mute_all_menuitem = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); + g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); + + // Slider + volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent); + dbusmenu_menuitem_child_append(root, mute_all_menuitem); + dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + b_sink_available); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + b_sink_available); + // Separator + DbusmenuMenuitem *separator = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append(root, separator); + + // Sound preferences dialog + DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, + ("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); +} + +/** +set_global_mute_from_ui: +Callback for the dbusmenuitem button +**/ +static void set_global_mute_from_ui() +{ + b_all_muted = !b_all_muted; + toggle_global_mute(b_all_muted); + dbusmenu_menuitem_property_set(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_LABEL, + (b_all_muted == FALSE ? "Mute All" : "Unmute")); +} + + diff --git a/src/dbus-menu-manager.h b/src/dbus-menu-manager.h new file mode 100644 index 0000000..5f49e5f --- /dev/null +++ b/src/dbus-menu-manager.h @@ -0,0 +1,31 @@ +#ifndef __INCLUDE_DBUS_MENU_MANAGER_H__ +#define __INCLUDE_DBUS_MENU_MANAGER_H__ + +/* +This handles the management of the dbusmeneu items. +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +void dbus_menu_manager_setup(); +void dbus_menu_manager_teardown(); +void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol); +// TODO update pa_state should incorporate the method below ! +void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value); + +#endif + diff --git a/src/indicator-sound.h b/src/indicator-sound.h index 6d0c85c..e508390 100644 --- a/src/indicator-sound.h +++ b/src/indicator-sound.h @@ -1,3 +1,6 @@ +#ifndef __INCLUDE_INDICATOR_SOUND_H__ +#define __INCLUDE_INDICATOR_SOUND_H__ + /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. @@ -28,3 +31,5 @@ gint get_state(); gchar* get_state_image_name(gint state); void prepare_for_tests(IndicatorObject * io); void tidy_up_hash(); + +#endif diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 9b9d7cd..4594d2f 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -26,12 +26,10 @@ with this program. If not, see . #include #include "pulse-manager.h" -#include "sound-service.h" - +#include "dbus-menu-manager.h" static GHashTable *sink_hash = NULL; static SoundServiceDbus *dbus_service = NULL; -// Until we find a satisfactory default sink this index should remain < 0 static gint DEFAULT_SINK_INDEX = -1; static gboolean pa_server_available = FALSE; // PA related @@ -46,6 +44,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata); static void destroy_sink_info(void *value); static gboolean determine_sink_availability(); +static void reconnect_to_pulse(); /** @@ -65,14 +64,19 @@ void establish_pulse_activities(SoundServiceDbus *service) g_assert(pulse_context); sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration pa_context_set_state_callback(pulse_context, context_state_callback, NULL); - pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); + // BUILD MENU ANYWHO - it will be updated + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); } void close_pulse_activites() { - if (pulse_context){ + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); pa_context_unref(pulse_context); pulse_context = NULL; } @@ -82,6 +86,30 @@ void close_pulse_activites() g_debug("I just closed communication with Pulse"); } +/** +reconnect_to_pulse() +In the event of Pulseaudio flapping in the wind handle gracefully without +memory leaks ! +*/ +static void reconnect_to_pulse() +{ + // reset + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); + pa_context_unref(pulse_context); + pulse_context = NULL; + } + g_hash_table_destroy(sink_hash); + + // reconnect + pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "ayatana.indicator.sound"); + g_assert(pulse_context); + sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration + pa_context_set_state_callback(pulse_context, context_state_callback, NULL); + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); +} static void destroy_sink_info(void *value) { @@ -186,6 +214,8 @@ Use the base volume stored in the sink struct to calculate actual linear volumes */ void set_sink_volume(gdouble percent) { + if(pa_server_available == FALSE) + return; g_debug("in the pulse manager:set_sink_volume with percent %f", percent); if(DEFAULT_SINK_INDEX < 0) { @@ -245,12 +275,15 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in gboolean device_available = determine_sink_availability(); if(device_available == TRUE) { - update_pa_state(TRUE, device_available, default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, + device_available, + default_sink_is_muted(), + get_default_sink_volume()); } else{ //Update the indicator to show PA either is not ready or has no available sink g_warning("Cannot find a suitable default sink ..."); - update_pa_state(FALSE, device_available, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0); } } else{ @@ -291,7 +324,7 @@ static void pulse_default_sink_info_callback(pa_context *c, const pa_sink_info * } else { - update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); } } } @@ -354,7 +387,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v { g_debug("Updating Mute from PA manager with mute = %i", s->mute); sound_service_dbus_update_sink_mute(dbus_service, s->mute); - update_mute_ui(s->mute); + dbus_menu_manager_update_mute_ui(s->mute); if(s->mute == FALSE){ pa_volume_t vol = pa_cvolume_avg(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; @@ -366,12 +399,20 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v } else { - // TODO ADD new sink - part of big refactor - g_debug("attempting to add new sink with name %s", info->name); - //sink_info *s; - //s = g_new0(sink_info, 1); - //update the sinks hash with new sink. - } + sink_info *value; + value = g_new0(sink_info, 1); + value->index = value->device_index = info->index; + value->name = g_strdup(info->name); + value->description = g_strdup(info->description); + value->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME)); + value->active_port = (info->active_port != NULL); + value->mute = !!info->mute; + value->volume = info->volume; + value->base_volume = info->base_volume; + value->channel_map = info->channel_map; + g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); + g_debug("pulse-manager:update_sink_info -> After adding a new sink to our hash"); + } } @@ -382,7 +423,7 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info if (info == NULL) { g_warning("No server - get the hell out of here"); - update_pa_state(FALSE, FALSE, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, FALSE, TRUE, 0); pa_server_available = FALSE; return; } @@ -474,7 +515,7 @@ static void context_state_callback(pa_context *c, void *userdata) { g_debug("unconnected"); break; case PA_CONTEXT_CONNECTING: - g_debug("connecting"); + g_debug("connecting - waiting for the server to become available"); break; case PA_CONTEXT_AUTHORIZING: g_debug("authorizing"); @@ -484,8 +525,8 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case PA_CONTEXT_FAILED: g_warning("FAILED to retrieve context - Is PulseAudio Daemon running ?"); - //Update the indicator to show PA either is not ready or has no available sink - update_pa_state(FALSE, FALSE, TRUE, 0); + pa_server_available = FALSE; + reconnect_to_pulse(); break; case PA_CONTEXT_TERMINATED: g_debug("context terminated"); diff --git a/src/pulse-manager.h b/src/pulse-manager.h index 1be5e44..e1777fb 100644 --- a/src/pulse-manager.h +++ b/src/pulse-manager.h @@ -1,3 +1,5 @@ +#ifndef __INCLUDE_PULSE_MANAGER_H__ +#define __INCLUDE_PULSE_MANAGER_H__ /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. @@ -21,7 +23,6 @@ with this program. If not, see . */ - #include #include #include "sound-service-dbus.h" @@ -47,4 +48,5 @@ void set_sink_volume(gdouble percent); void toggle_global_mute(gboolean mute_value); void close_pulse_activites(); +#endif diff --git a/src/sound-service.c b/src/sound-service.c index 61bf702..815fcdc 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -19,107 +19,22 @@ PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #include "sound-service.h" -#include "sound-service-dbus.h" +#include "dbus-menu-manager.h" #include "pulse-manager.h" -#include "slider-menu-item.h" -#include "common-defs.h" - -// GTK + DBUS static GMainLoop *mainloop = NULL; -static DbusmenuMenuitem *root_menuitem = NULL; -static DbusmenuMenuitem *mute_all_menuitem = NULL; -static SliderMenuItem *volume_slider_menuitem = NULL; -static SoundServiceDbus *dbus_interface = NULL; - -// PULSEAUDIO -static gboolean b_sink_available = FALSE; -static gboolean b_all_muted = FALSE; -static gboolean b_pulse_ready = FALSE; -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); - /**********************************************************************************************************************/ -// Init functions (GTK and DBUS) +// Init and exit functions /**********************************************************************************************************************/ -/** -Pass to the g_idle_add method - returning False will ensure that this method is never called again as it is removed as an event source. -**/ -static gboolean idle_routine (gpointer data) -{ - return FALSE; -} - - -static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data) -{ - GError * error = NULL; - if (!g_spawn_command_line_async("gnome-volume-control", &error)) - { - g_warning("Unable to show dialog: %s", error->message); - g_error_free(error); - } -} -/** -Build the DBus menu items. For now Mute all/Unmute is the only available option -**/ -static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service) -{ - // Mute button - mute_all_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(b_all_muted == FALSE ? "Mute All" : "Unmute")); - g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); - dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); - - // Slider - volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent); - dbusmenu_menuitem_child_append(root, mute_all_menuitem); - dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); - - DbusmenuMenuitem *separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append(root, separator); - DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, - _("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); -} /** -update_mute_ui: -'public' method allowing the server to update the mute UI +service_shutdown: +When the service interface starts to shutdown, we +should follow it. **/ -void update_mute_ui(gboolean incoming_mute_value) -{ - b_all_muted = incoming_mute_value; - dbusmenu_menuitem_property_set(mute_all_menuitem, - DBUSMENU_MENUITEM_PROP_LABEL, - _(b_all_muted == FALSE ? "Mute All" : "Unmute")); -} -/** -set_global_mute_from_ui: -Callback for the dbusmenuitem button -**/ -static void set_global_mute_from_ui() -{ - b_all_muted = !b_all_muted; - toggle_global_mute(b_all_muted); - dbusmenu_menuitem_property_set(mute_all_menuitem, - DBUSMENU_MENUITEM_PROP_LABEL, - _(b_all_muted == FALSE ? "Mute All" : "Unmute")); -} - - -/* When the service interface starts to shutdown, we - should follow it. - -*/ void service_shutdown (IndicatorService *service, gpointer user_data) { @@ -127,31 +42,15 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! - // TODO free the dbus interface !! - close_pulse_activites(); - g_main_loop_quit(mainloop); +/* close_pulse_activites();*/ +/* g_main_loop_quit(mainloop);*/ } return; } -void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent) -{ - b_sink_available = sink_available; - b_all_muted = sink_muted; - b_pulse_ready = pa_state; - volume_percent = percent; - g_debug("update pa state with state %i, availability of %i, mute value of %i and a volume percent is %f", pa_state, sink_available, sink_muted, volume_percent); - sound_service_dbus_update_sink_volume(dbus_interface, percent); - sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); - - // Only rebuild the menu on start up... - if(volume_slider_menuitem == NULL) - rebuild_sound_menu(root_menuitem, dbus_interface); -} - - -/* Main, is well, main. It brings everything up and throws - us into the mainloop of no return. Some refactoring needed.*/ +/** +main: +**/ int main (int argc, char ** argv) { @@ -167,16 +66,7 @@ main (int argc, char ** argv) INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); - root_menuitem = dbusmenu_menuitem_new(); - g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); - - g_idle_add(idle_routine, root_menuitem); - - dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); - - DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT); - dbusmenu_server_set_root(server, root_menuitem); - establish_pulse_activities(dbus_interface); + dbus_menu_manager_setup(); // Run the loop mainloop = g_main_loop_new(NULL, FALSE); diff --git a/src/sound-service.h b/src/sound-service.h index d36ea41..cefbf45 100644 --- a/src/sound-service.h +++ b/src/sound-service.h @@ -27,13 +27,6 @@ with this program. If not, see . #include #include -#include -#include - -#include -#include -#include - #include #include "dbus-shared-names.h" @@ -41,7 +34,5 @@ with this program. If not, see . // ENTRY AND EXIT POINTS void service_shutdown(IndicatorService * service, gpointer user_data); int main (int argc, char ** argv); -void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol); -void update_mute_ui(gboolean incoming_mute_value); -#endif +#endif -- cgit v1.2.3 From 259f58ec21be89f22f478243f4c8acf9a44231f9 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 3 Mar 2010 15:05:08 +0000 Subject: tests compiling --- src/dbus-menu-manager.c | 1 - src/indicator-sound.c | 1 + src/sound-service-dbus.c | 10 +++------- 3 files changed, 4 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 652e6b2..3e33932 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -113,7 +113,6 @@ void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); - //dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? _("Mute All") : _("Unmute"))); } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3aca517..4bdfbb7 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -238,6 +238,7 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata) { + // TODO: This could be safer. if (connected) { if (sound_dbus_proxy == NULL) { GError * error = NULL; diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 99a9d34..952a2d3 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -29,8 +29,7 @@ #include "sound-service-marshal.h" #include "pulse-manager.h" -// DBUS methods - -// TODO - other should be static and moved from the header to here +// DBUS methods static gboolean sound_service_dbus_get_sink_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror); static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror); static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror); @@ -41,7 +40,6 @@ typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { - DBusGConnection *system_bus; DBusGConnection *connection; gdouble volume_percent; gboolean mute; @@ -116,13 +114,10 @@ sound_service_dbus_init (SoundServiceDbus *self) GError *error = NULL; SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); - priv->system_bus = NULL; priv->connection = NULL; priv->volume_percent = 0; - /* Get the system bus */ - priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - /* Put the object on DBus */ + /* Fetch the session bus */ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (error != NULL) { @@ -130,6 +125,7 @@ sound_service_dbus_init (SoundServiceDbus *self) g_error_free(error); return; } + /* register the service on it */ dbus_g_connection_register_g_object(priv->connection, "/org/ayatana/indicator/sound/service", G_OBJECT(self)); -- cgit v1.2.3 From e2a152628f20271f5373702ad88fda483e0403ca Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 3 Mar 2010 21:57:43 +0000 Subject: debug trace was incorrect --- src/sound-service-dbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 952a2d3..72337fd 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -48,7 +48,7 @@ struct _SoundServiceDbusPrivate /* Signals */ enum { - SINK_INPUT_WHILE_MUTED, + SINK_INPUT_WHILE_MUTED, SINK_VOLUME_UPDATE, SINK_MUTE_UPDATE, LAST_SIGNAL @@ -121,7 +121,7 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (error != NULL) { - g_error("Unable to connect to the session bus when creating application indicator: %s", error->message); + g_error("sound-service-dbus:Unable to connect to the session bus when creating indicator sound service : %s", error->message); g_error_free(error); return; } -- cgit v1.2.3 From 633b514efeaf1c4086e1b2e5fbef185b199517c8 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 16:19:54 +0000 Subject: internationalisation reinstated whoops --- src/dbus-menu-manager.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 3e33932..17003df 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -18,6 +18,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + +#include +#include + #include #include @@ -112,7 +116,7 @@ void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) b_all_muted = incoming_mute_value; dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - (b_all_muted == FALSE ? "Mute All" : "Unmute")); + _(b_all_muted == FALSE ? "Mute All" : "Unmute")); } @@ -185,7 +189,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service { // Mute button mute_all_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); + dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(b_all_muted == FALSE ? "Mute All" : "Unmute")); g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); @@ -207,7 +211,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...")); 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); @@ -223,7 +227,7 @@ static void set_global_mute_from_ui() toggle_global_mute(b_all_muted); dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - (b_all_muted == FALSE ? "Mute All" : "Unmute")); + _(b_all_muted == FALSE ? "Mute All" : "Unmute")); } -- cgit v1.2.3 From 6b706a64c5bdcc4b33adfa94b5fa71dbda928399 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 18:02:45 +0000 Subject: slider stretching in place --- src/dbus-menu-manager.c | 5 ++--- src/indicator-sound.c | 47 +++++++++++++++++++++-------------------------- src/slider-menu-item.c | 1 + src/sound-service.c | 4 ++-- 4 files changed, 26 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 17003df..d2102ef 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - #include #include @@ -210,8 +209,8 @@ 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...")); + dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("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 3a6ae30..098b24f 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -78,14 +78,14 @@ G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); + //Slider related static GtkWidget *volume_slider = NULL; static gboolean new_slider_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget); -// Alternative callback mechanism, may use this again once ido is updated. -/*static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data);*/ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data); static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); +static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; @@ -96,6 +96,7 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); + /****Volume States 'members' ***/ static void update_state(const gint state); @@ -201,6 +202,7 @@ get_menu (IndicatorObject * io) return GTK_MENU(menu); } + /** new_slider_item: Create a new dBusMenu Slider item. @@ -220,10 +222,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - // alternative callback mechanism which i could use again at some point. -/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - + g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); @@ -277,9 +278,6 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u return; } - - - /* Prepare states Array. */ @@ -451,6 +449,21 @@ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data) return FALSE; } +/** +slider_size_allocate: +Callback on the size-allocate event on the slider item. +**/ +static void slider_size_allocate(GtkWidget *widget, + GtkAllocation *allocation, + gpointer user_data) +{ + g_print("size allocate on slider (%dx%d)\n", allocation->width, allocation->height); + if(allocation->width < 200) + { + gtk_widget_set_size_request(widget, 200, -1); + } +} + /** key_press_cb: **/ @@ -514,22 +527,4 @@ static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer dat return digested; } -/** -This callback should only be called when the user actually drags the slider. -Turned off for now in favour of the non descriminating value-changed call back. -Once the grabbing listener is implemented on the slider may revert to using this. -Its another tool for filtering unwanted volume change updates. -**/ -/*static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data)*/ -/*{*/ -/* DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;*/ -/* gdouble clamped_input = CLAMP(input_value, 0, 100);*/ -/* GValue value = {0};*/ -/* g_debug("User input on SLIDER - = %f", clamped_input);*/ -/* g_value_init(&value, G_TYPE_DOUBLE);*/ -/* g_value_set_double(&value, clamped_input);*/ -/* dbusmenu_menuitem_handle_event (item, "slider_change", &value, 0);*/ -/* return FALSE; */ -/*} */ - diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c index ef3b1fa..a14f4f9 100644 --- a/src/slider-menu-item.c +++ b/src/slider-menu-item.c @@ -92,6 +92,7 @@ SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_vol SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_SLIDER_MENUITEM_TYPE); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ENABLED, sinks_available); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, sinks_available); return self; } diff --git a/src/sound-service.c b/src/sound-service.c index 403b2b0..9e967c2 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -44,8 +44,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; } -- cgit v1.2.3 From 378c3c3f79aae564090593af6c6ce6abdb3c541a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 18:34:15 +0000 Subject: correct size now being used for the icons - design_team_size --- src/indicator-sound.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 098b24f..28f85b8 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -116,6 +116,9 @@ static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +#define DESIGN_TEAM_SIZE design_team_size +static GtkIconSize design_team_size; + // Construction static void indicator_sound_class_init (IndicatorSoundClass *klass) @@ -129,6 +132,8 @@ indicator_sound_class_init (IndicatorSoundClass *klass) io_class->get_label = get_label; io_class->get_image = get_icon; io_class->get_menu = get_menu; + + design_team_size = gtk_icon_size_register("design-team-size", 22, 22); /* dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,*/ /* G_TYPE_NONE,*/ @@ -181,7 +186,7 @@ get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -227,9 +232,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); gtk_widget_show_all(volume_slider); @@ -325,7 +330,7 @@ static void update_state(const gint state) current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(speaker_image, image_name, DESIGN_TEAM_SIZE); } -- cgit v1.2.3 From 8d392c8f315f18c1ebc52850141b103897e2eea2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 5 Mar 2010 10:38:57 +0000 Subject: blocking event now being registered, removed unneccessary marshaller --- src/Makefile.am | 18 ++---------------- src/dbus-menu-manager.c | 3 ++- src/indicator-sound.c | 17 ++++++----------- src/sound-service-dbus.h | 4 ---- 4 files changed, 10 insertions(+), 32 deletions(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 40a8fdd..73bb259 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,9 +11,7 @@ libsoundmenu_la_SOURCES = \ indicator-sound.h \ indicator-sound.c \ dbus-shared-names.h \ - sound-service-client.h \ - sound-service-marshal.c \ - sound-service-marshal.h + sound-service-client.h libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror libsoundmenu_la_LIBADD = $(APPLET_LIBS) @@ -30,16 +28,6 @@ sound-service-client.h: $(srcdir)/sound-service.xml --output=sound-service-client.h \ $(srcdir)/sound-service.xml -sound-service-marshal.h: $(srcdir)/sound-service.list - glib-genmarshal --header \ - --prefix=_sound_service_marshal $(srcdir)/sound-service.list \ - > sound-service-marshal.h - -sound-service-marshal.c: $(srcdir)/sound-service.list - glib-genmarshal --body \ - --prefix=_sound_service_marshal $(srcdir)/sound-service.list \ - > sound-service-marshal.c - ################# # Session Stuff @@ -74,9 +62,7 @@ sound-service-server.h: $(srcdir)/sound-service.xml ############### BUILT_SOURCES = \ sound-service-client.h \ - sound-service-server.h \ - sound-service-marshal.h \ - sound-service-marshal.c + sound-service-server.h EXTRA_DIST = \ sound-service.xml \ diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index d2102ef..243a3a7 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -157,7 +157,8 @@ static void refresh_menu() /** - +idle_routine: +Something for glip mainloop to do when idle **/ static gboolean idle_routine (gpointer data) { diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 28f85b8..1fb8090 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -90,7 +90,7 @@ static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata); -/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata);*/ +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata); static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata); static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata); static void fetch_volume_percent_from_dbus(); @@ -135,11 +135,6 @@ indicator_sound_class_init (IndicatorSoundClass *klass) design_team_size = gtk_icon_size_register("design-team-size", 22, 22); -/* dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,*/ -/* G_TYPE_NONE,*/ -/* G_TYPE_INT,*/ -/* G_TYPE_BOOLEAN,*/ -/* G_TYPE_INVALID);*/ return; } @@ -264,7 +259,7 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u 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_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_VOLUME_UPDATE, G_TYPE_DOUBLE, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); @@ -393,10 +388,10 @@ static void fetch_mute_value_from_dbus() g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } -/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata)*/ -/*{*/ -/* g_debug("signal caught - sink input while muted with value %i", block_value);*/ -/*}*/ +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) +{ + g_debug("signal caught - sink input while muted with value %i", block_value); +} static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index ef0d7dd..1a06117 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -49,10 +49,6 @@ struct _SoundServiceDbus { struct _SoundServiceDbusClass { GObjectClass parent_class; - /* Signals -> outward messages to the DBUS and beyond*/ - // TODO - ARE THESE NECESSARY ? - //void (* sink_input_while_muted) (SoundServiceDbus *self, gboolean block_value, gpointer sound_data); - //void (* sink_volume_update) (SoundServiceDbus *self, gdouble sink_volume, gpointer sound_data); }; GType sound_service_dbus_get_type (void) G_GNUC_CONST; -- cgit v1.2.3 From c462eb03f66d00a39562d00238f5dce35f371df6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 8 Mar 2010 19:12:18 +0000 Subject: no sink available dynamically being handled --- src/common-defs.h | 1 + src/dbus-menu-manager.c | 5 +++- src/indicator-sound.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- src/pulse-manager.c | 15 ++++++---- src/sound-service-dbus.c | 37 ++++++++++++++++++++++-- src/sound-service-dbus.h | 1 + src/sound-service.xml | 10 +++++++ 7 files changed, 134 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/common-defs.h b/src/common-defs.h index 942e269..9be1da5 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -22,6 +22,7 @@ with this program. If not, see . #define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted" #define SIGNAL_SINK_VOLUME_UPDATE "SinkVolumeUpdate" #define SIGNAL_SINK_MUTE_UPDATE "SinkMuteUpdate" +#define SIGNAL_SINK_AVAILABLE_UPDATE "SinkAvailableUpdate" // DBUS items #define DBUSMENU_SLIDER_MENUITEM_TYPE "x-canonical-ido-slider-item" diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 243a3a7..38ed727 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -101,6 +101,8 @@ void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_availabl refresh_menu(); } // Emit the signals after the menus are setup/torn down + // preserve ordering ! + sound_service_dbus_update_sink_availability(dbus_interface, sink_available); sound_service_dbus_update_sink_volume(dbus_interface, percent); sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); dbus_menu_manager_update_mute_ui(b_all_muted); @@ -199,7 +201,8 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_MENUITEM_PROP_ENABLED, - b_sink_available); + b_sink_available && !b_all_muted); + g_debug("!!!!!!**in the rebuild sound menu - slider active = %i", b_sink_available && !b_all_muted); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, b_sink_available); diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 1fb8090..c10b549 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -93,8 +93,10 @@ static void connection_changed (IndicatorServiceManager * sm, gboolean connected static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata); static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata); static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata); +static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata); static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); +static void fetch_sink_availability_from_dbus(); /****Volume States 'members' ***/ @@ -110,11 +112,13 @@ static const gint STATE_SINKS_NONE = 6; static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; +static GtkImage *blocking_image = NULL; static GtkWidget* primary_image = NULL; static gint current_state = 0; static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +static gboolean device_available = TRUE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; @@ -182,6 +186,8 @@ get_icon (IndicatorObject * io) gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); + gchar* blocking_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + blocking_image = GTK_IMAGE(gtk_image_new_from_icon_name(blocking_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -264,11 +270,14 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), 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), NULL, 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); // Ensure we are in a coherent state with the service at start up. // Preserve ordering! fetch_volume_percent_from_dbus(); fetch_mute_value_from_dbus(); + fetch_sink_availability_from_dbus(); } } else { @@ -332,7 +341,8 @@ static void update_state(const gint state) void determine_state_from_volume(gdouble volume_percent) { /* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ - + if (device_available == FALSE) + return; gint state = previous_state; if (volume_percent < 30.0 && volume_percent > 0){ state = STATE_LOW; @@ -350,6 +360,25 @@ void determine_state_from_volume(gdouble volume_percent) } +static void fetch_sink_availability_from_dbus() +{ + GError * error = NULL; + gboolean *available_input; + available_input = g_new0(gboolean, 1); + org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); + if (error != NULL) { + g_warning("Unable to fetch AVAILABILITY at indicator start up: %s", error->message); + g_error_free(error); + g_free(available_input); + return; + } + device_available = *available_input; + if (device_available == FALSE) + update_state(STATE_SINKS_NONE); + g_free(available_input); + g_debug("IndicatorSound::fetch_sink_availability_from_dbus -> AVAILABILTY returned from dbus method is %i", device_available); + +} static void fetch_volume_percent_from_dbus() { @@ -391,6 +420,38 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); + if (block_value == 1) { + GError* error= NULL; + // We can assume we are in the muted state ! + GtkIconTheme* theme = gtk_icon_theme_get_default(); + GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, + g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); + g_error_free(error); + return; + } + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); + g_error_free(error); + return; + } + g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); + gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, + gdk_pixbuf_get_width(blocked_buf), + gdk_pixbuf_get_height(blocked_buf), + 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128); + //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); + //gtk_image_set_from_pixbuf(speaker_image, blocked_buf); + } } static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) @@ -409,13 +470,23 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value { //We can be sure the service won't send a mute signal unless it has changed ! //UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here. - if(mute_value == TRUE) + if(mute_value == TRUE && device_available != FALSE) { update_state(STATE_MUTED); } g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } + +static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata) +{ + device_available = available_value; + if (device_available == FALSE){ + update_state(STATE_SINKS_NONE); + } + g_debug("signal caught - sink availability update with value: %i", available_value); +} + /** slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 36e6351..40add4e 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -282,7 +282,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in else{ //Update the indicator to show PA either is not ready or has no available sink g_warning("Cannot find a suitable default sink ..."); - dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, device_available, default_sink_is_muted(), get_default_sink_volume()); } } else{ @@ -398,6 +398,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v } else { + sink_info *value; value = g_new0(sink_info, 1); value->index = value->device_index = info->index; @@ -411,7 +412,8 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v value->channel_map = info->channel_map; g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); g_debug("pulse-manager:update_sink_info -> After adding a new sink to our hash"); - } + sound_service_dbus_update_sink_availability(dbus_service, TRUE); + } } @@ -460,8 +462,11 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event g_debug("PA_SUBSCRIPTION_EVENT_SINK event triggered"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - //TODO handle the remove event => if its our default sink - update date pa state - } else + if(index == DEFAULT_SINK_INDEX) + g_debug("PA_SUBSCRIPTION_EVENT_SINK REMOVAL event triggered"); + sound_service_dbus_update_sink_availability(dbus_service, FALSE); + } + else { pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); } @@ -470,7 +475,7 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event g_debug("PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - //TODO handle the remove event + //handle the remove event - not relevant for current design } else { diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 72337fd..1cc5f0d 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -32,6 +32,7 @@ // DBUS methods static gboolean sound_service_dbus_get_sink_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror); static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror); +static gboolean sound_service_dbus_get_sink_availability(SoundServiceDbus* service, gboolean* availability_input, GError** gerror); static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror); #include "sound-service-server.h" @@ -43,6 +44,7 @@ struct _SoundServiceDbusPrivate DBusGConnection *connection; gdouble volume_percent; gboolean mute; + gboolean sink_availability; }; @@ -51,6 +53,7 @@ enum { SINK_INPUT_WHILE_MUTED, SINK_VOLUME_UPDATE, SINK_MUTE_UPDATE, + SINK_AVAILABLE_UPDATE, LAST_SIGNAL }; @@ -105,6 +108,15 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass) NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + signals[SINK_AVAILABLE_UPDATE] = g_signal_new("sink-available-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + } @@ -116,6 +128,8 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->connection = NULL; priv->volume_percent = 0; + priv->mute = FALSE; + priv->sink_availability = FALSE; /* Fetch the session bus */ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); @@ -129,8 +143,6 @@ sound_service_dbus_init (SoundServiceDbus *self) dbus_g_connection_register_g_object(priv->connection, "/org/ayatana/indicator/sound/service", G_OBJECT(self)); - - return; } @@ -174,6 +186,14 @@ static gboolean sound_service_dbus_get_sink_mute (SoundServiceDbus *self, gboole return TRUE; } +static gboolean sound_service_dbus_get_sink_availability (SoundServiceDbus *self, gboolean *availability_input, GError** gerror) +{ + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); + g_debug("Get sink availability - sound service dbus!, about to send over availability_value of %i", priv->sink_availability); + *availability_input = priv->sink_availability; + return TRUE; +} + /** SIGNALS Utility methods to emit signals from the service into the ether. @@ -212,5 +232,18 @@ void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mu priv->mute); } +void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availability) +{ + g_debug("Emitting signal: SINK_AVAILABILITY_UPDATE, with value %i", sink_availability); + + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); + priv->sink_availability = sink_availability; + + g_signal_emit(obj, + signals[SINK_AVAILABLE_UPDATE], + 0, + priv->sink_availability); +} + diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index 1a06117..ae4953e 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -56,6 +56,7 @@ GType sound_service_dbus_get_type (void) G_GNUC_CONST; void sound_service_dbus_sink_input_while_muted (SoundServiceDbus* obj, gboolean block_value); void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume); void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mute); +void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availibity); G_END_DECLS diff --git a/src/sound-service.xml b/src/sound-service.xml index 580f0e1..12ed03e 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -5,6 +5,7 @@ + @@ -15,6 +16,11 @@ + + + + + @@ -30,6 +36,10 @@ Our respective UI element should listen to this and therefore will be updated wi + + + + -- cgit v1.2.3 From ea8064d34d73a1b242cc571fbfd9f0f39128178a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 9 Mar 2010 18:10:09 +0000 Subject: smoother slider actions due ido grabbing update and pixbuf icon loading problems --- src/dbus-menu-manager.c | 5 ++ src/indicator-sound.c | 124 ++++++++++++++++++++++++++++++------------------ 2 files changed, 83 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 38ed727..64f7108 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -154,6 +154,11 @@ static void refresh_menu() DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); } +/* if(b_all_muted == TRUE){*/ +/* dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), */ +/* DBUSMENU_MENUITEM_PROP_ENABLED,*/ +/* FALSE); */ +/* }*/ } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index c10b549..5fd68b2 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -5,7 +5,7 @@ into the gnome-panel using it's applet interface. Copyright 2010 Canonical Ltd. Authors: - Conor Curran + Conor Curran Ted Gould This program is free software: you can redistribute it and/or modify it @@ -82,10 +82,12 @@ static GtkMenu * get_menu (IndicatorObject * io); //Slider related static GtkWidget *volume_slider = NULL; static gboolean new_slider_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); -static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget); +/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget);*/ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data); static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); +static void slider_grabbed(GtkWidget *widget, gpointer user_data); +static void slider_released(GtkWidget *widget, gpointer user_data); // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; @@ -98,7 +100,6 @@ static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); static void fetch_sink_availability_from_dbus(); - /****Volume States 'members' ***/ static void update_state(const gint state); @@ -112,13 +113,13 @@ static const gint STATE_SINKS_NONE = 6; static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; -static GtkImage *blocking_image = NULL; -static GtkWidget* primary_image = NULL; static gint current_state = 0; static gint previous_state = 0; + static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; static gboolean device_available = TRUE; +static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; @@ -184,10 +185,8 @@ static GtkImage * get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - //g_debug("At start-up attempting to set the image to %s", current_name); + g_debug("At start-up attempting to set the image to %s", current_name); speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); - gchar* blocking_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); - blocking_image = GTK_IMAGE(gtk_image_new_from_icon_name(blocking_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -204,7 +203,6 @@ get_menu (IndicatorObject * io) // register Key-press listening on the menu widget as the slider does not allow this. g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); - return GTK_MENU(menu); } @@ -224,15 +222,16 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); +/* g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);*/ // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - - g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); + g_signal_connect(volume_slider, "slider-grabbed", G_CALLBACK(slider_grabbed), NULL); + g_signal_connect(volume_slider, "slider-released", G_CALLBACK(slider_released), NULL); + g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido - primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); + GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); @@ -413,6 +412,9 @@ static void fetch_mute_value_from_dbus() initial_mute = *mute_input; if (initial_mute == TRUE) update_state(STATE_MUTED); +// TODO bug down below - VIRTUALLY IMPOSSIBLE TO SETUP SLIDER WITH ANY ALTERNATIVE STARTUP STATE +/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ +/* gtk_widget_set_sensitive(slider, !initial_mute);*/ g_free(mute_input); g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } @@ -423,18 +425,25 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean blo if (block_value == 1) { GError* error= NULL; // We can assume we are in the muted state ! + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); GtkIconTheme* theme = gtk_icon_theme_get_default(); - GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, - g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK, - &error); + g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); +/* GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, */ +/* blocked_name,*/ +/* 22,*/ +/* GTK_ICON_LOOKUP_GENERIC_FALLBACK,*/ +/* &error);*/ if(error != NULL){ g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); g_error_free(error); return; } - gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + + GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK); + g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info)); + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, 22, GTK_ICON_LOOKUP_GENERIC_FALLBACK, @@ -445,25 +454,34 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean blo return; } g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); - gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, - gdk_pixbuf_get_width(blocked_buf), - gdk_pixbuf_get_height(blocked_buf), - 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128); +/* gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0,*/ +/* gdk_pixbuf_get_width(blocked_buf),*/ +/* gdk_pixbuf_get_height(blocked_buf), */ +/* 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128);*/ //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); - //gtk_image_set_from_pixbuf(speaker_image, blocked_buf); + + g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); + gchar ** theme_path; + gint nelements = 1; + + gtk_icon_theme_get_search_path(theme, &theme_path, &nelements); + g_debug("icon theme path is %s ", *theme_path); + gtk_image_set_from_pixbuf(speaker_image, blocked_buf); } } static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - GtkRange *range = (GtkRange*)slider; - - // DEBUG - gdouble current_value = gtk_range_get_value(range); - g_debug("SIGNAL- update sink volume - current_value : %f and new value : %f", current_value, volume_percent); - gtk_range_set_value(range, volume_percent); - determine_state_from_volume(volume_percent); + if (slider_in_direct_use != TRUE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + GtkRange *range = (GtkRange*)slider; + + // DEBUG + gdouble current_value = gtk_range_get_value(range); + g_debug("SIGNAL- update sink volume - current_value : %f and new value : %f", current_value, volume_percent); + gtk_range_set_value(range, volume_percent); + determine_state_from_volume(volume_percent); + } } static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata) @@ -491,15 +509,15 @@ static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean av slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. **/ -static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget) -{ - g_debug("slider_prop_change_cb - dodgy updater "); - g_debug("about to set the slider to %f", g_value_get_double(value)); - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - GtkRange* range = (GtkRange*)slider; - gtk_range_set_value(range, g_value_get_double(value)); - return; -} +/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget)*/ +/*{*/ +/* g_debug("slider_prop_change_cb - dodgy updater ");*/ +/* g_debug("about to set the slider to %f", g_value_get_double(value));*/ +/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ +/* GtkRange* range = (GtkRange*)slider; */ +/* gtk_range_set_value(range, g_value_get_double(value)); */ +/* return;*/ +/*}*/ /** value_changed_event_cb: @@ -520,6 +538,20 @@ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data) return FALSE; } + +static void slider_grabbed (GtkWidget *widget, gpointer user_data) +{ + slider_in_direct_use = TRUE; + g_debug ("!!!!!! grabbed\n"); +} + +static void slider_released (GtkWidget *widget, gpointer user_data) +{ + slider_in_direct_use = FALSE; + g_debug ("!!!!!! released\n"); +} + + /** slider_size_allocate: Callback on the size-allocate event on the slider item. @@ -528,10 +560,10 @@ static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { - g_print("size allocate on slider (%dx%d)\n", allocation->width, allocation->height); - if(allocation->width < 200) - { - gtk_widget_set_size_request(widget, 200, -1); + g_print("Size allocate on slider (%dx%d)\n", allocation->width, allocation->height); + if(allocation->width < 200){ + g_print("Attempting to resize the slider"); + gtk_widget_set_size_request(widget, 200, -1); } } -- cgit v1.2.3 From 16021586200c0e7746ce787e43a8721dfe23ae48 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 10 Mar 2010 10:53:23 +0000 Subject: fixed that annoying startup in mute state allowing slider to move - race conditions on start up are pretty hairy --- src/indicator-sound.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 5fd68b2..1876e69 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -235,6 +235,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); + + // the race conditions at start up are like a west waterford greyhound dart. god knows who wins, who breaks a leg. + gtk_widget_set_sensitive(volume_slider, !initial_mute); gtk_widget_show_all(volume_slider); @@ -412,9 +415,6 @@ static void fetch_mute_value_from_dbus() initial_mute = *mute_input; if (initial_mute == TRUE) update_state(STATE_MUTED); -// TODO bug down below - VIRTUALLY IMPOSSIBLE TO SETUP SLIDER WITH ANY ALTERNATIVE STARTUP STATE -/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ -/* gtk_widget_set_sensitive(slider, !initial_mute);*/ g_free(mute_input); g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } -- cgit v1.2.3 From 59eb14451f0635c286d482e8b35cad622882aa35 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 10 Mar 2010 18:10:40 +0000 Subject: fade animation in place --- src/indicator-sound.c | 181 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 45 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 1876e69..ebd4306 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -123,6 +123,13 @@ static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; +static gint timeout_id; +static gint animation_id; +static GList * blocked_animation_list = NULL; +static GList * blocked_iter = NULL; +static void prepare_blocked_animation(); +static gboolean fade_back_to_mute_image(); +static gboolean commence_animation(); // Construction static void @@ -151,6 +158,9 @@ static void indicator_sound_init (IndicatorSound *self) self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_VERSION); g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); prepare_state_machine(); + prepare_blocked_animation(); + timeout_id = 0; + animation_id = 0; return; } @@ -164,6 +174,8 @@ indicator_sound_dispose (GObject *object) self->service = NULL; } g_hash_table_destroy(volume_states); + // TODO delete all pointers in the list; + g_list_free(blocked_animation_list); G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); return; } @@ -305,6 +317,51 @@ void prepare_state_machine() g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); } +/* +prepare_blocked_animation: +Prepares the array of images to be used in the blocked animation. +Only called at startup. +*/ +static void prepare_blocked_animation() +{ + GError* error= NULL; + int i; + + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + gchar* muted_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)); + GtkIconTheme* theme = gtk_icon_theme_get_default(); + GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, + muted_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : prepare_blocked_animation - %s", error->message); + g_error_free(error); + return; + } + + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : prepare_blocked_animation - %s", error->message); + g_error_free(error); + return; + } + + for(i = 0; i < 256; i++) + { + gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, + gdk_pixbuf_get_width(mute_buf), + gdk_pixbuf_get_height(mute_buf), + 0, 0, 1, 1, GDK_INTERP_BILINEAR, i); + g_debug("creating animation - alpha value = %i", i); + blocked_animation_list = g_list_append(blocked_animation_list, gdk_pixbuf_copy(blocked_buf)); + } +} + gint get_state() { return current_state; @@ -365,7 +422,7 @@ void determine_state_from_volume(gdouble volume_percent) static void fetch_sink_availability_from_dbus() { GError * error = NULL; - gboolean *available_input; + gboolean * available_input; available_input = g_new0(gboolean, 1); org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); if (error != NULL) { @@ -422,53 +479,75 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); - if (block_value == 1) { - GError* error= NULL; + if (block_value == 1 && timeout_id == 0 ) { // We can assume we are in the muted state ! - gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); - GtkIconTheme* theme = gtk_icon_theme_get_default(); - g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); -/* GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, */ -/* blocked_name,*/ -/* 22,*/ -/* GTK_ICON_LOOKUP_GENERIC_FALLBACK,*/ -/* &error);*/ - if(error != NULL){ - g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); - g_error_free(error); - return; - } - - GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name, - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK); - g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info)); - - GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK, - &error); - if(error != NULL){ - g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); - g_error_free(error); - return; - } - g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); -/* gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0,*/ -/* gdk_pixbuf_get_width(blocked_buf),*/ -/* gdk_pixbuf_get_height(blocked_buf), */ -/* 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128);*/ - //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); - - g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); - gchar ** theme_path; - gint nelements = 1; + gtk_image_set_from_icon_name(speaker_image, + g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), + DESIGN_TEAM_SIZE); + blocked_iter = blocked_animation_list; + timeout_id = g_timeout_add_seconds(3, commence_animation, NULL); + } +} - gtk_icon_theme_get_search_path(theme, &theme_path, &nelements); - g_debug("icon theme path is %s ", *theme_path); - gtk_image_set_from_pixbuf(speaker_image, blocked_buf); - } +static gboolean commence_animation() +{ + animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); + timeout_id = 0; + g_debug("out of there\n"); + return FALSE; +} + +static gboolean fade_back_to_mute_image() +{ + g_debug("fade me entry\n"); + if(blocked_iter != NULL) + { + g_debug("in there\n"); + gtk_image_set_from_pixbuf(speaker_image, blocked_iter->data); + blocked_iter = blocked_iter->next; + return TRUE; + } + else{ + animation_id = 0; + g_debug("out of there\n"); + return FALSE; + } } +/* int i;*/ +/* GList * anim_iter;*/ +/* anim_iter = blocked_animation_list;*/ +/* for(i=0; i < 2560000; i++)*/ +/* { */ +/* if(i % 100000 == 0)*/ +/* {*/ +/* if (anim_iter != NULL)*/ +/* {*/ +/* gtk_image_set_from_pixbuf(speaker_image, anim_iter->data); */ +/* anim_iter = anim_iter->next; */ +/* g_debug("should now be setting each image");*/ +/* }*/ +/* }*/ +/* }*/ +/* gtk_image_set_from_icon_name(speaker_image,*/ +/* g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)),*/ +/* DESIGN_TEAM_SIZE);*/ + //fade_id = g_timeout_add_seconds(0.2, fade_each_frame, NULL); + + + + +/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ +/* GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name,*/ +/* 22,*/ +/* GTK_ICON_LOOKUP_GENERIC_FALLBACK);*/ +/* g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info));*/ +/* g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf));*/ +/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ +/* gchar ** theme_path; */ +/* gint nelements = 1;*/ +/* gtk_icon_theme_get_search_path(theme, &theme_path, &nelements);*/ +/* gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE);*/ +/* g_debug("icon theme path is %s ", *theme_path);*/ static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { @@ -492,6 +571,18 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value { update_state(STATE_MUTED); } + else{ + if(timeout_id != 0){ + g_debug("about to remove the timeout_id callback from the mainloop!!**"); + g_source_remove(timeout_id); + timeout_id = 0; + } + if(animation_id != 0){ + g_debug("about to remove the animation_id callback from the mainloop!!**"); + g_source_remove(animation_id); + animation_id = 0; + } + } g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } -- cgit v1.2.3 From c67c7ac2effb7ee425370ee33e6b5449e04b98c6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 11 Mar 2010 00:23:59 +0000 Subject: animation working much better now --- src/indicator-sound.c | 85 +++++---------------------------------------------- 1 file changed, 8 insertions(+), 77 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index ebd4306..d9c5aa6 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -123,13 +123,11 @@ static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; -static gint timeout_id; static gint animation_id; static GList * blocked_animation_list = NULL; static GList * blocked_iter = NULL; static void prepare_blocked_animation(); static gboolean fade_back_to_mute_image(); -static gboolean commence_animation(); // Construction static void @@ -152,14 +150,11 @@ indicator_sound_class_init (IndicatorSoundClass *klass) static void indicator_sound_init (IndicatorSound *self) { - /* Set good defaults */ self->service = NULL; - /* Now let's fire these guys up. */ self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_VERSION); g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); prepare_state_machine(); prepare_blocked_animation(); - timeout_id = 0; animation_id = 0; return; } @@ -234,7 +229,6 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); -/* g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);*/ // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); @@ -306,7 +300,6 @@ Prepare states Array. */ void prepare_state_machine() { - // TODO we need three more images volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel")); @@ -350,14 +343,14 @@ static void prepare_blocked_animation() g_error_free(error); return; } - - for(i = 0; i < 256; i++) + // sample 22 snapshots - range : 0-256 + for(i = 0; i < 23; i++) { gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, gdk_pixbuf_get_width(mute_buf), gdk_pixbuf_get_height(mute_buf), - 0, 0, 1, 1, GDK_INTERP_BILINEAR, i); - g_debug("creating animation - alpha value = %i", i); + 0, 0, 1, 1, GDK_INTERP_BILINEAR, MIN(255, i * 11)); + g_debug("creating blocking animation - alpha value = %i", MIN(255, i * 11)); blocked_animation_list = g_list_append(blocked_animation_list, gdk_pixbuf_copy(blocked_buf)); } } @@ -479,75 +472,31 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); - if (block_value == 1 && timeout_id == 0 ) { + if (block_value == 1 && animation_id == 0 ) { // We can assume we are in the muted state ! gtk_image_set_from_icon_name(speaker_image, g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), DESIGN_TEAM_SIZE); blocked_iter = blocked_animation_list; - timeout_id = g_timeout_add_seconds(3, commence_animation, NULL); + animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); } } - -static gboolean commence_animation() -{ - animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); - timeout_id = 0; - g_debug("out of there\n"); - return FALSE; -} static gboolean fade_back_to_mute_image() { - g_debug("fade me entry\n"); if(blocked_iter != NULL) { - g_debug("in there\n"); + g_debug("in animation 'loop'\n"); gtk_image_set_from_pixbuf(speaker_image, blocked_iter->data); blocked_iter = blocked_iter->next; return TRUE; } else{ animation_id = 0; - g_debug("out of there\n"); + g_debug("exit from animation\n"); return FALSE; } } -/* int i;*/ -/* GList * anim_iter;*/ -/* anim_iter = blocked_animation_list;*/ -/* for(i=0; i < 2560000; i++)*/ -/* { */ -/* if(i % 100000 == 0)*/ -/* {*/ -/* if (anim_iter != NULL)*/ -/* {*/ -/* gtk_image_set_from_pixbuf(speaker_image, anim_iter->data); */ -/* anim_iter = anim_iter->next; */ -/* g_debug("should now be setting each image");*/ -/* }*/ -/* }*/ -/* }*/ -/* gtk_image_set_from_icon_name(speaker_image,*/ -/* g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)),*/ -/* DESIGN_TEAM_SIZE);*/ - //fade_id = g_timeout_add_seconds(0.2, fade_each_frame, NULL); - - - - -/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ -/* GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name,*/ -/* 22,*/ -/* GTK_ICON_LOOKUP_GENERIC_FALLBACK);*/ -/* g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info));*/ -/* g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf));*/ -/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ -/* gchar ** theme_path; */ -/* gint nelements = 1;*/ -/* gtk_icon_theme_get_search_path(theme, &theme_path, &nelements);*/ -/* gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE);*/ -/* g_debug("icon theme path is %s ", *theme_path);*/ static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { @@ -572,11 +521,6 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value update_state(STATE_MUTED); } else{ - if(timeout_id != 0){ - g_debug("about to remove the timeout_id callback from the mainloop!!**"); - g_source_remove(timeout_id); - timeout_id = 0; - } if(animation_id != 0){ g_debug("about to remove the animation_id callback from the mainloop!!**"); g_source_remove(animation_id); @@ -596,19 +540,6 @@ static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean av g_debug("signal caught - sink availability update with value: %i", available_value); } -/** -slider_prop_change_cb: -Whenever we have a property change on a DbusmenuMenuitem this will be called. -**/ -/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget)*/ -/*{*/ -/* g_debug("slider_prop_change_cb - dodgy updater ");*/ -/* g_debug("about to set the slider to %f", g_value_get_double(value));*/ -/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ -/* GtkRange* range = (GtkRange*)slider; */ -/* gtk_range_set_value(range, g_value_get_double(value)); */ -/* return;*/ -/*}*/ /** value_changed_event_cb: -- cgit v1.2.3 From 69c96d7e7fa903569073bd87069b2d9f6aeb3fa4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Mar 2010 22:59:35 -0600 Subject: Update to use new icon helper from libindicator --- src/indicator-sound.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3a6ae30..0b92af8 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -34,6 +34,7 @@ with this program. If not, see . #include #include #include +#include #include "indicator-sound.h" #include "dbus-shared-names.h" @@ -180,7 +181,7 @@ get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + speaker_image = indicator_image_helper(current_name); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -327,7 +328,9 @@ static void update_state(const gint state) current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); + GtkImage * tempimage = indicator_image_helper(image_name); + gtk_image_set_from_pixbuf(speaker_image, gtk_image_get_pixbuf(tempimage)); + g_object_ref_sink(tempimage); } -- cgit v1.2.3 From 21d52b5ed3206791d5a0b4adc907be75a9e5f668 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Mar 2010 23:07:22 -0600 Subject: Using GIcon for setting the icons on the IDO slider. --- src/indicator-sound.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 0b92af8..2dc6bf3 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -225,12 +225,23 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p // alternative callback mechanism which i could use again at some point. /* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - // Set images on the ido + /* Get the primary Image */ primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + + /* Build a GIcon for the theme fallbacks */ + GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks(g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO))); + gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(primary_gicon); + + /* Get the secondary image */ GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + /* Build a GIcon for fallbacks */ + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks(g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH))); + gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(secondary_gicon); + + /* Make the widget visible to users */ gtk_widget_show_all(volume_slider); return TRUE; -- cgit v1.2.3