diff options
-rw-r--r-- | configure.ac | 6 | ||||
-rw-r--r-- | docs/reference/libappindicator-sections.txt | 1 | ||||
-rw-r--r-- | example/simple-client.c | 5 | ||||
-rw-r--r-- | src/libappindicator/app-indicator.c | 78 | ||||
-rw-r--r-- | src/libappindicator/app-indicator.h | 1 |
5 files changed, 80 insertions, 11 deletions
diff --git a/configure.ac b/configure.ac index 713f40e..ebd6b20 100644 --- a/configure.ac +++ b/configure.ac @@ -1,11 +1,11 @@ -AC_INIT(indicator-application, 0.0.8, ted@canonical.com) -AC_COPYRIGHT([Copyright 2009 Canonical]) +AC_INIT(indicator-application, 0.0.9, ted@canonical.com) +AC_COPYRIGHT([Copyright 2009, 2010 Canonical]) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-application, 0.0.8) +AM_INIT_AUTOMAKE(indicator-application, 0.0.9) AM_MAINTAINER_MODE diff --git a/docs/reference/libappindicator-sections.txt b/docs/reference/libappindicator-sections.txt index 68b120a..70df0b8 100644 --- a/docs/reference/libappindicator-sections.txt +++ b/docs/reference/libappindicator-sections.txt @@ -28,5 +28,6 @@ app_indicator_get_category app_indicator_get_status app_indicator_get_icon app_indicator_get_attention_icon +app_indicator_get_menu </SECTION> diff --git a/example/simple-client.c b/example/simple-client.c index 8ff3827..6dcf5d1 100644 --- a/example/simple-client.c +++ b/example/simple-client.c @@ -73,26 +73,31 @@ main (int argc, char ** argv) g_signal_connect (item, "activate", G_CALLBACK (item_clicked_cb), "1"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show(item); item = gtk_radio_menu_item_new_with_label (NULL, "2"); g_signal_connect (item, "activate", G_CALLBACK (item_clicked_cb), "2"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show(item); item = gtk_menu_item_new_with_label ("3"); g_signal_connect (item, "activate", G_CALLBACK (item_clicked_cb), "3"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show(item); GtkWidget *toggle_item = gtk_menu_item_new_with_label ("Toggle 3"); g_signal_connect (toggle_item, "activate", G_CALLBACK (toggle_sensitivity_cb), item); gtk_menu_shell_append (GTK_MENU_SHELL (menu), toggle_item); + gtk_widget_show(toggle_item); item = gtk_image_menu_item_new_from_stock (GTK_STOCK_NEW, NULL); g_signal_connect (item, "activate", G_CALLBACK (image_clicked_cb), NULL); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); + gtk_widget_show(item); app_indicator_set_menu (ci, GTK_MENU (menu)); diff --git a/src/libappindicator/app-indicator.c b/src/libappindicator/app-indicator.c index e38e760..6c969c2 100644 --- a/src/libappindicator/app-indicator.c +++ b/src/libappindicator/app-indicator.c @@ -133,9 +133,11 @@ static void app_indicator_get_property (GObject * object, guint prop_id, GValue /* Other stuff */ static void check_connect (AppIndicator * self); static void register_service_cb (DBusGProxy * proxy, GError * error, gpointer data); -static void start_fallback_timer (AppIndicator * self, gboolean do_it_now); +static void start_fallback_timer (AppIndicator * self, gboolean disable_timeout); static gboolean fallback_timer_expire (gpointer data); static GtkStatusIcon * fallback (AppIndicator * self); +static void status_icon_status_wrapper (AppIndicator * self, const gchar * status, gpointer data); +static void status_icon_changes (AppIndicator * self, gpointer data); static void status_icon_activate (GtkStatusIcon * icon, gpointer data); static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon); static void watcher_proxy_destroyed (GObject * object, gpointer data); @@ -683,7 +685,7 @@ dbus_owner_change (DBusGProxy * proxy, const gchar * name, const gchar * prev, c there is a change. Also, provides an override mode for cases where it's unlikely that a timer will help anything. */ static void -start_fallback_timer (AppIndicator * self, gboolean do_it_now) +start_fallback_timer (AppIndicator * self, gboolean disable_timeout) { g_return_if_fail(IS_APP_INDICATOR(self)); AppIndicatorPrivate * priv = APP_INDICATOR(self)->priv; @@ -706,7 +708,7 @@ start_fallback_timer (AppIndicator * self, gboolean do_it_now) G_CALLBACK(dbus_owner_change), self, NULL); } - if (do_it_now) { + if (disable_timeout) { fallback_timer_expire(self); } else { priv->fallback_timer = g_timeout_add(DEFAULT_FALLBACK_TIMER, fallback_timer_expire, self); @@ -734,7 +736,7 @@ fallback_timer_expire (gpointer data) class->unfallback(APP_INDICATOR(data), priv->status_icon); priv->status_icon = NULL; } else { - g_warning("Can't 'unfallback' and I have an allocated status_icon. Might be a memory leak!"); + g_warning("No 'unfallback' function but the 'fallback' function returned a non-NULL result."); } } @@ -751,6 +753,35 @@ fallback (AppIndicator * self) gtk_status_icon_set_title(icon, app_indicator_get_id(self)); + g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_STATUS, + G_CALLBACK(status_icon_changes), icon); + g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_ICON, + G_CALLBACK(status_icon_changes), icon); + g_signal_connect(G_OBJECT(self), APP_INDICATOR_SIGNAL_NEW_ATTENTION_ICON, + G_CALLBACK(status_icon_changes), icon); + + status_icon_changes(self, icon); + + g_signal_connect(G_OBJECT(icon), "activate", G_CALLBACK(status_icon_activate), self); + + return icon; +} + +/* A wrapper as the status update prototype is a little + bit different, but we want to handle it the same. */ +static void +status_icon_status_wrapper (AppIndicator * self, const gchar * status, gpointer data) +{ + return status_icon_changes(self, data); +} + +/* This tracks changes to either the status or the icons + that are associated with the app indicator */ +static void +status_icon_changes (AppIndicator * self, gpointer data) +{ + GtkStatusIcon * icon = GTK_STATUS_ICON(data); + switch (app_indicator_get_status(self)) { case APP_INDICATOR_STATUS_PASSIVE: gtk_status_icon_set_visible(icon, FALSE); @@ -766,9 +797,7 @@ fallback (AppIndicator * self) break; }; - g_signal_connect(G_OBJECT(icon), "activate", G_CALLBACK(status_icon_activate), self); - - return NULL; + return; } /* Handles the activate action by the status icon by showing @@ -776,7 +805,18 @@ fallback (AppIndicator * self) static void status_icon_activate (GtkStatusIcon * icon, gpointer data) { - g_debug("Status Icon Activate"); + GtkMenu * menu = app_indicator_get_menu(APP_INDICATOR(data)); + if (menu == NULL) + return; + + gtk_menu_popup(menu, + NULL, /* Parent Menu */ + NULL, /* Parent item */ + gtk_status_icon_position_menu, + icon, + 1, /* Button */ + gtk_get_current_event_time()); + return; } @@ -785,6 +825,8 @@ status_icon_activate (GtkStatusIcon * icon, gpointer data) static void unfallback (AppIndicator * self, GtkStatusIcon * status_icon) { + g_signal_handlers_disconnect_by_func(G_OBJECT(self), status_icon_status_wrapper, status_icon); + g_signal_handlers_disconnect_by_func(G_OBJECT(self), status_icon_changes, status_icon); g_object_unref(G_OBJECT(status_icon)); return; } @@ -1267,3 +1309,23 @@ app_indicator_get_attention_icon (AppIndicator *self) return self->priv->attention_icon_name; } + +/** + app_indicator_get_menu: + @self: The #AppIndicator object to use + + Gets the menu being used for this application indicator. + + Return value: A menu object or #NULL if one hasn't been set. +*/ +GtkMenu * +app_indicator_get_menu (AppIndicator *self) +{ + AppIndicatorPrivate *priv; + + g_return_val_if_fail (IS_APP_INDICATOR (self), NULL); + + priv = self->priv; + + return GTK_MENU(priv->menu); +} diff --git a/src/libappindicator/app-indicator.h b/src/libappindicator/app-indicator.h index a8d82ab..03656ce 100644 --- a/src/libappindicator/app-indicator.h +++ b/src/libappindicator/app-indicator.h @@ -228,6 +228,7 @@ AppIndicatorCategory app_indicator_get_category (AppIndicator * AppIndicatorStatus app_indicator_get_status (AppIndicator *self); const gchar * app_indicator_get_icon (AppIndicator *self); const gchar * app_indicator_get_attention_icon (AppIndicator *self); +GtkMenu * app_indicator_get_menu (AppIndicator *self); G_END_DECLS |