aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--applets/Makefile.am2
-rw-r--r--applets/startup-notify/Makefile.am15
-rw-r--r--applets/startup-notify/marshal.list1
-rw-r--r--applets/startup-notify/startup.c177
-rw-r--r--configure.ac14
6 files changed, 151 insertions, 70 deletions
diff --git a/ChangeLog b/ChangeLog
index 30be293..104c575 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2008-02-18 Ross Burton <ross@openedhand.com>
+ * configure.ac:
+ Don't check for libnotify.
+
+ * applets/Makefile.am:
+ Build startup-notify if we have DBus.
+
+ * applets/startup-notify:
+ Don't use libnotify as it doesn't conform to the specification and
+ makes blocking DBus calls. Instead, call it directly.
+
+2008-02-18 Ross Burton <ross@openedhand.com>
+
* applets/clock/clock.c:
Don't set a colour in the code, let the theme style it.
diff --git a/applets/Makefile.am b/applets/Makefile.am
index cbac0e7..aae9972 100644
--- a/applets/Makefile.am
+++ b/applets/Makefile.am
@@ -6,7 +6,7 @@ endif
if HAVE_LIBSN
SUBDIRS += startup
-if HAVE_LIBNOTIFY
+if HAVE_DBUS
SUBDIRS += startup-notify
endif
endif
diff --git a/applets/startup-notify/Makefile.am b/applets/startup-notify/Makefile.am
index 74b7273..550606a 100644
--- a/applets/startup-notify/Makefile.am
+++ b/applets/startup-notify/Makefile.am
@@ -2,13 +2,22 @@ AM_CPPFLAGS=-DPKGDATADIR=\"$(pkgdatadir)\" \
-DGETTEXT_PACKAGE=\"matchbox-panel\"
AM_CFLAGS = -Wall -g $(MATCHBOX_PANEL_CFLAGS) \
-I$(top_srcdir) -I$(top_builddir) -Werror \
- $(SN_CFLAGS) $(LIBNOTIFY_CFLAGS)
+ $(SN_CFLAGS) $(DBUS_CFLAGS)
appletdir = $(pkglibdir)
applet_LTLIBRARIES = libstartup-notify.la
-libstartup_notify_la_SOURCES = startup.c
-libstartup_notify_la_LIBADD = $(SN_LIBS) $(LIBNOTIFY_LIBS)
+libstartup_notify_la_SOURCES = startup.c $(MARSHALS)
+libstartup_notify_la_LIBADD = $(SN_LIBS) $(DBUS_LIBS)
libstartup_notify_la_LDFLAGS = -avoid-version
+MARSHALS = marshal.c marshal.h
+%.c: %.list
+ $(GLIB_GENMARSHAL) --prefix=mb_marshal $^ --body > $@
+%.h: %.list
+ $(GLIB_GENMARSHAL) --prefix=mb_marshal $^ --header > $@
+
+BUILT_SOURCES = $(MARSHALS)
+CLEANFILES = $(BUILT_SOURCES)
+
MAINTAINERCLEANFILES = Makefile.in
diff --git a/applets/startup-notify/marshal.list b/applets/startup-notify/marshal.list
new file mode 100644
index 0000000..6cb7431
--- /dev/null
+++ b/applets/startup-notify/marshal.list
@@ -0,0 +1 @@
+VOID:UINT,UINT
diff --git a/applets/startup-notify/startup.c b/applets/startup-notify/startup.c
index 48158be..cb5aa01 100644
--- a/applets/startup-notify/startup.c
+++ b/applets/startup-notify/startup.c
@@ -1,21 +1,20 @@
/*
- * startup-monitor - A tray app that provides feedback on application startup.
+ * startup-notify: invisible applet which fires a notification when an
+ * application is started.
*
- * Copyright 2004 - 2007, Openedhand Ltd.
- * By Matthew Allum <mallum@o-hand.com>,
- * Stefan Schmidt <stefan@openmoko.org>,
+ * Copyright 2004 - 2008, Openedhand Ltd.
* Ross Burton <ross@openedhand.com>
+ * Portions by Matthew Allum <mallum@o-hand.com>,
+ * Stefan Schmidt <stefan@openmoko.org>.
*
- * Originally based on mb-applet-startup-monitor
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by the Free Software
+ * Foundation; version 2 of the license.
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the license.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
*
*/
@@ -23,6 +22,8 @@
#include <stdlib.h>
#include <time.h>
+#include <dbus/dbus-glib.h>
+
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -33,9 +34,9 @@
#define SN_API_NOT_YET_FROZEN 1
#include <libsn/sn.h>
-#include <libnotify/notify.h>
#include <string.h>
+#include "marshal.h"
#define TIMEOUT 20
@@ -50,7 +51,8 @@ typedef struct {
GdkWindow *root_window;
SnDisplay *sn_display;
GList *launch_list;
- NotifyNotification *notify;
+ DBusGProxy *proxy;
+ guint notify_id;
} StartupApplet;
static GdkFilterReturn filter_func (GdkXEvent *gdk_xevent,
@@ -58,12 +60,46 @@ static GdkFilterReturn filter_func (GdkXEvent *gdk_xevent,
static gboolean timeout (StartupApplet *applet);
+/*
+ * Notify code
+ */
+
+static void
+notify_done (DBusGProxy *proxy, DBusGProxyCall *call, void *user_data)
+{
+ StartupApplet *applet = user_data;
+ GError *error = NULL;
+
+ dbus_g_proxy_end_call (proxy, call, &error, G_TYPE_UINT, &applet->notify_id, G_TYPE_INVALID);
+ if (error) {
+ g_printerr ("Cannot send notification: %s", error->message);
+ g_error_free (error);
+ }
+}
+
+void
+notify_send (StartupApplet *applet, const char *summary)
+{
+ dbus_g_proxy_begin_call (applet->proxy, "Notify",
+ notify_done, applet, NULL,
+ G_TYPE_STRING, "matchbox-panel",
+ G_TYPE_UINT, applet->notify_id,
+ G_TYPE_STRING, NULL, /* icon name */
+ G_TYPE_STRING, summary,
+ G_TYPE_STRING, NULL, /* body */
+ G_TYPE_STRV, NULL, /* actions */
+ dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), g_hash_table_new (NULL, NULL), /* Hints */
+ G_TYPE_INT, -1, /* timeout */
+ G_TYPE_INVALID);
+}
+
/* Destroy applet */
static void
startup_applet_free (StartupApplet *applet)
{
gdk_window_remove_filter (applet->root_window,
(GdkFilterFunc) filter_func, applet);
+ g_object_unref (applet->proxy);
g_slice_free (StartupApplet, applet);
}
@@ -76,26 +112,24 @@ update_notify (StartupApplet *applet)
g_return_if_fail (applet->launch_list != NULL);
item = applet->launch_list->data;
-
+
msg = g_strdup_printf ("Starting %s...", item->name);
-
- if (applet->notify) {
- notify_notification_update (applet->notify, msg, NULL, NULL);
- } else {
- applet->notify = notify_notification_new (msg, NULL, NULL, NULL);
- }
- notify_notification_show (applet->notify, NULL);
-
+
+ notify_send (applet, msg);
+
g_free (msg);
}
static void
hide_notify (StartupApplet *applet)
{
- if (applet->notify) {
- notify_notification_close (applet->notify, NULL);
- g_object_unref (applet->notify);
- applet->notify = NULL;
+ if (applet->notify_id) {
+ dbus_g_proxy_call_no_reply (applet->proxy, "CloseNotification",
+ G_TYPE_UINT, applet->notify_id,
+ G_TYPE_INVALID);
+ /* Unset this here just in case the close signal never arrives. Not that
+ notification-daemon doesn't respect the specification or anything... */
+ applet->notify_id = 0;
}
}
@@ -189,7 +223,7 @@ timeout (StartupApplet *applet)
time_t t;
GList *l;
- if (!applet->notify)
+ if (!applet->notify_id)
return TRUE;
t = time (NULL);
@@ -225,6 +259,46 @@ filter_func (GdkXEvent *gdk_xevent, GdkEvent *event, StartupApplet *applet)
return GDK_FILTER_CONTINUE;
}
+static void
+close_cb (DBusGProxy *proxy, guint id, guint reason, StartupApplet *applet)
+{
+ applet->notify_id = 0;
+}
+
+static gboolean
+init_notify (StartupApplet *applet)
+{
+ DBusGConnection *bus;
+ GError *error = NULL;
+
+ bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+ if (error) {
+ g_printerr ("Cannot get DBus connection: %s\n", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ applet->proxy = dbus_g_proxy_new_for_name (bus,
+ "org.freedesktop.Notifications",
+ "/org/freedesktop/Notifications",
+ "org.freedesktop.Notifications");
+
+ dbus_g_object_register_marshaller(mb_marshal_VOID__UINT_UINT,
+ G_TYPE_NONE,
+ G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID);
+
+ dbus_g_proxy_add_signal (applet->proxy, "NotificationClosed",
+ G_TYPE_UINT, G_TYPE_UINT, G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (applet->proxy, "NotificationClosed",
+ G_CALLBACK (close_cb),
+ applet, NULL);
+
+ dbus_g_connection_unref (bus);
+
+ return TRUE;
+}
+
G_MODULE_EXPORT GtkWidget *
mb_panel_applet_create (const char *id, GtkOrientation orientation)
{
@@ -233,32 +307,31 @@ mb_panel_applet_create (const char *id, GtkOrientation orientation)
Display *xdisplay;
SnMonitorContext *context;
- if (!notify_is_initted ())
- notify_init ("matchbox-panel");
-
applet = g_slice_new0 (StartupApplet);
-
+
widget = gtk_hbox_new (0, FALSE); /* grr */
g_object_weak_ref (G_OBJECT (widget), (GWeakNotify)startup_applet_free, applet);
-
- xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
-
- applet->sn_display = sn_display_new (xdisplay, NULL, NULL);
-
- context = sn_monitor_context_new (applet->sn_display,
- DefaultScreen (xdisplay),
- monitor_event_func,
- applet, NULL);
-
- /* We have to select for property events on at least one root window (but not
- * all as INITIATE messages go to all root windows)
- */
- XSelectInput (xdisplay, DefaultRootWindow (xdisplay), PropertyChangeMask);
-
- applet->root_window = gdk_window_lookup_for_display
- (gdk_x11_lookup_xdisplay (xdisplay), 0);
-
- gdk_window_add_filter (applet->root_window, (GdkFilterFunc)filter_func, applet);
+
+ if (init_notify (applet)) {
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
+
+ applet->sn_display = sn_display_new (xdisplay, NULL, NULL);
+
+ context = sn_monitor_context_new (applet->sn_display,
+ DefaultScreen (xdisplay),
+ monitor_event_func,
+ applet, NULL);
+
+ /* We have to select for property events on at least one root window (but not
+ * all as INITIATE messages go to all root windows)
+ */
+ XSelectInput (xdisplay, DefaultRootWindow (xdisplay), PropertyChangeMask);
+
+ applet->root_window = gdk_window_lookup_for_display
+ (gdk_x11_lookup_xdisplay (xdisplay), 0);
+
+ gdk_window_add_filter (applet->root_window, (GdkFilterFunc)filter_func, applet);
+ }
/* TODO: need to fix the panel to support invisible widgets */
return widget;
diff --git a/configure.ac b/configure.ac
index d04265b..03cc81c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,20 +30,6 @@ fi
AM_CONDITIONAL(HAVE_LIBSN, test x$enable_startup_notification = xyes)
-# libnotify
-AC_ARG_ENABLE(libnotify,
- AC_HELP_STRING([--disable-libnotify], [disable libnotify support]),
- enable_libnotify=$enableval, enable_libnotify=yes )
-
-if test x$enable_libnotify != xno; then
- PKG_CHECK_MODULES(LIBNOTIFY, libnotify, ,
- AC_MSG_ERROR([*** Required libnotify library not installed ***]))
-
- AC_DEFINE(USE_LIBNOTIFY, [1], [Has libnotify Support])
-fi
-AM_CONDITIONAL(HAVE_LIBNOTIFY, test x$enable_libnotify = xyes)
-
-
# DBus
AC_ARG_ENABLE(dbus,
AC_HELP_STRING([--disable-dbus], [disable DBus support]),