diff options
-rw-r--r-- | ChangeLog | 20 | ||||
-rw-r--r-- | applets/Makefile.am | 2 | ||||
-rw-r--r-- | applets/clock/clock.c | 68 | ||||
-rw-r--r-- | applets/launcher/launcher.c | 152 | ||||
-rw-r--r-- | applets/showdesktop/Makefile.am | 10 | ||||
-rw-r--r-- | applets/showdesktop/showdesktop.c | 170 | ||||
-rw-r--r-- | applets/systray/systray.c | 6 | ||||
-rw-r--r-- | configure.ac | 1 |
8 files changed, 309 insertions, 120 deletions
@@ -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 |