aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--applets/Makefile.am2
-rw-r--r--applets/startup/Makefile.am17
-rw-r--r--applets/startup/data/Makefile.am11
-rw-r--r--applets/startup/data/hourglass-0.pngbin0 -> 996 bytes
-rw-r--r--applets/startup/data/hourglass-1.pngbin0 -> 1147 bytes
-rw-r--r--applets/startup/data/hourglass-2.pngbin0 -> 1125 bytes
-rw-r--r--applets/startup/data/hourglass-3.pngbin0 -> 1118 bytes
-rw-r--r--applets/startup/data/hourglass-4.pngbin0 -> 1024 bytes
-rw-r--r--applets/startup/data/hourglass-5.pngbin0 -> 1456 bytes
-rw-r--r--applets/startup/data/hourglass-6.pngbin0 -> 1131 bytes
-rw-r--r--applets/startup/data/hourglass-7.pngbin0 -> 1372 bytes
-rw-r--r--applets/startup/startup.c250
-rw-r--r--configure.ac5
14 files changed, 295 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 0e6e6ec..780e89d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-06-14 Jorn Baayen <jorn@openedhand.com>
+
+ * applets/Makefile.am:
+ * applets/startup/Makefile.am:
+ * applets/startup/data/Makefile.am:
+ * applets/startup/startup.c:
+ * configure.ac:
+
+ Added startup notification applet. Ported from mb-panel1 by
+ Stefan Schmidt <stefan@datenfreihafen.org>.
+
2007-06-12 Jorn Baayen <jorn@openedhand.com>
* matchbox-panel/mb-panel-scaling-image.c:
diff --git a/applets/Makefile.am b/applets/Makefile.am
index 35c2edc..077735c 100644
--- a/applets/Makefile.am
+++ b/applets/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = clock launcher systray showdesktop windowselector
+SUBDIRS = clock launcher startup systray showdesktop windowselector
if HAVE_LIBAPM
SUBDIRS += battery
diff --git a/applets/startup/Makefile.am b/applets/startup/Makefile.am
new file mode 100644
index 0000000..86b068a
--- /dev/null
+++ b/applets/startup/Makefile.am
@@ -0,0 +1,17 @@
+SUBDIRS = data
+
+AM_CPPFLAGS=-DPKGDATADIR=\"$(pkgdatadir)\" \
+ -DGETTEXT_PACKAGE=\"matchbox-panel\" \
+ -DDATADIR=\"$(pkgdatadir)/startup/\"
+AM_CFLAGS = -Wall -g $(MATCHBOX_PANEL_CFLAGS) \
+ -I$(top_srcdir) -I$(top_builddir) -Werror \
+ $(SN_CFLAGS)
+
+appletdir = $(pkglibdir)
+applet_LTLIBRARIES = libstartup.la
+
+libstartup_la_SOURCES = startup.c
+libstartup_la_LIBADD = $(SN_LIBS)
+libstartup_la_LDFLAGS = -avoid-version
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/applets/startup/data/Makefile.am b/applets/startup/data/Makefile.am
new file mode 100644
index 0000000..f9b124b
--- /dev/null
+++ b/applets/startup/data/Makefile.am
@@ -0,0 +1,11 @@
+imagedir = $(pkgdatadir)/startup
+image_DATA = hourglass-0.png \
+ hourglass-1.png \
+ hourglass-2.png \
+ hourglass-3.png \
+ hourglass-4.png \
+ hourglass-5.png \
+ hourglass-6.png \
+ hourglass-7.png
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/applets/startup/data/hourglass-0.png b/applets/startup/data/hourglass-0.png
new file mode 100644
index 0000000..7493688
--- /dev/null
+++ b/applets/startup/data/hourglass-0.png
Binary files differ
diff --git a/applets/startup/data/hourglass-1.png b/applets/startup/data/hourglass-1.png
new file mode 100644
index 0000000..d195085
--- /dev/null
+++ b/applets/startup/data/hourglass-1.png
Binary files differ
diff --git a/applets/startup/data/hourglass-2.png b/applets/startup/data/hourglass-2.png
new file mode 100644
index 0000000..2f1e7bc
--- /dev/null
+++ b/applets/startup/data/hourglass-2.png
Binary files differ
diff --git a/applets/startup/data/hourglass-3.png b/applets/startup/data/hourglass-3.png
new file mode 100644
index 0000000..712392d
--- /dev/null
+++ b/applets/startup/data/hourglass-3.png
Binary files differ
diff --git a/applets/startup/data/hourglass-4.png b/applets/startup/data/hourglass-4.png
new file mode 100644
index 0000000..b11c1b7
--- /dev/null
+++ b/applets/startup/data/hourglass-4.png
Binary files differ
diff --git a/applets/startup/data/hourglass-5.png b/applets/startup/data/hourglass-5.png
new file mode 100644
index 0000000..13020d6
--- /dev/null
+++ b/applets/startup/data/hourglass-5.png
Binary files differ
diff --git a/applets/startup/data/hourglass-6.png b/applets/startup/data/hourglass-6.png
new file mode 100644
index 0000000..50a2db3
--- /dev/null
+++ b/applets/startup/data/hourglass-6.png
Binary files differ
diff --git a/applets/startup/data/hourglass-7.png b/applets/startup/data/hourglass-7.png
new file mode 100644
index 0000000..e345b2c
--- /dev/null
+++ b/applets/startup/data/hourglass-7.png
Binary files differ
diff --git a/applets/startup/startup.c b/applets/startup/startup.c
new file mode 100644
index 0000000..dd8f624
--- /dev/null
+++ b/applets/startup/startup.c
@@ -0,0 +1,250 @@
+/*
+ * startup-monitor - A tray app that provides feedback
+ * on application startup.
+ *
+ * Copyright 2004 - 2007, Openedhand Ltd.
+ * By Matthew Allum <mallum@o-hand.com>,
+ * Stefan Schmidt <stefan@openmoko.org>
+ *
+ * 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 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#include <glib.h>
+#include <gdk/gdkx.h>
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+#define SN_API_NOT_YET_FROZEN 1
+#include <libsn/sn.h>
+
+#include <string.h>
+#include <matchbox-panel/mb-panel-scaling-image.h>
+
+#define TIMEOUT 20
+#define HOURGLASS_PIXMAPS 8
+
+typedef struct LaunchItem {
+ char *id;
+ time_t when;
+ guint timeout_id;
+} LaunchItem;
+
+typedef struct {
+ MBPanelScalingImage *image;
+ GdkWindow *root_window;
+ SnDisplay *sn_display;
+ GList *launch_list;
+ gboolean hourglass_shown;
+ int hourglass_cur_frame_n;
+} StartupApplet;
+
+static GdkFilterReturn filter_func(GdkXEvent *gdk_xevent,
+ GdkEvent *event, StartupApplet *applet);
+
+static gboolean timeout(StartupApplet *applet);
+
+/* Destroy applet */
+static void startup_applet_free(StartupApplet *applet)
+{
+ gdk_window_remove_filter(applet->root_window,
+ (GdkFilterFunc) filter_func, applet);
+ g_slice_free(StartupApplet, applet);
+}
+
+static void show_hourglass(StartupApplet *applet)
+{
+ gtk_widget_show(GTK_WIDGET(applet->image));
+ applet->hourglass_shown = TRUE;
+}
+
+static void hide_hourglass(StartupApplet *applet)
+{
+ gtk_widget_hide(GTK_WIDGET(applet->image));
+ applet->hourglass_shown = FALSE;
+}
+
+static void monitor_event_func(SnMonitorEvent *event, void *user_data)
+{
+ SnStartupSequence *sequence;
+ const char *id;
+ time_t t;
+ StartupApplet *applet = (StartupApplet *) user_data;
+
+ sequence = sn_monitor_event_get_startup_sequence(event);
+ id = sn_startup_sequence_get_id(sequence);
+
+ switch (sn_monitor_event_get_type(event)) {
+ case SN_MONITOR_EVENT_INITIATED:
+ {
+ /* Reset counter */
+ applet->hourglass_cur_frame_n = 0;
+
+ LaunchItem *item;
+ item = malloc(sizeof(LaunchItem));
+
+ /* Fillup list item with current launchee informations */
+ item->id = g_strdup(id);
+ t = time(NULL);
+ item->when = t + TIMEOUT;
+
+ /* Set up a timeout that will be called every 0.5 seconds */
+ item->timeout_id = g_timeout_add(500,
+ (GSourceFunc) timeout, applet);
+
+ /* Add a new launch at the end of list */
+ applet->launch_list = g_list_append(applet->launch_list,
+ (gpointer) item);
+
+ if (!applet->hourglass_shown)
+ show_hourglass(applet);
+ }
+ break;
+
+ case SN_MONITOR_EVENT_COMPLETED:
+ case SN_MONITOR_EVENT_CANCELED:
+ {
+ GList *tmp = applet->launch_list;
+
+ /* Find actual list item and free it*/
+ while(tmp != NULL) {
+ LaunchItem *item = (LaunchItem*) tmp->data;
+ if(!strcmp(item->id, id)) {
+ applet->launch_list = g_list_remove(tmp, item);
+ g_source_remove(item->timeout_id);
+ free(item->id);
+ free(item);
+
+ break;
+ }
+ tmp = tmp->next;
+ }
+
+ if (applet->launch_list == NULL && applet->hourglass_shown)
+ hide_hourglass(applet);
+ }
+ break;
+ default:
+ break; /* Nothing */
+ }
+}
+
+static gboolean timeout(StartupApplet *applet)
+{
+ time_t t;
+ char *icon;
+
+ if (!applet->hourglass_shown)
+ return TRUE;
+
+ t = time(NULL);
+ GList *tmp = applet->launch_list;
+
+ /* handle launchee timeouts */
+ while(tmp != NULL) {
+ LaunchItem *item = (LaunchItem*) tmp->data;
+ if ((item->when - t) <= 0) {
+ applet->launch_list = g_list_remove(tmp, item);
+ g_source_remove(item->timeout_id);
+ free(item->id);
+ free(item);
+
+ break;
+ }
+ tmp = tmp->next;
+ }
+
+ if (applet->launch_list == NULL && applet->hourglass_shown) {
+ hide_hourglass(applet);
+ return TRUE;
+ }
+
+ applet->hourglass_cur_frame_n++;
+ if (applet->hourglass_cur_frame_n == 8)
+ applet->hourglass_cur_frame_n = 0;
+
+ icon = malloc(sizeof(DATADIR) +16);
+ sprintf(icon, "%s/hourglass-%i.png", DATADIR,
+ applet->hourglass_cur_frame_n);
+
+ mb_panel_scaling_image_set_icon(applet->image, icon);
+
+ free(icon);
+
+ return TRUE;
+}
+
+static GdkFilterReturn filter_func(GdkXEvent *gdk_xevent, GdkEvent *event,
+ StartupApplet *applet) {
+ XEvent *xevent;
+ xevent = (XEvent *) gdk_xevent;
+ gboolean ret;
+
+ ret = sn_display_process_event(applet->sn_display, xevent);
+
+ return GDK_FILTER_CONTINUE;
+}
+
+G_MODULE_EXPORT GtkWidget *mb_panel_applet_create(const char *id,
+ GtkOrientation orientation)
+{
+ StartupApplet *applet;
+ Display *xdisplay;
+ SnMonitorContext *context;
+
+ /* Create applet data structure */
+ applet = g_slice_new(StartupApplet);
+
+ applet->launch_list = NULL;
+
+ /* Create image */
+ applet->image = MB_PANEL_SCALING_IMAGE(mb_panel_scaling_image_new
+ (orientation, NULL));
+
+ mb_panel_scaling_image_set_caching (applet->image, TRUE);
+
+ gtk_widget_set_name(GTK_WIDGET(applet->image),
+ "MatchboxPanelStartupMonitor" );
+
+ g_object_weak_ref( G_OBJECT(applet->image),
+ (GWeakNotify) startup_applet_free, applet );
+
+ xdisplay = GDK_DISPLAY_XDISPLAY
+ (gtk_widget_get_display(GTK_WIDGET(applet->image)));
+
+ applet->sn_display = sn_display_new(xdisplay, NULL, NULL);
+
+ context = sn_monitor_context_new(applet->sn_display,
+ DefaultScreen(xdisplay),
+ monitor_event_func, (void *)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);
+
+ return GTK_WIDGET(applet->image);
+}
diff --git a/configure.ac b/configure.ac
index 24f9534..80d5a8e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,6 +28,9 @@ if test x$enable_startup_notification != xno; then
AC_DEFINE(USE_LIBSN, [1], [Has Startup Notification Support])
fi
+AC_SUBST(SN_LIBS)
+AC_SUBST(SN_CFLAGS)
+
# libnotify
AC_ARG_ENABLE(libnotify,
[ --enable-libnotify enable libnotify support],
@@ -65,6 +68,8 @@ matchbox-panel/Makefile
applets/Makefile
applets/clock/Makefile
applets/launcher/Makefile
+applets/startup/Makefile
+applets/startup/data/Makefile
applets/systray/Makefile
applets/showdesktop/Makefile
applets/windowselector/Makefile