diff options
-rw-r--r-- | ChangeLog | 11 | ||||
-rw-r--r-- | applets/Makefile.am | 2 | ||||
-rw-r--r-- | applets/startup/Makefile.am | 17 | ||||
-rw-r--r-- | applets/startup/data/Makefile.am | 11 | ||||
-rw-r--r-- | applets/startup/data/hourglass-0.png | bin | 0 -> 996 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-1.png | bin | 0 -> 1147 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-2.png | bin | 0 -> 1125 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-3.png | bin | 0 -> 1118 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-4.png | bin | 0 -> 1024 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-5.png | bin | 0 -> 1456 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-6.png | bin | 0 -> 1131 bytes | |||
-rw-r--r-- | applets/startup/data/hourglass-7.png | bin | 0 -> 1372 bytes | |||
-rw-r--r-- | applets/startup/startup.c | 250 | ||||
-rw-r--r-- | configure.ac | 5 |
14 files changed, 295 insertions, 1 deletions
@@ -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 Binary files differnew file mode 100644 index 0000000..7493688 --- /dev/null +++ b/applets/startup/data/hourglass-0.png diff --git a/applets/startup/data/hourglass-1.png b/applets/startup/data/hourglass-1.png Binary files differnew file mode 100644 index 0000000..d195085 --- /dev/null +++ b/applets/startup/data/hourglass-1.png diff --git a/applets/startup/data/hourglass-2.png b/applets/startup/data/hourglass-2.png Binary files differnew file mode 100644 index 0000000..2f1e7bc --- /dev/null +++ b/applets/startup/data/hourglass-2.png diff --git a/applets/startup/data/hourglass-3.png b/applets/startup/data/hourglass-3.png Binary files differnew file mode 100644 index 0000000..712392d --- /dev/null +++ b/applets/startup/data/hourglass-3.png diff --git a/applets/startup/data/hourglass-4.png b/applets/startup/data/hourglass-4.png Binary files differnew file mode 100644 index 0000000..b11c1b7 --- /dev/null +++ b/applets/startup/data/hourglass-4.png diff --git a/applets/startup/data/hourglass-5.png b/applets/startup/data/hourglass-5.png Binary files differnew file mode 100644 index 0000000..13020d6 --- /dev/null +++ b/applets/startup/data/hourglass-5.png diff --git a/applets/startup/data/hourglass-6.png b/applets/startup/data/hourglass-6.png Binary files differnew file mode 100644 index 0000000..50a2db3 --- /dev/null +++ b/applets/startup/data/hourglass-6.png diff --git a/applets/startup/data/hourglass-7.png b/applets/startup/data/hourglass-7.png Binary files differnew file mode 100644 index 0000000..e345b2c --- /dev/null +++ b/applets/startup/data/hourglass-7.png 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 |