aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am47
-rw-r--r--src/dbus-shared.h32
-rw-r--r--src/dbus-spy.c27
-rw-r--r--src/indicator-notifications.c194
-rw-r--r--src/notifications-interface.c210
-rw-r--r--src/notifications-interface.h56
-rw-r--r--src/notifications-service.c290
-rw-r--r--src/notifications-service.xml11
-rw-r--r--src/settings-shared.h25
9 files changed, 112 insertions, 780 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 2b92fc7..803402a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,32 +1,14 @@
AM_CPPFLAGS = -DICONS_DIR='"$(INDICATORICONSDIR)"' \
-DWITH_GTK='$(GTK_VERSION)'
-libexec_PROGRAMS = indicator-notifications-service
-
-indicator_notifications_service_SOURCES = \
- dbus-spy.c \
- dbus-spy.h \
- notification.c \
- notification.h \
- notifications-interface.c \
- notifications-interface.h \
- gen-notifications-service.xml.c \
- notifications-service.c \
- dbus-shared.h \
- settings-shared.h
-indicator_notifications_service_CFLAGS = \
- -Wall \
- $(SERVICE_CFLAGS) \
- -DG_LOG_DOMAIN=\"Indicator-Notifications\"
-indicator_notifications_service_LDADD = \
- $(SERVICE_LIBS)
-
notificationslibdir = $(INDICATORDIR)
notificationslib_LTLIBRARIES = libnotifications.la
libnotifications_la_SOURCES = \
- dbus-shared.h \
- settings-shared.h \
- indicator-notifications.c
+ dbus-spy.c \
+ dbus-spy.h \
+ indicator-notifications.c \
+ notification.c \
+ notification.h
libnotifications_la_CFLAGS = \
$(INDICATOR_CFLAGS) \
-Wall \
@@ -37,22 +19,3 @@ libnotifications_la_LDFLAGS = \
-module \
-avoid-version
-gen-notifications-service.xml.c: notifications-service.xml
- @echo "Building $@ from $<"
- @echo "const char * _notifications_service = " > $@
- @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@
- @echo ";" >> $@
-
-gen-notifications-service.xml.h: notifications-service.xml
- @echo "Building $@ from $<"
- @echo "extern const char * _notifications_service;" > $@
-
-BUILT_SOURCES = \
- gen-notifications-service.xml.c \
- gen-notifications-service.xml.h
-
-CLEANFILES = \
- $(BUILT_SOURCES)
-
-EXTRA_DIST = \
- notifications-service.xml
diff --git a/src/dbus-shared.h b/src/dbus-shared.h
deleted file mode 100644
index da93e73..0000000
--- a/src/dbus-shared.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-An indicator to display recent notifications.
-
-Adapted from: indicator-datetime/src/dbus-shared.c by
- Ted Gould <ted@canonical.com>
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#define SERVICE_NAME "com.launchpad.RecentNotifications.indicator"
-#define SERVICE_IFACE "com.launchpad.RecentNotifications.indicator.service"
-#define SERVICE_OBJ "/com/launchpad/RecentNotifications/indicator/service"
-#define SERVICE_VERSION 1
-
-#define MENU_OBJ "/com/launchpad/RecentNotifications/indicator/menu"
-
-#define NOTIFICATION_MENUITEM_TYPE "notification-menuitem"
-#define NOTIFICATION_MENUITEM_PROP_APP_NAME "notification-menuitem-prop-app-name"
-#define NOTIFICATION_MENUITEM_PROP_APP_ICON "notification-menuitem-prop-app-icon"
-#define NOTIFICATION_MENUITEM_PROP_SUMMARY "notification-menuitem-prop-summary"
-#define NOTIFICATION_MENUITEM_PROP_BODY "notification-menuitem-prop-body"
-#define NOTIFICATION_MENUITEM_PROP_TIMESTAMP_STRING "notification-menuitem-prop-timestamp-string"
diff --git a/src/dbus-spy.c b/src/dbus-spy.c
index 4fe5141..e63a5ee 100644
--- a/src/dbus-spy.c
+++ b/src/dbus-spy.c
@@ -9,6 +9,13 @@ enum {
LAST_SIGNAL
};
+typedef struct _IdleMessage IdleMessage;
+struct _IdleMessage
+{
+ DBusSpy *spy;
+ Notification *note;
+};
+
static guint signals[LAST_SIGNAL];
static void dbus_spy_class_init(DBusSpyClass *klass);
@@ -22,6 +29,8 @@ static void bus_get_cb(GObject *source_object, GAsyncResult *res, gpointer user_
static GDBusMessage *message_filter(GDBusConnection *connection, GDBusMessage *message,
gboolean incoming, gpointer user_data);
+static gboolean idle_message_emit(gpointer user_data);
+
#define MATCH_STRING "type='method_call',interface='org.freedesktop.Notifications',member='Notify'"
G_DEFINE_TYPE (DBusSpy, dbus_spy, G_TYPE_OBJECT);
@@ -115,8 +124,10 @@ message_filter(GDBusConnection *connection, GDBusMessage *message, gboolean inco
{
DBusSpy *spy = DBUS_SPY(user_data);
Notification *note = notification_new_from_dbus_message(message);
- g_signal_emit(spy, signals[MESSAGE_RECEIVED], 0, note);
- g_object_unref(note);
+ IdleMessage *im = g_new0(IdleMessage, 1);
+ im->spy = spy;
+ im->note = note;
+ g_idle_add(idle_message_emit, im);
g_object_unref(message);
message = NULL;
}
@@ -124,6 +135,18 @@ message_filter(GDBusConnection *connection, GDBusMessage *message, gboolean inco
return message;
}
+static gboolean
+idle_message_emit(gpointer user_data)
+{
+ IdleMessage *message = (IdleMessage *)user_data;
+
+ g_signal_emit(message->spy, signals[MESSAGE_RECEIVED], 0, message->note);
+
+ g_free(message);
+
+ return FALSE;
+}
+
static void
dbus_spy_init(DBusSpy *self)
{
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
diff --git a/src/notifications-interface.c b/src/notifications-interface.c
deleted file mode 100644
index d130049..0000000
--- a/src/notifications-interface.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-An indicator to display recent notifications.
-
-Adapted from: indicator-notifications/src/notifications-service.c by
- Ted Gould <ted@canonical.com>
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <gio/gio.h>
-
-#include "notifications-interface.h"
-#include "gen-notifications-service.xml.h"
-#include "dbus-shared.h"
-
-/**
- NotificationsInterfacePrivate:
- @dbus_registration: The handle for this object being registered
- on dbus.
-
- Structure to define the memory for the private area
- of the notifications interface instance.
-*/
-struct _NotificationsInterfacePrivate {
- GDBusConnection *bus;
- GCancellable *bus_cancel;
- guint dbus_registration;
-};
-
-#define NOTIFICATIONS_INTERFACE_GET_PRIVATE(o) (NOTIFICATIONS_INTERFACE(o)->priv)
-
-/* GDBus Stuff */
-static GDBusNodeInfo *node_info = NULL;
-static GDBusInterfaceInfo *interface_info = NULL;
-
-static void notifications_interface_class_init(NotificationsInterfaceClass *klass);
-static void notifications_interface_init(NotificationsInterface *self);
-static void notifications_interface_dispose(GObject *object);
-static void notifications_interface_finalize(GObject *object);
-static void bus_get_cb(GObject *object, GAsyncResult *res, gpointer user_data);
-
-G_DEFINE_TYPE (NotificationsInterface, notifications_interface, G_TYPE_OBJECT);
-
-static void
-notifications_interface_class_init(NotificationsInterfaceClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- g_type_class_add_private(klass, sizeof(NotificationsInterfacePrivate));
-
- object_class->dispose = notifications_interface_dispose;
- object_class->finalize = notifications_interface_finalize;
-
- /* Setting up the DBus interfaces */
- if(node_info == NULL) {
- GError * error = NULL;
-
- node_info = g_dbus_node_info_new_for_xml(_notifications_service, &error);
- if(error != NULL) {
- g_error("Unable to parse Notifications Service Interface description: %s", error->message);
- g_error_free(error);
- }
- }
-
- if(interface_info == NULL) {
- interface_info = g_dbus_node_info_lookup_interface(node_info, SERVICE_IFACE);
-
- if(interface_info == NULL) {
- g_error("Unable to find interface '" SERVICE_IFACE "'");
- }
- }
-
- return;
-}
-
-static void
-notifications_interface_init(NotificationsInterface *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NOTIFICATIONS_INTERFACE_TYPE, NotificationsInterfacePrivate);
-
- self->priv->bus = NULL;
- self->priv->bus_cancel = NULL;
- self->priv->dbus_registration = 0;
-
- self->priv->bus_cancel = g_cancellable_new();
- g_bus_get(G_BUS_TYPE_SESSION,
- self->priv->bus_cancel,
- bus_get_cb,
- self);
-
- return;
-}
-
-static void
-bus_get_cb(GObject *object, GAsyncResult *res, gpointer user_data)
-{
- GError *error = NULL;
- GDBusConnection *connection = g_bus_get_finish(res, &error);
-
- if(error != NULL) {
- g_error("OMG! Unable to get a connection to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- NotificationsInterfacePrivate *priv = NOTIFICATIONS_INTERFACE_GET_PRIVATE(user_data);
-
- g_warn_if_fail(priv->bus == NULL);
- priv->bus = connection;
-
- if(priv->bus_cancel != NULL) {
- g_object_unref(priv->bus_cancel);
- priv->bus_cancel = NULL;
- }
-
- /* Now register our object on our new connection */
- priv->dbus_registration = g_dbus_connection_register_object(priv->bus,
- SERVICE_OBJ,
- interface_info,
- NULL,
- user_data,
- NULL,
- &error);
-
- if(error != NULL) {
- g_error("Unable to register the object to DBus: %s", error->message);
- g_error_free(error);
- return;
- }
-
- return;
-}
-
-static void
-notifications_interface_dispose(GObject *object)
-{
- NotificationsInterfacePrivate *priv = NOTIFICATIONS_INTERFACE_GET_PRIVATE(object);
-
- if(priv->dbus_registration != 0) {
- g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration);
- /* Don't care if it fails, there's nothing we can do */
- priv->dbus_registration = 0;
- }
-
- if(priv->bus != NULL) {
- g_object_unref(priv->bus);
- priv->bus = NULL;
- }
-
- if(priv->bus_cancel != NULL) {
- g_cancellable_cancel(priv->bus_cancel);
- g_object_unref(priv->bus_cancel);
- priv->bus_cancel = NULL;
- }
-
- G_OBJECT_CLASS (notifications_interface_parent_class)->dispose (object);
- return;
-}
-
-static void
-notifications_interface_finalize(GObject *object)
-{
- G_OBJECT_CLASS (notifications_interface_parent_class)->finalize (object);
- return;
-}
-
-NotificationsInterface *
-notifications_interface_new()
-{
- return NOTIFICATIONS_INTERFACE(g_object_new(NOTIFICATIONS_INTERFACE_TYPE, NULL));
-}
-
-void
-notifications_interface_message_added(NotificationsInterface *self)
-{
- g_return_if_fail(IS_NOTIFICATIONS_INTERFACE(self));
-
- NotificationsInterfacePrivate *priv = NOTIFICATIONS_INTERFACE_GET_PRIVATE(self);
- GError *error = NULL;
-
- g_dbus_connection_emit_signal(priv->bus,
- NULL,
- SERVICE_OBJ,
- SERVICE_IFACE,
- "MessageAdded",
- NULL,
- &error);
-
- if(error != NULL) {
- g_error("Unable to send MessageAdded signal: %s", error->message);
- g_error_free(error);
- return;
- }
-
- return;
-}
diff --git a/src/notifications-interface.h b/src/notifications-interface.h
deleted file mode 100644
index 1af5824..0000000
--- a/src/notifications-interface.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
-An indicator to display recent notifications.
-
-Adapted from: indicator-notifications/src/notifications-interface.c by
- Ted Gould <ted@canonical.com>
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __NOTIFICATIONS_INTERFACE_H__
-#define __NOTIFICATIONS_INTERFACE_H__
-
-#include <glib.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define NOTIFICATIONS_INTERFACE_TYPE (notifications_interface_get_type ())
-#define NOTIFICATIONS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NOTIFICATIONS_INTERFACE_TYPE, NotificationsInterface))
-#define NOTIFICATIONS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NOTIFICATIONS_INTERFACE_TYPE, NotificationsInterfaceClass))
-#define IS_NOTIFICATIONS_INTERFACE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NOTIFICATIONS_INTERFACE_TYPE))
-#define IS_NOTIFICATIONS_INTERFACE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NOTIFICATIONS_INTERFACE_TYPE))
-#define NOTIFICATIONS_INTERFACE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NOTIFICATIONS_INTERFACE_TYPE, NotificationsInterfaceClass))
-
-typedef struct _NotificationsInterface NotificationsInterface;
-typedef struct _NotificationsInterfacePrivate NotificationsInterfacePrivate;
-typedef struct _NotificationsInterfaceClass NotificationsInterfaceClass;
-
-struct _NotificationsInterfaceClass {
- GObjectClass parent_class;
-
- void (*message_added) (void);
-};
-
-struct _NotificationsInterface {
- GObject parent;
- NotificationsInterfacePrivate *priv;
-};
-
-GType notifications_interface_get_type(void);
-NotificationsInterface *notifications_interface_new();
-void notifications_interface_message_added(NotificationsInterface *self);
-
-G_END_DECLS
-
-#endif
diff --git a/src/notifications-service.c b/src/notifications-service.c
deleted file mode 100644
index d3c7da2..0000000
--- a/src/notifications-service.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
-An indicator to display recent notifications.
-
-Adapted from: indicator-datetime/src/datetime-service.c by
- Ted Gould <ted@canonical.com>
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-#include <libindicator/indicator-service.h>
-#include <locale.h>
-#include <stdio.h>
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <gio/gio.h>
-
-#if WITH_GTK == 3
-#include <libdbusmenu-gtk3/menuitem.h>
-#else
-#include <libdbusmenu-gtk/menuitem.h>
-#endif
-
-#include <libdbusmenu-glib/server.h>
-#include <libdbusmenu-glib/client.h>
-#include <libdbusmenu-glib/menuitem.h>
-
-#include "dbus-shared.h"
-#include "dbus-spy.h"
-#include "notifications-interface.h"
-#include "settings-shared.h"
-
-static IndicatorService *service = NULL;
-static GMainLoop *mainloop = NULL;
-static DbusmenuServer *server = NULL;
-static DbusmenuMenuitem *root = NULL;
-static DBusSpy *spy = NULL;
-static NotificationsInterface *dbus = NULL;
-
-/* Global Items */
-static DbusmenuMenuitem *clear_item = NULL;
-static DbusmenuMenuitem *empty_item = NULL;
-static GQueue *notification_items = NULL;
-static guint notification_limit = 5;
-
-/* Logging */
-#define LOG_FILE_NAME "indicator-notifications-service.log"
-static FILE *log_file = NULL;
-
-static gboolean add_notification_item(gpointer);
-static gboolean clear_notification_items(gpointer);
-static void build_menus(DbusmenuMenuitem *);
-static void clear_notifications_cb(DbusmenuMenuitem *, guint, gpointer);
-static void log_cb(const gchar *, GLogLevelFlags, const gchar *, gpointer);
-static void log_init();
-static void message_received_cb(DBusSpy *, Notification *, gpointer);
-static void service_shutdown_cb(IndicatorService *, gpointer);
-
-static gboolean
-add_notification_item(gpointer user_data)
-{
- Notification *note = NOTIFICATION(user_data);
- DbusmenuMenuitem *item;
-
- guint length = g_queue_get_length(notification_items);
-
- /* Remove the empty item from the menu */
- if(length == 0) {
- dbusmenu_menuitem_child_delete(root, empty_item);
- }
-
- gchar *timestamp_string = notification_timestamp_for_locale(note);
-
- item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TYPE, NOTIFICATION_MENUITEM_TYPE);
- dbusmenu_menuitem_property_set(item, NOTIFICATION_MENUITEM_PROP_APP_NAME, notification_get_app_name(note));
- dbusmenu_menuitem_property_set(item, NOTIFICATION_MENUITEM_PROP_SUMMARY, notification_get_summary(note));
- dbusmenu_menuitem_property_set(item, NOTIFICATION_MENUITEM_PROP_BODY, notification_get_body(note));
- dbusmenu_menuitem_property_set(item, NOTIFICATION_MENUITEM_PROP_TIMESTAMP_STRING, timestamp_string);
- dbusmenu_menuitem_child_prepend(root, item);
- g_queue_push_head(notification_items, item);
- length++;
-
- g_debug("Adding message from %s (Queue length: %d)", notification_get_app_name(note),
- length);
-
- if(length > notification_limit) {
- item = DBUSMENU_MENUITEM(g_queue_pop_tail(notification_items));
- dbusmenu_menuitem_child_delete(root, item);
- g_object_unref(item);
- item = NULL;
- }
-
- /* Notify the indicator that a new message has been added */
- notifications_interface_message_added(dbus);
-
- g_free(timestamp_string);
- g_object_unref(note);
-
- return FALSE;
-}
-
-static gboolean
-clear_notification_items(gpointer user_data)
-{
- DbusmenuMenuitem *item;
-
- while(!g_queue_is_empty(notification_items)) {
- item = DBUSMENU_MENUITEM(g_queue_pop_tail(notification_items));
- dbusmenu_menuitem_child_delete(root, item);
- g_object_unref(item);
- }
-
- item = NULL;
-
- /* Add the empty item back, if it isn't already there */
- if(dbusmenu_menuitem_child_find(root, dbusmenu_menuitem_get_id(empty_item)) == NULL) {
- dbusmenu_menuitem_child_prepend(root, empty_item);
- }
-
- return FALSE;
-}
-
-static void
-build_menus(DbusmenuMenuitem *root)
-{
- g_debug("Building Menus.");
-
- if(empty_item == NULL) {
- empty_item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(empty_item, DBUSMENU_MENUITEM_PROP_LABEL, _("There are 0 notifications."));
- dbusmenu_menuitem_child_append(root, empty_item);
- }
-
- if(clear_item == NULL) {
- DbusmenuMenuitem *item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(item, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
- dbusmenu_menuitem_child_append(root, item);
-
- clear_item = dbusmenu_menuitem_new();
- dbusmenu_menuitem_property_set(clear_item, DBUSMENU_MENUITEM_PROP_LABEL, _("Clear"));
- dbusmenu_menuitem_child_append(root, clear_item);
-
- g_signal_connect(G_OBJECT(clear_item), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
- G_CALLBACK(clear_notifications_cb), NULL);
- }
-
- return;
-}
-
-static void
-clear_notifications_cb(DbusmenuMenuitem *item, guint timestamp, gpointer user_data)
-{
- g_idle_add(clear_notification_items, NULL);
-}
-
-/* from lightdm */
-static void
-log_cb(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer user_data)
-{
- if(log_file) {
- const gchar *prefix;
-
- switch(level & G_LOG_LEVEL_MASK) {
- case G_LOG_LEVEL_ERROR:
- prefix = "ERROR:";
- break;
- case G_LOG_LEVEL_CRITICAL:
- prefix = "CRITICAL:";
- break;
- case G_LOG_LEVEL_WARNING:
- prefix = "WARNING:";
- break;
- case G_LOG_LEVEL_MESSAGE:
- prefix = "MESSAGE:";
- break;
- case G_LOG_LEVEL_INFO:
- prefix = "INFO:";
- break;
- case G_LOG_LEVEL_DEBUG:
- prefix = "DEBUG:";
- break;
- default:
- prefix = "LOG:";
- break;
- }
-
- fprintf(log_file, "%s %s\n", prefix, message);
- fflush(log_file);
- }
-
- g_log_default_handler(domain, level, message, user_data);
-}
-
-/* from lightdm */
-static void
-log_init()
-{
- gchar *path;
-
- g_mkdir_with_parents(g_get_user_cache_dir(), 0755);
- path = g_build_filename(g_get_user_cache_dir(), LOG_FILE_NAME, NULL);
-
- log_file = fopen(path, "w");
- g_log_set_default_handler(log_cb, NULL);
-
- g_debug("Logging to %s", path);
- g_free(path);
-}
-
-static void
-message_received_cb(DBusSpy *spy, Notification *note, gpointer user_data)
-{
- /* Discard volume notifications */
- if(notification_is_volume(note)) return;
-
- g_object_ref(note);
- g_idle_add(add_notification_item, note);
-}
-
-/* Responds to the service object saying it's time to shutdown.
- It stops the mainloop. */
-static void
-service_shutdown_cb(IndicatorService *service, gpointer user_data)
-{
- g_warning("Shutting down service!");
- g_main_loop_quit(mainloop);
- return;
-}
-
-/* Function to build everything up. Entry point from asm. */
-int
-main(int argc, char **argv)
-{
- g_type_init();
-
- /* Logging */
- log_init();
-
- /* Acknowledging the service init and setting up the interface */
- service = indicator_service_new_version(SERVICE_NAME, SERVICE_VERSION);
- g_signal_connect(service, INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown_cb), NULL);
-
- /* Setting up i18n and gettext. Apparently, we need
- all of these. */
- setlocale(LC_ALL, "");
- bindtextdomain(GETTEXT_PACKAGE, GNOMELOCALEDIR);
- textdomain(GETTEXT_PACKAGE);
-
- /* Building the base menu */
- server = dbusmenu_server_new(MENU_OBJ);
- root = dbusmenu_menuitem_new();
- dbusmenu_server_set_root(server, root);
-
- build_menus(root);
-
- /* Create the notification queue */
- notification_items = g_queue_new();
-
- /* Set up the notification spy */
- spy = dbus_spy_new();
- g_signal_connect(spy, DBUS_SPY_SIGNAL_MESSAGE_RECEIVED, G_CALLBACK(message_received_cb), NULL);
-
- /* Setup the dbus interface */
- dbus = notifications_interface_new();
-
- mainloop = g_main_loop_new(NULL, FALSE);
- g_main_loop_run(mainloop);
-
- g_object_unref(G_OBJECT(dbus));
- g_object_unref(G_OBJECT(spy));
- g_object_unref(G_OBJECT(service));
- g_object_unref(G_OBJECT(server));
- g_object_unref(G_OBJECT(root));
-
- fclose(log_file);
-
- return 0;
-}
diff --git a/src/notifications-service.xml b/src/notifications-service.xml
deleted file mode 100644
index 36edd68..0000000
--- a/src/notifications-service.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<node name="/">
- <interface name="com.launchpad.RecentNotifications.indicator.service">
-
-<!-- Methods -->
-
-<!-- Signals -->
- <signal name="MessageAdded" />
-
- </interface>
-</node>
diff --git a/src/settings-shared.h b/src/settings-shared.h
deleted file mode 100644
index 3297ad2..0000000
--- a/src/settings-shared.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
-An indicator to display recent notifications.
-
-Adapted from: indicator-datetime/src/settings-shared.c by
- Ted Gould <ted@canonical.com>
-
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __NOTIFICATIONS_SETTINGS_SHARED_H__
-#define __NOTIFICATIONS_SETTINGS_SHARED_H__
-
-#define SETTINGS_INTERFACE "com.launchpad.RecentNotifications.indicator"
-
-#endif