summaryrefslogtreecommitdiff
path: root/src/notification.c
diff options
context:
space:
mode:
authorLucas Rocha <lucasr@gnome.org>2006-07-28 21:25:11 +0000
committerLucas Almeida Rocha <lucasr@src.gnome.org>2006-07-28 21:25:11 +0000
commitd373b3f3ce9e1876f2e267bf240fbb807abd6815 (patch)
treed5a34fee0582667ea12d1905540dabb5ed68577e /src/notification.c
parente46814b46ac4687de519dfdd0fd8f578cfa17946 (diff)
src/notification.c (-set_scaled_pixbuf, +zenity_notification_icon_update,
2006-07-27 Lucas Rocha <lucasr@gnome.org> * src/notification.c (-set_scaled_pixbuf, +zenity_notification_icon_update, -zenity_notification_icon_press_callback, +zenity_notification_icon_size_changed_cb, -zenity_notification_icon_expose_callback, -zenity_notification_icon_destroy_callback, +zenity_notification_icon_activate_cb, zenity_notification_handle_stdin, zenity_notification), src/util.[ch] (+zenity_util_stock_from_filename, zenity_util_pixbuf_new_from_file), Makefile.am, configure.in: Migration to gtk_status_icon (Fixes bug #341451). Patch from Christian Persch <chpe@gnome.org>. * src/eggtrayicon.[ch]: removed.
Diffstat (limited to 'src/notification.c')
-rw-r--r--src/notification.c287
1 files changed, 127 insertions, 160 deletions
diff --git a/src/notification.c b/src/notification.c
index 6d5f8dd..222fbc8 100644
--- a/src/notification.c
+++ b/src/notification.c
@@ -2,6 +2,7 @@
* notification.c
*
* Copyright (C) 2002 Sun Microsystems, Inc.
+ * Copyright (C) 2006 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +24,7 @@
#include <config.h>
+#include <gtk/gtk.h>
#include <glade/glade.h>
#include <time.h>
#include <string.h>
@@ -32,101 +34,71 @@
#endif
#include "zenity.h"
-#include "eggtrayicon.h"
#include "util.h"
-static EggTrayIcon *tray_icon;
-static GtkWidget *icon_image;
-static GtkWidget *icon_event_box;
-static GtkTooltips *tooltips;
-
+static GtkStatusIcon *status_icon;
+static gchar *icon_file;
+static const gchar *icon_stock;
+static gint icon_size;
static void
-set_scaled_pixbuf (GtkImage *image, GdkPixbuf *pixbuf, GtkIconSize icon_size)
+zenity_notification_icon_update (void)
{
- GdkScreen *screen;
- GtkSettings *settings;
- int width, height, desired_width, desired_height;
- GdkPixbuf *new_pixbuf;
-
- screen = gtk_widget_get_screen (GTK_WIDGET (image));
- settings = gtk_settings_get_for_screen (screen);
- if (!gtk_icon_size_lookup_for_settings (settings, icon_size,
- &desired_width, &desired_height))
- return;
-
- width = gdk_pixbuf_get_width (pixbuf);
- height = gdk_pixbuf_get_height (pixbuf);
- if (height > desired_height || width > desired_width) {
- if (width * desired_height / height > desired_width)
- desired_height = height * desired_width / width;
- else
- desired_width = width * desired_height / height;
-
- new_pixbuf = gdk_pixbuf_scale_simple (pixbuf,
- desired_width,
- desired_height,
- GDK_INTERP_BILINEAR);
- gtk_image_set_from_pixbuf (image, new_pixbuf);
- g_object_unref (new_pixbuf);
- } else {
- gtk_image_set_from_pixbuf (image, pixbuf);
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (icon_file, icon_size, icon_size, TRUE, &error);
+ if (error) {
+ g_warning ("Could not load notification icon '%s': %s",
+ icon_file, error->message);
+ g_clear_error (&error);
+ }
+ if (!pixbuf) {
+ pixbuf = gdk_pixbuf_new_from_file_at_scale (ZENITY_IMAGE_FULLPATH ("zenity-notification.png"),
+ icon_size, icon_size, TRUE, NULL);
+ }
+
+ gtk_status_icon_set_from_pixbuf (status_icon, pixbuf);
+
+ if (pixbuf) {
+ g_object_unref (pixbuf);
}
}
static gboolean
-zenity_notification_icon_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer data)
+zenity_notification_icon_size_changed_cb (GtkStatusIcon *icon,
+ gint size,
+ gpointer user_data)
{
- ZenityData *zen_data;
+ icon_size = size;
- zen_data = data;
+ /* If we're displaying not a stock icon but a custom pixbuf,
+ * we need to update the icon for the new size.
+ */
+ if (!icon_stock) {
+ zenity_notification_icon_update ();
- zen_data->exit_code = zenity_util_return_exit_code (ZENITY_OK);
- gtk_main_quit ();
- return TRUE;
-}
+ return TRUE;
+ }
-static gboolean
-zenity_notification_icon_expose_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
-{
- if (GTK_WIDGET_HAS_FOCUS (widget)) {
- gint focus_width, focus_pad;
- gint x, y, width, height;
-
- gtk_widget_style_get (widget,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
- x = widget->allocation.x + focus_pad;
- y = widget->allocation.y + focus_pad;
- width = widget->allocation.width - 2 * focus_pad;
- height = widget->allocation.height - 2 * focus_pad;
-
- gtk_paint_focus (widget->style, widget->window,
- GTK_WIDGET_STATE (widget),
- &event->area, widget, "button",
- x, y, width, height);
- }
-
- return FALSE;
+ return FALSE;
}
-static void
-zenity_notification_icon_destroy_callback (GtkWidget *widget, gpointer data)
+static gboolean
+zenity_notification_icon_activate_cb (GtkWidget *widget,
+ ZenityData *data)
{
- ZenityData *zen_data;
+ data->exit_code = zenity_util_return_exit_code (ZENITY_OK);
- zen_data = data;
- gtk_widget_destroy (GTK_WIDGET (tray_icon));
-
- zen_data->exit_code = zenity_util_return_exit_code (ZENITY_ESC);
gtk_main_quit ();
+
+ return TRUE;
}
static gboolean
-zenity_notification_handle_stdin (GIOChannel *channel,
+zenity_notification_handle_stdin (GIOChannel *channel,
GIOCondition condition,
- gpointer user_data)
+ gpointer user_data)
{
ZenityData *zen_data;
@@ -137,7 +109,7 @@ zenity_notification_handle_stdin (GIOChannel *channel,
GError *error = NULL;
string = g_string_new (NULL);
- while (channel->is_readable != TRUE)
+ while (channel->is_readable == FALSE)
;
do {
gint status;
@@ -167,60 +139,72 @@ zenity_notification_handle_stdin (GIOChannel *channel,
continue;
}
/* split off the command and value */
- command = g_strndup (string->str, colon - string->str);
- command = g_strstrip (command);
- g_strdown (command);
+ command = g_strstrip (g_strndup (string->str, colon - string->str));
value = colon + 1;
while (*value && g_ascii_isspace (*value)) value++;
- if (!strcmp (command, "icon")) {
- GdkPixbuf *pixbuf;
-
- pixbuf = zenity_util_pixbuf_new_from_file (GTK_WIDGET (tray_icon),
- value);
- if (pixbuf != NULL) {
- set_scaled_pixbuf (GTK_IMAGE (icon_image), pixbuf,
- GTK_ICON_SIZE_BUTTON);
- gdk_pixbuf_unref (pixbuf);
- } else {
- g_warning ("Could not load notification icon : %s", value);
- }
- } else if (!strcmp (command, "message")) {
-#ifdef HAVE_LIBNOTIFY
- /* display a notification bubble */
- if (notify_is_initted ()) {
- GError *error = NULL;
- NotifyNotification *n;
- GdkPixbuf *icon;
-
- n = notify_notification_new (g_strcompress (value), NULL, NULL,
- GTK_WIDGET (tray_icon));
+ if (!g_ascii_strcasecmp (command, "icon")) {
+ icon_stock = zenity_util_stock_from_filename (value);
- icon = gtk_image_get_pixbuf (GTK_IMAGE (icon_image));
+ g_free (icon_file);
+ icon_file = g_strdup (value);
- notify_notification_set_icon_from_pixbuf (n, icon);
-
- notify_notification_show (n, &error);
+ if (icon_stock) {
+ gtk_status_icon_set_from_stock (status_icon, icon_stock);
+ } else if (gtk_status_icon_get_visible (status_icon) &&
+ gtk_status_icon_is_embedded (status_icon)) {
+ zenity_notification_icon_update ();
+ }
+ } else if (!g_ascii_strcasecmp (command, "message")) {
+#ifdef HAVE_LIBNOTIFY
+ /* display a notification bubble */
+ if (!g_utf8_validate (value, -1, NULL)) {
+ g_warning ("Invalid UTF-8 in input!");
+ } else if (notify_is_initted ()) {
+ GError *error = NULL;
+ NotifyNotification *notif;
+ const gchar *icon = NULL;
+ gchar *freeme = NULL;
+ gchar *message;
+
+ message = g_strcompress (value);
+
+ if (icon_stock) {
+ icon = icon_stock;
+ } else if (icon_file) {
+ icon = freeme = g_filename_to_uri (icon_file, NULL, NULL);
+ }
+
+ notif = notify_notification_new_with_status_icon (message, NULL /* summary */,
+ icon, status_icon);
+ g_free (message);
+ g_free (freeme);
+
+ notify_notification_show (notif, &error);
if (error) {
- g_warning (error->message);
+ g_warning ("Error showing notification: %s", error->message);
g_error_free (error);
}
- g_object_unref (G_OBJECT (n));
+ g_object_unref (notif);
} else {
#else
{ /* this brace is for balance */
#endif
g_warning ("Notification framework not available");
}
- } else if (!strcmp (command, "tooltip")) {
- gtk_tooltips_set_tip (tooltips, icon_event_box, value, value);
- } else if (!strcmp (command, "visible")) {
- if (!strcasecmp (value, "false")) {
- gtk_widget_hide (GTK_WIDGET (tray_icon));
- } else {
- gtk_widget_show (GTK_WIDGET (tray_icon));
+ } else if (!g_ascii_strcasecmp (command, "tooltip")) {
+ if (g_utf8_validate (value, -1, NULL)) {
+ gtk_status_icon_set_tooltip (status_icon, value);
+ } else {
+ g_warning ("Invalid UTF-8 in input!");
+ }
+ } else if (!g_ascii_strcasecmp (command, "visible")) {
+ if (!g_ascii_strcasecmp (value, "false")) {
+ gtk_status_icon_set_visible (status_icon, FALSE);
+ } else {
+ gtk_status_icon_set_visible (status_icon, TRUE);
}
} else {
g_warning ("Unknown command '%s'", command);
@@ -256,64 +240,47 @@ zenity_notification_listen_on_stdin (ZenityData *data)
void
zenity_notification (ZenityData *data, ZenityNotificationData *notification_data)
{
- GdkPixbuf *pixbuf = NULL;
+ status_icon = gtk_status_icon_new ();
+ g_signal_connect (status_icon, "size-changed",
+ G_CALLBACK (zenity_notification_icon_size_changed_cb), data);
- tray_icon = egg_tray_icon_new (_("Zenity notification"));
- tooltips = gtk_tooltips_new ();
-
- if (data->window_icon != NULL)
- pixbuf = zenity_util_pixbuf_new_from_file (GTK_WIDGET (tray_icon), data->window_icon);
- else
- pixbuf = gdk_pixbuf_new_from_file (ZENITY_IMAGE_FULLPATH ("zenity-notification.png"), NULL);
-
- icon_event_box = gtk_event_box_new ();
- icon_image = gtk_image_new ();
-
- if (pixbuf) {
- set_scaled_pixbuf (GTK_IMAGE (icon_image), pixbuf,
- GTK_ICON_SIZE_BUTTON);
- gdk_pixbuf_unref (pixbuf);
+ if (notification_data->notification_text) {
+ gtk_status_icon_set_tooltip (status_icon, notification_data->notification_text);
} else {
- if (data->window_icon != NULL) {
- g_warning ("Could not load notification icon : %s", data->window_icon);
- }
- else
- g_warning ("Could not load notification icon : %s", ZENITY_IMAGE_FULLPATH ("zenity-notification.png"));
- return;
+ gtk_status_icon_set_tooltip (status_icon, _("Zenity notification"));
}
- gtk_container_add (GTK_CONTAINER (icon_event_box), icon_image);
-
- if (notification_data->notification_text)
- gtk_tooltips_set_tip (tooltips, icon_event_box, notification_data->notification_text, notification_data->notification_text);
- else
- gtk_tooltips_set_tip (tooltips, icon_event_box, _("Zenity notification"), _("Zenity notification"));
-
- gtk_widget_add_events (GTK_WIDGET (tray_icon), GDK_BUTTON_PRESS_MASK | GDK_FOCUS_CHANGE_MASK);
- gtk_container_add (GTK_CONTAINER (tray_icon), icon_event_box);
+ icon_file = g_strdup (data->window_icon);
+ icon_stock = zenity_util_stock_from_filename (data->window_icon);
- g_signal_connect (tray_icon, "destroy",
- G_CALLBACK (zenity_notification_icon_destroy_callback), data);
-
- g_signal_connect (tray_icon, "expose_event",
- G_CALLBACK (zenity_notification_icon_expose_callback), data);
+ /* Only set the stock icon here; if we're going to display a
+ * custom pixbuf we wait for the size-changed signal to load
+ * it at the right size.
+ */
+ if (icon_stock) {
+ gtk_status_icon_set_from_stock (status_icon, icon_stock);
+ }
+#ifdef HAVE_LIBNOTIFY
+ /* create the notification widget */
+ if (!notify_is_initted ()) {
+ notify_init (_("Zenity notification"));
+ }
+#endif
+
if (notification_data->listen) {
zenity_notification_listen_on_stdin (data);
} else {
- /* if we aren't listening for changes, then close on button_press */
- g_signal_connect (tray_icon, "button_press_event",
- G_CALLBACK (zenity_notification_icon_press_callback), data);
+ /* if we aren't listening for changes, then close on activate (left-click) */
+ g_signal_connect (status_icon, "activate",
+ G_CALLBACK (zenity_notification_icon_activate_cb), data);
}
-#ifdef HAVE_LIBNOTIFY
- /* create the notification widget */
- if (!notify_is_initted ())
- notify_init (_("Zenity notification"));
-#endif
-
- gtk_widget_show_all (GTK_WIDGET (tray_icon));
-
- /* Does nothing at the moment */
+ /* Show icon and wait */
+ gtk_status_icon_set_visible (status_icon, TRUE);
gtk_main ();
+
+ /* Cleanup */
+ g_object_unref (status_icon);
+ g_free (icon_file);
}