aboutsummaryrefslogtreecommitdiff
path: root/src/indicator-notifications.c
diff options
context:
space:
mode:
authorJason Conti <jason.conti@gmail.com>2011-08-29 11:11:43 -0400
committerJason Conti <jason.conti@gmail.com>2011-08-29 11:11:43 -0400
commitcb1da8552b56959f8f1c59a17fd4341f2aee611f (patch)
treeffe7c115e93253976ca04e2cf6743fe0d49c3088 /src/indicator-notifications.c
parent467b817e26d75b156aacdaadc446de1a69b1a3fb (diff)
downloadayatana-indicator-notifications-cb1da8552b56959f8f1c59a17fd4341f2aee611f.tar.gz
ayatana-indicator-notifications-cb1da8552b56959f8f1c59a17fd4341f2aee611f.tar.bz2
ayatana-indicator-notifications-cb1da8552b56959f8f1c59a17fd4341f2aee611f.zip
* Simplified the indicator by removing the dbus service. Still needs:
- Clear button - Message limit * GTK3 is having issues with the multi-line menu items. Adding a bit of a hack to calculate the size of the menu and resize it when an item is added. Still has some problems, but better than before. Will probably cause other issues that will need to be addressed later.
Diffstat (limited to 'src/indicator-notifications.c')
-rw-r--r--src/indicator-notifications.c194
1 files changed, 82 insertions, 112 deletions
diff --git a/src/indicator-notifications.c b/src/indicator-notifications.c
index 237c4d0..3d4dc56 100644
--- a/src/indicator-notifications.c
+++ b/src/indicator-notifications.c
@@ -39,17 +39,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>.
#include <libindicator/indicator-object.h>
#include <libindicator/indicator-service-manager.h>
-/* DBusMenu */
-#if WITH_GTK == 3
-#include <libdbusmenu-gtk3/menu.h>
-#include <libdbusmenu-gtk3/menuitem.h>
-#else
-#include <libdbusmenu-gtk/menu.h>
-#include <libdbusmenu-gtk/menuitem.h>
-#endif
-
-#include "dbus-shared.h"
-#include "settings-shared.h"
+#include "dbus-spy.h"
#define INDICATOR_NOTIFICATIONS_TYPE (indicator_notifications_get_type ())
#define INDICATOR_NOTIFICATIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_NOTIFICATIONS_TYPE, IndicatorNotifications))
@@ -79,13 +69,11 @@ struct _IndicatorNotificationsPrivate {
gboolean have_unread;
- IndicatorServiceManager *sm;
- DbusmenuGtkMenu *menu;
+ GtkMenu *menu;
gchar *accessible_desc;
- GCancellable *service_proxy_cancel;
- GDBusProxy *service_proxy;
+ DBusSpy *spy;
};
#define INDICATOR_NOTIFICATIONS_GET_PRIVATE(o) \
@@ -106,9 +94,14 @@ static GtkMenu *get_menu(IndicatorObject *io);
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 gboolean new_notification_menuitem(DbusmenuMenuitem *new_item, DbusmenuMenuitem *parent, DbusmenuClient *client, gpointer user_data);
-static void receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, GVariant *parameters, gpointer user_data);
-static void service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data);
+
+#if WITH_GTK == 3
+static void calculate_size_cb(GtkWidget *item, gpointer user_data);
+static void resize_menu(GtkWidget *menu);
+#endif
+
+static void message_received_cb(DBusSpy *spy, Notification *note, gpointer user_data);
+static GtkWidget *new_notification_menuitem(Notification *note);
static void style_changed(GtkWidget *widget, GtkStyle *oldstyle, gpointer user_data);
/* Indicator Module Config */
@@ -151,80 +144,91 @@ menu_visible_notify_cb(GtkWidget *menu, G_GNUC_UNUSED GParamSpec *pspec, gpointe
}
}
+#if WITH_GTK == 3
+/* In GTK3 labels can now automatically wrap to fit the size of their parent,
+ * however, it seems to take several tries for GtkMenu to resize properly.
+ *
+ * As a workaround, calculate the preferred size for each of the menu items and
+ * set the menu's size request appropriately.
+ */
static void
-indicator_notifications_init(IndicatorNotifications *self)
+calculate_size_cb(GtkWidget *item, gpointer user_data)
{
- self->priv = INDICATOR_NOTIFICATIONS_GET_PRIVATE(self);
-
- self->priv->service_proxy = NULL;
+ GtkAllocation *alloc = (GtkAllocation *)user_data;
+ gint width;
+ gint height;
- self->priv->sm = NULL;
- self->priv->menu = NULL;
+ gtk_widget_get_preferred_width(item, NULL, &width);
+ gtk_widget_get_preferred_height_for_width(item, width, NULL, &height);
- self->priv->image = NULL;
- self->priv->pixbuf_read = NULL;
- self->priv->pixbuf_unread = NULL;
+ if(alloc->width < width)
+ alloc->width = width;
- self->priv->have_unread = FALSE;
+ alloc->height += height;
+}
- self->priv->accessible_desc = _("Notifications");
+static void
+resize_menu(GtkWidget *menu)
+{
+ GtkAllocation alloc;
+ GtkAllocation child_alloc;
- self->priv->sm = indicator_service_manager_new_version(SERVICE_NAME, SERVICE_VERSION);
+ gtk_widget_get_allocation(menu, &alloc);
- self->priv->menu = dbusmenu_gtkmenu_new(SERVICE_NAME, MENU_OBJ);
+ child_alloc.x = 0;
+ child_alloc.y = 0;
+ child_alloc.width = 1;
+ child_alloc.height = 1;
- g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self);
+ gtk_container_foreach(GTK_CONTAINER(menu), calculate_size_cb, &child_alloc);
+ gtk_widget_set_size_request(menu, child_alloc.width, child_alloc.height);
+ g_debug("RESIZE_MENU: W: %d H: %d -> W: %d H: %d", alloc.width, alloc.height,
+ child_alloc.width, child_alloc.height);
+}
+#endif
- DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(self->priv->menu);
+static void
+message_received_cb(DBusSpy *spy, Notification *note, gpointer user_data)
+{
+ IndicatorNotifications *self = INDICATOR_NOTIFICATIONS(user_data);
- dbusmenu_client_add_type_handler_full(DBUSMENU_CLIENT(client),
- NOTIFICATION_MENUITEM_TYPE,
- new_notification_menuitem,
- self, NULL);
+ /* Discard volume notifications */
+ if(notification_is_volume(note)) return;
- self->priv->service_proxy_cancel = g_cancellable_new();
+ GtkWidget *item = new_notification_menuitem(note);
+ g_object_unref(note);
- g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL,
- SERVICE_NAME,
- SERVICE_OBJ,
- SERVICE_IFACE,
- self->priv->service_proxy_cancel,
- service_proxy_cb,
- self);
+ gtk_menu_shell_append(GTK_MENU_SHELL(self->priv->menu), item);
- return;
+ if(self->priv->pixbuf_unread != NULL) {
+ self->priv->have_unread = TRUE;
+ gtk_image_set_from_pixbuf(self->priv->image, self->priv->pixbuf_unread);
+ }
+#if WITH_GTK == 3
+ resize_menu(GTK_WIDGET(self->priv->menu));
+#endif
}
static void
-service_proxy_cb(GObject *object, GAsyncResult *res, gpointer user_data)
+indicator_notifications_init(IndicatorNotifications *self)
{
- GError *error = NULL;
-
- IndicatorNotifications *self = INDICATOR_NOTIFICATIONS(user_data);
- g_return_if_fail(self != NULL);
-
- GDBusProxy *proxy = g_dbus_proxy_new_for_bus_finish(res, &error);
+ self->priv = INDICATOR_NOTIFICATIONS_GET_PRIVATE(self);
- IndicatorNotificationsPrivate *priv = INDICATOR_NOTIFICATIONS_GET_PRIVATE(self);
+ self->priv->menu = NULL;
- if(priv->service_proxy_cancel != NULL) {
- g_object_unref(priv->service_proxy_cancel);
- priv->service_proxy_cancel = NULL;
- }
+ self->priv->image = NULL;
+ self->priv->pixbuf_read = NULL;
+ self->priv->pixbuf_unread = NULL;
- if(error != NULL) {
- g_warning("Could not grab DBus proxy for %s: %s", SERVICE_NAME, error->message);
- g_error_free(error);
- return;
- }
+ self->priv->have_unread = FALSE;
- priv->service_proxy = proxy;
+ self->priv->accessible_desc = _("Notifications");
- g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
+ self->priv->menu = GTK_MENU(gtk_menu_new());
+ g_signal_connect(self->priv->menu, "notify::visible", G_CALLBACK(menu_visible_notify_cb), self);
- return;
+ self->priv->spy = dbus_spy_new();
+ g_signal_connect(self->priv->spy, DBUS_SPY_SIGNAL_MESSAGE_RECEIVED, G_CALLBACK(message_received_cb), self);
}
static void
@@ -252,16 +256,6 @@ indicator_notifications_dispose(GObject *object)
self->priv->menu = NULL;
}
- if(self->priv->sm != NULL) {
- g_object_unref(G_OBJECT(self->priv->sm));
- self->priv->sm = NULL;
- }
-
- if(self->priv->service_proxy != NULL) {
- g_object_unref(self->priv->service_proxy);
- self->priv->service_proxy = NULL;
- }
-
G_OBJECT_CLASS (indicator_notifications_parent_class)->dispose (object);
return;
}
@@ -275,39 +269,15 @@ indicator_notifications_finalize(GObject *object)
return;
}
-static void
-receive_signal(GDBusProxy *proxy, gchar *sender_name, gchar *signal_name,
- GVariant *parameters, gpointer user_data)
+static GtkWidget *
+new_notification_menuitem(Notification *note)
{
- IndicatorNotifications *self = INDICATOR_NOTIFICATIONS(user_data);
+ gchar *unescaped_timestamp_string = notification_timestamp_for_locale(note);
- g_debug("received signal '%s'", signal_name);
- if(g_strcmp0(signal_name, "MessageAdded") == 0) {
- if(self->priv->pixbuf_unread != NULL) {
- self->priv->have_unread = TRUE;
- gtk_image_set_from_pixbuf(self->priv->image, self->priv->pixbuf_unread);
- }
- }
-
- return;
-}
-
-static gboolean
-new_notification_menuitem(DbusmenuMenuitem *new_item, DbusmenuMenuitem *parent,
- DbusmenuClient *client, gpointer user_data)
-{
- g_return_val_if_fail(DBUSMENU_IS_MENUITEM(new_item), FALSE);
- g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE);
- g_return_val_if_fail(IS_INDICATOR_NOTIFICATIONS(user_data), FALSE);
-
- gchar *app_name = g_markup_escape_text(dbusmenu_menuitem_property_get(new_item,
- NOTIFICATION_MENUITEM_PROP_APP_NAME), -1);
- gchar *summary = g_markup_escape_text(dbusmenu_menuitem_property_get(new_item,
- NOTIFICATION_MENUITEM_PROP_SUMMARY), -1);
- gchar *body = g_markup_escape_text(dbusmenu_menuitem_property_get(new_item,
- NOTIFICATION_MENUITEM_PROP_BODY), -1);
- gchar *timestamp_string = g_markup_escape_text(dbusmenu_menuitem_property_get(new_item,
- NOTIFICATION_MENUITEM_PROP_TIMESTAMP_STRING), -1);
+ gchar *app_name = g_markup_escape_text(notification_get_app_name(note), -1);
+ gchar *summary = g_markup_escape_text(notification_get_summary(note), -1);
+ gchar *body = g_markup_escape_text(notification_get_body(note), -1);
+ gchar *timestamp_string = g_markup_escape_text(unescaped_timestamp_string, -1);
gchar *markup = g_strdup_printf("<b>%s</b>\n%s\n<small><i>%s %s <b>%s</b></i></small>",
summary, body, timestamp_string, _("from"), app_name);
@@ -315,6 +285,7 @@ new_notification_menuitem(DbusmenuMenuitem *new_item, DbusmenuMenuitem *parent,
g_free(app_name);
g_free(summary);
g_free(body);
+ g_free(unescaped_timestamp_string);
g_free(timestamp_string);
#if WITH_GTK == 3
@@ -344,10 +315,9 @@ new_notification_menuitem(DbusmenuMenuitem *new_item, DbusmenuMenuitem *parent,
GtkWidget *item = gtk_menu_item_new();
gtk_container_add(GTK_CONTAINER(item), hbox);
gtk_widget_show(hbox);
+ gtk_widget_show(item);
- dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), new_item, GTK_MENU_ITEM(item), parent);
-
- return TRUE;
+ return item;
}
static void