diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libappindicator/app-indicator.c | 78 | ||||
-rw-r--r-- | src/libappindicator/app-indicator.h | 1 |
2 files changed, 71 insertions, 8 deletions
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 |