aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-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