aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--applets/Makefile.am2
-rw-r--r--applets/clock/clock.c68
-rw-r--r--applets/launcher/launcher.c152
-rw-r--r--applets/showdesktop/Makefile.am10
-rw-r--r--applets/showdesktop/showdesktop.c170
-rw-r--r--applets/systray/systray.c6
-rw-r--r--configure.ac1
8 files changed, 309 insertions, 120 deletions
diff --git a/ChangeLog b/ChangeLog
index 4d7b4c2..9a8d6ae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,25 @@
2006-08-22 Jorn Baayen <jorn@openedhand.com>
+ * configure.ac:
+ * applets/Makefile.am:
+ * applets/showdesktop/Makefile.am:
+ * applets/showdesktop/showdesktop.c:
+
+ Added 'Show Desktop' button applet. Still needs to get an icon
+ packed into it.
+
+ * applets/clock/clock.c: (timeout), (mb_panel_applet_create):
+
+ Put stuff into ClockApplet data structure.
+
+ * applets/launcher/launcher.c: (button_release_event_cb),
+ (mb_panel_applet_create):
+ * applets/systray/systray.c:
+
+ Use screen-changed signal correctly.
+
+2006-08-22 Jorn Baayen <jorn@openedhand.com>
+
* applets/battery/Makefile.am:
* applets/battery/battery.c: (timeout), (mb_panel_applet_create):
* applets/battery/data/Makefile.am:
diff --git a/applets/Makefile.am b/applets/Makefile.am
index 224fdfb..b3a8059 100644
--- a/applets/Makefile.am
+++ b/applets/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = clock launcher systray
+SUBDIRS = clock launcher systray showdesktop
if HAVE_LIBAPM
SUBDIRS += battery
diff --git a/applets/clock/clock.c b/applets/clock/clock.c
index 62a85c4..396ea9d 100644
--- a/applets/clock/clock.c
+++ b/applets/clock/clock.c
@@ -10,23 +10,23 @@
#include <time.h>
#include <matchbox-panel/mb-panel.h>
-/* Applet destroyed */
+typedef struct {
+ GtkLabel *label;
+
+ guint timeout_id;
+} ClockApplet;
+
static void
-destroy_cb (GtkLabel *label)
+clock_applet_free (ClockApplet *applet)
{
- guint timeout_id;
-
- /* Remove timeout */
- timeout_id =
- GPOINTER_TO_UINT
- (g_object_get_data (G_OBJECT (label), "timeout-id"));
+ g_source_remove (applet->timeout_id);
- g_source_remove (timeout_id);
+ g_slice_free (ClockApplet, applet);
}
/* Called every minute */
static gboolean
-timeout (GtkLabel *label)
+timeout (ClockApplet *applet)
{
time_t t;
char str[6];
@@ -35,7 +35,7 @@ timeout (GtkLabel *label)
t = time (NULL);
strftime (str, 6, "%H:%M", localtime (&t));
- gtk_label_set_text (label, str);
+ gtk_label_set_text (applet->label, str);
/* Keep going */
return TRUE;
@@ -43,21 +43,15 @@ timeout (GtkLabel *label)
/* Called on the next minute after applet creation */
static gboolean
-initial_timeout (GtkLabel *label)
+initial_timeout (ClockApplet *applet)
{
- guint timeout_id;
-
/* Update label */
- timeout (label);
+ timeout (applet);
/* Install a new timeout that is called every minute */
- timeout_id = g_timeout_add (60 * 1000,
- (GSourceFunc) timeout,
- label);
-
- g_object_set_data (G_OBJECT (label),
- "timeout-id",
- GUINT_TO_POINTER (timeout_id));
+ applet->timeout_id = g_timeout_add (60 * 1000,
+ (GSourceFunc) timeout,
+ applet);
/* Don't call this again */
return FALSE;
@@ -85,34 +79,33 @@ mb_panel_applet_create (const char *id,
int panel_width,
int panel_height)
{
+ ClockApplet *applet;
GtkWidget *label;
- guint timeout_id;
time_t t;
struct tm *local_time;
+ /* Create applet data structure */
+ applet = g_slice_new (ClockApplet);
+
/* Create label */
label = gtk_label_new (NULL);
+ applet->label = GTK_LABEL (label);
gtk_widget_set_name (label, "MatchboxPanelClock");
- timeout (GTK_LABEL (label));
-
- g_signal_connect (label,
- "destroy",
- G_CALLBACK (destroy_cb),
- NULL);
+ g_object_weak_ref (G_OBJECT (label),
+ (GWeakNotify) clock_applet_free,
+ applet);
/* Set up a timeout to be called when we hit the next minute */
t = time (NULL);
local_time = localtime (&t);
- timeout_id = g_timeout_add ((60 - local_time->tm_sec) * 1000,
- (GSourceFunc) initial_timeout,
- label);
+ applet->timeout_id = g_timeout_add ((60 - local_time->tm_sec) * 1000,
+ (GSourceFunc) initial_timeout,
+ applet);
- g_object_set_data (G_OBJECT (label),
- "timeout-id",
- GUINT_TO_POINTER (timeout_id));
+ timeout (applet);
/* Is this a vertical panel? */
if (panel_width < panel_height) {
@@ -121,10 +114,7 @@ mb_panel_applet_create (const char *id,
"style-set",
G_CALLBACK (style_set_cb),
GINT_TO_POINTER (panel_width));
-
- gtk_misc_set_padding (GTK_MISC (label), 0, 5);
- } else
- gtk_misc_set_padding (GTK_MISC (label), 5, 0);
+ }
/* Show! */
gtk_widget_show (label);
diff --git a/applets/launcher/launcher.c b/applets/launcher/launcher.c
index 7fdbfb9..f2a982d 100644
--- a/applets/launcher/launcher.c
+++ b/applets/launcher/launcher.c
@@ -35,22 +35,22 @@ typedef struct {
char *name;
char **argv;
-} LauncherData;
+} LauncherApplet;
static void
-launcher_data_free (LauncherData *data)
+launcher_applet_free (LauncherApplet *applet)
{
- g_free (data->icon);
+ g_free (applet->icon);
- if (data->icon_theme_changed_id) {
- g_signal_handler_disconnect (data->icon_theme,
- data->icon_theme_changed_id);
+ if (applet->icon_theme_changed_id) {
+ g_signal_handler_disconnect (applet->icon_theme,
+ applet->icon_theme_changed_id);
}
- g_free (data->name);
- g_strfreev (data->argv);
+ g_free (applet->name);
+ g_strfreev (applet->argv);
- g_slice_free (LauncherData, data);
+ g_slice_free (LauncherApplet, applet);
}
/* Strips extension off filename */
@@ -75,27 +75,27 @@ strip_extension (const char *file)
/* This follows the same logic as gnome-panel. This should hopefully
* ensure correct behaviour. */
static char *
-find_icon (LauncherData *data)
+find_icon (LauncherApplet *applet)
{
GtkIconInfo *info;
char *icon, *stripped;
- if (g_path_is_absolute (data->icon)) {
- if (g_file_test (data->icon, G_FILE_TEST_EXISTS))
- return g_strdup (data->icon);
+ if (g_path_is_absolute (applet->icon)) {
+ if (g_file_test (applet->icon, G_FILE_TEST_EXISTS))
+ return g_strdup (applet->icon);
else
- icon = g_path_get_basename (data->icon);
+ icon = g_path_get_basename (applet->icon);
} else
- icon = data->icon;
+ icon = applet->icon;
stripped = strip_extension (icon);
- if (icon != data->icon)
+ if (icon != applet->icon)
g_free (icon);
- info = gtk_icon_theme_lookup_icon (data->icon_theme,
+ info = gtk_icon_theme_lookup_icon (applet->icon_theme,
stripped,
- data->icon_size,
+ applet->icon_size,
0);
g_free (stripped);
@@ -114,32 +114,32 @@ find_icon (LauncherData *data)
/* Icon theme changed */
static void
-icon_theme_changed_cb (GtkIconTheme *icon_theme,
- LauncherData *data)
+icon_theme_changed_cb (GtkIconTheme *icon_theme,
+ LauncherApplet *applet)
{
/* Reload icon */
char *file;
GdkPixbuf *pixbuf;
GError *error;
- file = find_icon (data);
+ file = find_icon (applet);
if (!file) {
- g_warning ("Icon \"%s\" not found", data->icon);
+ g_warning ("Icon \"%s\" not found", applet->icon);
return;
}
error = NULL;
pixbuf = gdk_pixbuf_new_from_file_at_scale (file,
- data->icon_size,
- data->icon_size,
+ applet->icon_size,
+ applet->icon_size,
TRUE,
&error);
g_free (file);
if (pixbuf) {
- gtk_image_set_from_pixbuf (data->image, pixbuf);
+ gtk_image_set_from_pixbuf (applet->image, pixbuf);
g_object_unref (pixbuf);
} else {
@@ -151,34 +151,33 @@ icon_theme_changed_cb (GtkIconTheme *icon_theme,
/* Screen set or changed */
static void
-screen_changed_cb (GtkWidget *widget,
- GdkScreen *screen,
- LauncherData *data)
+screen_changed_cb (GtkWidget *widget,
+ GdkScreen *old_screen,
+ LauncherApplet *applet)
{
+ GdkScreen *screen;
GtkIconTheme *new_icon_theme;
/* Get associated icon theme */
- if (!screen)
- screen = gdk_screen_get_default ();
-
+ screen = gtk_widget_get_screen (widget);
new_icon_theme = gtk_icon_theme_get_for_screen (screen);
- if (data->icon_theme == new_icon_theme)
+ if (applet->icon_theme == new_icon_theme)
return;
- if (data->icon_theme_changed_id) {
- g_signal_handler_disconnect (data->icon_theme,
- data->icon_theme_changed_id);
+ if (applet->icon_theme_changed_id) {
+ g_signal_handler_disconnect (applet->icon_theme,
+ applet->icon_theme_changed_id);
}
- data->icon_theme = new_icon_theme;
+ applet->icon_theme = new_icon_theme;
- data->icon_theme_changed_id =
- g_signal_connect (data->icon_theme,
+ applet->icon_theme_changed_id =
+ g_signal_connect (applet->icon_theme,
"changed",
G_CALLBACK (icon_theme_changed_cb),
- data);
+ applet);
- icon_theme_changed_cb (data->icon_theme, data);
+ icon_theme_changed_cb (applet->icon_theme, applet);
}
/* Convert command line to argv array, stripping % conversions on the way */
@@ -267,12 +266,12 @@ exec_to_argv (const char *exec)
static gboolean
button_press_event_cb (GtkWidget *event_box,
GdkEventButton *event,
- LauncherData *data)
+ LauncherApplet *applet)
{
if (event->button != 1)
return TRUE;
- data->button_down = TRUE;
+ applet->button_down = TRUE;
return TRUE;
}
@@ -281,7 +280,7 @@ button_press_event_cb (GtkWidget *event_box,
static gboolean
button_release_event_cb (GtkWidget *event_box,
GdkEventButton *event,
- LauncherData *data)
+ LauncherApplet *applet)
{
int x, y;
pid_t child_pid = 0;
@@ -289,10 +288,10 @@ button_release_event_cb (GtkWidget *event_box,
SnLauncherContext *context;
#endif
- if (event->button != 1 || !data->button_down)
+ if (event->button != 1 || !applet->button_down)
return TRUE;
- data->button_down = FALSE;
+ applet->button_down = FALSE;
/* Only process if the button was released inside the button */
gtk_widget_translate_coordinates (event_box,
@@ -311,7 +310,7 @@ button_release_event_cb (GtkWidget *event_box,
#ifdef USE_LIBSN
context = NULL;
- if (data->use_sn) {
+ if (applet->use_sn) {
SnDisplay *sn_dpy;
Display *display;
int screen;
@@ -325,13 +324,13 @@ button_release_event_cb (GtkWidget *event_box,
context = sn_launcher_context_new (sn_dpy, screen);
sn_display_unref (sn_dpy);
- sn_launcher_context_set_name (context, data->name);
+ sn_launcher_context_set_name (context, applet->name);
sn_launcher_context_set_binary_name (context,
- data->argv[0]);
+ applet->argv[0]);
sn_launcher_context_initiate (context,
"matchbox-panel",
- data->argv[0],
+ applet->argv[0],
CurrentTime);
}
#endif
@@ -342,19 +341,19 @@ button_release_event_cb (GtkWidget *event_box,
break;
case 0:
#ifdef USE_LIBSN
- if (data->use_sn)
+ if (applet->use_sn)
sn_launcher_context_setup_child_process (context);
#endif
- execvp (data->argv[0], data->argv);
+ execvp (applet->argv[0], applet->argv);
- g_warning ("Failed to execvp() %s", data->argv[0]);
+ g_warning ("Failed to execvp() %s", applet->argv[0]);
_exit (1);
break;
}
#ifdef USE_LIBSN
- if (data->use_sn)
+ if (applet->use_sn)
sn_launcher_context_unref (context);
#endif
@@ -363,13 +362,13 @@ button_release_event_cb (GtkWidget *event_box,
/* Someone took or released the GTK+ grab */
static void
-grab_notify_cb (GtkWidget *widget,
- gboolean was_grabbed,
- LauncherData *data)
+grab_notify_cb (GtkWidget *widget,
+ gboolean was_grabbed,
+ LauncherApplet *applet)
{
if (!was_grabbed) {
/* It wasn't us. Reset press state */
- data->button_down = FALSE;
+ applet->button_down = FALSE;
}
}
@@ -384,7 +383,7 @@ mb_panel_applet_create (const char *id,
GError *error;
char *icon, *exec, *name;
gboolean use_sn;
- LauncherData *data;
+ LauncherApplet *applet;
/* Try to find a .desktop file for @id */
key_file = g_key_file_new ();
@@ -476,48 +475,47 @@ mb_panel_applet_create (const char *id,
gtk_container_add (GTK_CONTAINER (event_box), image);
- /* Set up data structure */
- data = g_slice_new (LauncherData);
+ /* Set up applet structure */
+ applet = g_slice_new (LauncherApplet);
- data->image = GTK_IMAGE (image);
+ applet->image = GTK_IMAGE (image);
- data->icon = icon;
- data->icon_size = MIN (panel_width, panel_height);
+ applet->icon = icon;
+ applet->icon_size = MIN (panel_width, panel_height);
- data->icon_theme = NULL;
- data->icon_theme_changed_id = 0;
+ applet->icon_theme = NULL;
+ applet->icon_theme_changed_id = 0;
- data->button_down = FALSE;
+ applet->button_down = FALSE;
- data->use_sn = use_sn;
+ applet->use_sn = use_sn;
- data->name = name;
+ applet->name = name;
- data->argv = exec_to_argv (exec);
+ applet->argv = exec_to_argv (exec);
g_free (exec);
g_object_weak_ref (G_OBJECT (event_box),
- (GWeakNotify) launcher_data_free,
- data);
+ (GWeakNotify) launcher_applet_free,
+ applet);
/* Listen to events */
g_signal_connect (event_box,
"button-press-event",
G_CALLBACK (button_press_event_cb),
- data);
+ applet);
g_signal_connect (event_box,
"button-release-event",
G_CALLBACK (button_release_event_cb),
- data);
+ applet);
g_signal_connect (event_box,
"grab-notify",
G_CALLBACK (grab_notify_cb),
- data);
-
- g_signal_connect (image,
+ applet);
+ g_signal_connect (event_box,
"screen-changed",
G_CALLBACK (screen_changed_cb),
- data);
+ applet);
/* Show! */
gtk_widget_show_all (event_box);
diff --git a/applets/showdesktop/Makefile.am b/applets/showdesktop/Makefile.am
new file mode 100644
index 0000000..8434dd0
--- /dev/null
+++ b/applets/showdesktop/Makefile.am
@@ -0,0 +1,10 @@
+AM_CPPFLAGS=-DPKGDATADIR=\"$(pkgdatadir)\" -DGETTEXT_PACKAGE=\"matchbox-panel\"
+AM_CFLAGS = -Wall -g $(MATCHBOX_PANEL_CFLAGS) \
+ -I$(top_srcdir) -I$(top_builddir) -Werror
+
+appletdir = $(libdir)/matchbox-panel
+applet_LTLIBRARIES = libshowdesktop.la
+
+libshowdesktop_la_SOURCES = showdesktop.c
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/applets/showdesktop/showdesktop.c b/applets/showdesktop/showdesktop.c
new file mode 100644
index 0000000..cd22bac
--- /dev/null
+++ b/applets/showdesktop/showdesktop.c
@@ -0,0 +1,170 @@
+/*
+ * (C) 2006 OpenedHand Ltd.
+ *
+ * Author: Jorn Baayen <jorn@openedhand.com>
+ *
+ * Licensed under the GPL v2 or greater.
+ */
+
+#include <gtk/gtktogglebutton.h>
+#include <gtk/gtkimage.h>
+#include <gdk/gdkx.h>
+#include <matchbox-panel/mb-panel.h>
+
+typedef struct {
+ GtkToggleButton *button;
+
+ gboolean block_toggle;
+
+ Atom atom;
+
+ GdkWindow *root_window;
+} ShowDesktopApplet;
+
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+ GdkEvent *event,
+ ShowDesktopApplet *applet);
+
+static void
+show_desktop_applet_free (ShowDesktopApplet *applet)
+{
+ if (applet->root_window) {
+ gdk_window_remove_filter (applet->root_window,
+ (GdkFilterFunc) filter_func,
+ applet);
+ }
+
+ g_slice_free (ShowDesktopApplet, applet);
+}
+
+/* _NET_SHOWING_DESKTOP message received */
+static GdkFilterReturn
+filter_func (GdkXEvent *xevent,
+ GdkEvent *event,
+ ShowDesktopApplet *applet)
+{
+ XEvent *xev;
+
+ xev = (XEvent *) xevent;
+
+ if (xev->type == ClientMessage) {
+ if (xev->xclient.message_type == applet->atom) {
+ applet->block_toggle = TRUE;
+
+ gtk_toggle_button_set_active (applet->button,
+ xev->xclient.data.l[0]);
+
+ applet->block_toggle = FALSE;
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+/* Screen changed */
+static void
+screen_changed_cb (GtkWidget *button,
+ GdkScreen *old_screen,
+ ShowDesktopApplet *applet)
+{
+ GdkScreen *screen;
+ GdkDisplay *display;
+
+ if (applet->root_window) {
+ gdk_window_remove_filter (applet->root_window,
+ (GdkFilterFunc) filter_func,
+ applet);
+ }
+
+ screen = gtk_widget_get_screen (button);
+ display = gdk_screen_get_display (screen);
+
+ applet->atom = gdk_x11_get_xatom_by_name_for_display
+ (display, "_NET_SHOWING_DESKTOP");
+ applet->root_window = gdk_screen_get_root_window (screen);
+
+ /* Watch _NET_SHOWING_DESKTOP */
+ gdk_window_add_filter (applet->root_window,
+ (GdkFilterFunc) filter_func,
+ applet);
+}
+
+/* Button toggled */
+static void
+button_toggled_cb (GtkToggleButton *button,
+ ShowDesktopApplet *applet)
+{
+ GtkWidget *widget;
+ Screen *screen;
+ XEvent xev;
+
+ if (applet->block_toggle)
+ return;
+
+ widget = GTK_WIDGET (button);
+ screen = GDK_SCREEN_XSCREEN (gtk_widget_get_screen (widget));
+
+ xev.xclient.type = ClientMessage;
+ xev.xclient.serial = 0;
+ xev.xclient.send_event = True;
+ xev.xclient.display = DisplayOfScreen (screen);
+ xev.xclient.window = RootWindowOfScreen (screen);
+ xev.xclient.message_type = applet->atom;
+ xev.xclient.format = 32;
+ xev.xclient.data.l[0] = button->active;
+ xev.xclient.data.l[1] = 0;
+ xev.xclient.data.l[2] = 0;
+ xev.xclient.data.l[3] = 0;
+ xev.xclient.data.l[4] = 0;
+
+ XSendEvent (DisplayOfScreen (screen),
+ RootWindowOfScreen (screen),
+ False,
+ SubstructureRedirectMask | SubstructureNotifyMask,
+ &xev);
+}
+
+G_MODULE_EXPORT GtkWidget *
+mb_panel_applet_create (const char *id,
+ int panel_width,
+ int panel_height)
+{
+ ShowDesktopApplet *applet;
+ GtkWidget *button, *image;
+
+ /* Create applet data structure */
+ applet = g_slice_new (ShowDesktopApplet);
+
+ applet->block_toggle = FALSE;
+ applet->root_window = NULL;
+
+ /* Create button */
+ button = gtk_toggle_button_new ();
+ applet->button = GTK_TOGGLE_BUTTON (button);
+
+ GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_FOCUS);
+
+ gtk_widget_set_name (button, "MatchboxPanelShowDesktop");
+
+ image = gtk_image_new ();
+ gtk_container_add (GTK_CONTAINER (button), image);
+
+ g_signal_connect (button,
+ "screen-changed",
+ G_CALLBACK (screen_changed_cb),
+ applet);
+ g_signal_connect (button,
+ "toggled",
+ G_CALLBACK (button_toggled_cb),
+ applet);
+
+ g_object_weak_ref (G_OBJECT (button),
+ (GWeakNotify) show_desktop_applet_free,
+ applet);
+
+ /* Show! */
+ gtk_widget_show_all (button);
+
+ return button;
+};
diff --git a/applets/systray/systray.c b/applets/systray/systray.c
index 78c6b29..45d2b6b 100644
--- a/applets/systray/systray.c
+++ b/applets/systray/systray.c
@@ -134,12 +134,12 @@ message_cancelled_cb (EggTrayManager *manager,
/* Screen changed */
static void
screen_changed_cb (GtkWidget *widget,
- GdkScreen *screen,
+ GdkScreen *old_screen,
EggTrayManager *manager)
{
- if (!screen)
- screen = gdk_screen_get_default ();
+ GdkScreen *screen;
+ screen = gtk_widget_get_screen (widget);
if (egg_tray_manager_check_running (screen)) {
g_warning ("Another system tray manager is running. "
"Not managing screen.");
diff --git a/configure.ac b/configure.ac
index 880f889..839ed8a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,7 @@ applets/Makefile
applets/clock/Makefile
applets/launcher/Makefile
applets/systray/Makefile
+applets/showdesktop/Makefile
applets/battery/Makefile
applets/battery/data/Makefile
po/Makefile.in