diff options
-rw-r--r-- | src/indicator-notifications.c | 59 |
1 files changed, 53 insertions, 6 deletions
diff --git a/src/indicator-notifications.c b/src/indicator-notifications.c index 4cc006c..628fa5c 100644 --- a/src/indicator-notifications.c +++ b/src/indicator-notifications.c @@ -59,23 +59,32 @@ struct _IndicatorNotifications { }; struct _IndicatorNotificationsPrivate { - GtkImage *image; + GtkImage *image; GdkPixbuf *pixbuf_read; GdkPixbuf *pixbuf_unread; - gboolean have_unread; + GList *visible_items; + GList *hidden_items; - GtkMenu *menu; + gboolean have_unread; - gchar *accessible_desc; + GtkMenu *menu; - DBusSpy *spy; + gchar *accessible_desc; + + DBusSpy *spy; }; #define INDICATOR_NOTIFICATIONS_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), INDICATOR_NOTIFICATIONS_TYPE, IndicatorNotificationsPrivate)) +/** + * The maximum number of items to show in the indicator at once. + * FIXME: Store this value in gsettings + */ +#define INDICATOR_MAX_ITEMS 5 + #define INDICATOR_ICON_SIZE 22 #define INDICATOR_ICON_READ "indicator-notification-read" #define INDICATOR_ICON_UNREAD "indicator-notification-unread" @@ -92,6 +101,8 @@ static const gchar *get_accessible_desc(IndicatorObject *io); static GdkPixbuf *load_icon(const gchar *name, gint size); static void menu_visible_notify_cb(GtkWidget *menu, GParamSpec *pspec, gpointer user_data); +static void insert_menuitem(IndicatorNotifications *self, GtkWidget *item); + static void calculate_size_cb(GtkWidget *item, gpointer user_data); static void resize_menu(GtkWidget *menu); @@ -181,6 +192,29 @@ resize_menu(GtkWidget *menu) } static void +insert_menuitem(IndicatorNotifications *self, GtkWidget *item) +{ + GList *last_item; + GtkWidget *last_widget; + + /* List holds a ref to the menuitem */ + self->priv->visible_items = g_list_prepend(self->priv->visible_items, g_object_ref(item)); + gtk_menu_shell_prepend(GTK_MENU_SHELL(self->priv->menu), item); + + /* Move items that overflow to the hidden list */ + while(g_list_length(self->priv->visible_items) > INDICATOR_MAX_ITEMS) { + last_item = g_list_last(self->priv->visible_items); + last_widget = GTK_WIDGET(last_item->data); + /* Steal the ref from the visible list */ + self->priv->visible_items = g_list_delete_link(self->priv->visible_items, last_item); + self->priv->hidden_items = g_list_prepend(self->priv->hidden_items, last_widget); + gtk_container_remove(GTK_CONTAINER(self->priv->menu), last_widget); + last_item = NULL; + last_widget = NULL; + } +} + +static void message_received_cb(DBusSpy *spy, Notification *note, gpointer user_data) { IndicatorNotifications *self = INDICATOR_NOTIFICATIONS(user_data); @@ -192,7 +226,7 @@ message_received_cb(DBusSpy *spy, Notification *note, gpointer user_data) GtkWidget *item = new_notification_menuitem(note); g_object_unref(note); - gtk_menu_shell_prepend(GTK_MENU_SHELL(self->priv->menu), item); + insert_menuitem(self, item); if(self->priv->pixbuf_unread != NULL) { self->priv->have_unread = TRUE; @@ -216,6 +250,9 @@ indicator_notifications_init(IndicatorNotifications *self) self->priv->accessible_desc = _("Notifications"); + self->priv->visible_items = NULL; + self->priv->hidden_items = NULL; + self->priv->menu = GTK_MENU(gtk_menu_new()); g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self); @@ -243,6 +280,16 @@ indicator_notifications_dispose(GObject *object) self->priv->pixbuf_unread = NULL; } + if(self->priv->visible_items != NULL) { + g_list_free_full(self->priv->visible_items, g_object_unref); + self->priv->visible_items = NULL; + } + + if(self->priv->hidden_items != NULL) { + g_list_free_full(self->priv->hidden_items, g_object_unref); + self->priv->hidden_items = NULL; + } + if(self->priv->menu != NULL) { g_object_unref(G_OBJECT(self->priv->menu)); self->priv->menu = NULL; |