summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog15
-rw-r--r--data/Makefile.am3
-rw-r--r--data/zenity-notification.pngbin0 -> 898 bytes
-rw-r--r--data/zenity.114
-rw-r--r--help/C/figures/zenity-notification-screenshot.pngbin0 -> 3104 bytes
-rwxr-xr-xhelp/C/l10n_scripts/notification.sh5
-rw-r--r--help/C/zenity.xml70
-rw-r--r--src/Makefile.am3
-rw-r--r--src/about.c4
-rw-r--r--src/calendar.c5
-rw-r--r--src/eggtrayicon.c468
-rw-r--r--src/eggtrayicon.h77
-rw-r--r--src/entry.c5
-rw-r--r--src/fileselection.c5
-rw-r--r--src/main.c67
-rw-r--r--src/msg.c36
-rw-r--r--src/notification.c129
-rw-r--r--src/progress.c5
-rw-r--r--src/text.c5
-rw-r--r--src/tree.c5
-rw-r--r--src/util.c73
-rw-r--r--src/util.h10
-rw-r--r--src/zenity.h6
23 files changed, 918 insertions, 92 deletions
diff --git a/ChangeLog b/ChangeLog
index 3801b06..aaa250b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,20 @@
2004-09-13 Glynn Foster <glynn.foster@sun.com>
+ * data/Makefile.am, data/zenity-notification.png: Add new
+ notification icon.
+ * src/Makefile.am: Update for new files.
+ * src/about.c, src/calendar.c, src/entry.c, src/fileselection.c,
+ src/progress.c, src/text.c, src/tree.c, src/msg.c: Restructure code a
+ little bit for new utility functions for setting window icons.
+ * src/eggtrayicon.c, src/eggtrayicon.h: New files for notification area
+ support.
+ * src/main.c, src/notification.c, src/util.c, src/util.h, src/zenity.h:
+ Add support for notification area.
+ * data/zenity.1, help/*: Update docs for notification and new file
+ selection changes.
+
+2004-09-13 Glynn Foster <glynn.foster@sun.com>
+
* THANKS: Update
* src/about.c: Update.
* src/fileselection.c, src/main.c, src/zenity.h:
diff --git a/data/Makefile.am b/data/Makefile.am
index aade652..fd71b4e 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -14,7 +14,8 @@ images_DATA = \
zenity-file.png \
zenity-progress.png \
zenity-text.png \
- zenity-entry.png
+ zenity-entry.png \
+ zenity-notification.png
man_MANS = zenity.1
diff --git a/data/zenity-notification.png b/data/zenity-notification.png
new file mode 100644
index 0000000..6b44ef9
--- /dev/null
+++ b/data/zenity-notification.png
Binary files differ
diff --git a/data/zenity.1 b/data/zenity.1
index 17f6eab..3949899 100644
--- a/data/zenity.1
+++ b/data/zenity.1
@@ -43,6 +43,9 @@ Display info dialog
.B \-\-list
Display list dialog
.TP
+.B \-\-notification
+Display notification icon
+.TP
.B \-\-progress
Display progress indication dialog
.TP
@@ -153,6 +156,13 @@ Specify what column to print to standard output. The default is to return
the first column. 'ALL' may be used to print all columns.
.PP
+Notification options
+
+.TP
+.B \-\-text=STRING
+Set the notification text
+
+.PP
Progress options
.TP
@@ -230,6 +240,10 @@ and the text \fIFinding all header files...\fP.
.IP
find . -name '*.h' | zenity --title "Search Results" --text "Finding all header files.." --column "Files"
.PP
+Show an icon in the notification area
+.IP
+zenity --notification --window-icon=update.png --text "System update necessary!"
+.PP
Display a weekly shopping list in a check list dialog with \fIApples\fP and \fIOranges\fP pre selected
.IP
zenity --list --checklist --column "Buy" --column "Item" TRUE Apples TRUE Oranges FALSE Pears FALSE Toothpaste
diff --git a/help/C/figures/zenity-notification-screenshot.png b/help/C/figures/zenity-notification-screenshot.png
new file mode 100644
index 0000000..c1b2c9a
--- /dev/null
+++ b/help/C/figures/zenity-notification-screenshot.png
Binary files differ
diff --git a/help/C/l10n_scripts/notification.sh b/help/C/l10n_scripts/notification.sh
new file mode 100755
index 0000000..b7de9ab
--- /dev/null
+++ b/help/C/l10n_scripts/notification.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+/gnome/head/cvs/zenity/src/zenity --notification \
+--window-icon="info" \
+--text="There are system updates necessary!"
diff --git a/help/C/zenity.xml b/help/C/zenity.xml
index 9d51f70..749a741 100644
--- a/help/C/zenity.xml
+++ b/help/C/zenity.xml
@@ -115,6 +115,7 @@
<listitem><para>Calendar</para></listitem>
<listitem><para>File selection</para></listitem>
<listitem><para>List</para></listitem>
+ <listitem><para>Notification</para></listitem>
<listitem><para>Message</para>
<itemizedlist>
<listitem><para>Error</para></listitem>
@@ -248,7 +249,10 @@
<varlistentry>
<term><option>--window-icon</option>=<replaceable>icon_path</replaceable></term>
<listitem>
- <para>Specifies the icon that is displayed in the window frame of the dialog.</para>
+ <para>Specifies the icon that is displayed in the window frame of the dialog. There are
+ 4 stock icons also available by providing the following keywords - 'info', 'warning', 'question' and
+ 'error'.
+ </para>
</listitem>
</varlistentry>
@@ -435,7 +439,8 @@
<title>File Selection Dialog</title>
<para>
- Use the <option>--file-selection</option> option to create a file selection dialog. &app; returns the selected files or directories to standard error.
+ Use the <option>--file-selection</option> option to create a file selection dialog. &app; returns the selected files or directories to standard
+ error. The default mode of the file selection dialog is open.
</para>
<para>
The file selection dialog supports the following options:
@@ -458,6 +463,20 @@
</varlistentry>
<varlistentry>
+ <term><option>--directory</option></term>
+ <listitem>
+ <para>Allows only selection of directories in the file selection dialog.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><option>--save</option></term>
+ <listitem>
+ <para>Set the file selection dialog into save mode.</para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><option>--separator</option>=<replaceable>separator</replaceable></term>
<listitem>
<para>Specifies the string that is used to divide the returned list of filenames.</para>
@@ -501,6 +520,53 @@
</sect1>
+<!-- ==== Notification Options ====== -->
+ <sect1 id="zenity-notification-options">
+ <title>Notification Icon</title>
+
+ <para>
+ </para>
+
+ <variablelist>
+
+ <varlistentry>
+ <term><option>--text</option>=<replaceable>text</replaceable></term>
+ <listitem>
+ <para>Specifies the text that is displayed in the notification area.</para>
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+
+ <para>
+ The following example script shows how to create a notification icon:
+ <programlisting>
+ #!/bin/sh
+
+ zenity --notification\
+ --window-icon="info" \
+ --text="There are system updates necessary!"
+ </programlisting>
+
+ </para>
+
+ <figure id="zenity-notification-screenshot">
+ <title>Notification Icon Example</title>
+ <screenshot>
+ <mediaobject>
+ <imageobject>
+ <imagedata fileref="figures/zenity-notification-screenshot.png" format="PNG"/>
+ </imageobject>
+ <textobject>
+ <phrase>&app; notification icon example</phrase>
+ </textobject>
+ </mediaobject>
+ </screenshot>
+ </figure>
+
+ </sect1>
+
<!-- ==== List Options ====== -->
<sect1 id="zenity-list-options">
diff --git a/src/Makefile.am b/src/Makefile.am
index c5c9fcd..310cb56 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -12,6 +12,9 @@ zenity_SOURCES = \
text.c \
progress.c \
tree.c \
+ notification.c \
+ eggtrayicon.c \
+ eggtrayicon.h \
about.c \
util.h \
util.c
diff --git a/src/about.c b/src/about.c
index 60cb570..d6fc908 100644
--- a/src/about.c
+++ b/src/about.c
@@ -300,7 +300,7 @@ zenity_create_boutique (void)
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- zenity_util_set_window_icon (window, ZENITY_IMAGE_FULLPATH ("zenity.png"));
+ zenity_util_set_window_icon (window, NULL, ZENITY_IMAGE_FULLPATH ("zenity.png"));
canvas = zenity_create_monk ();
gtk_container_add (GTK_CONTAINER (window), canvas);
@@ -383,7 +383,7 @@ zenity_about (ZenityData *data)
g_signal_connect (G_OBJECT (dialog), "key_press_event",
G_CALLBACK (zenity_zen_wisdom), glade_dialog);
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity.png"));
+ zenity_util_set_window_icon (dialog, NULL, ZENITY_IMAGE_FULLPATH ("zenity.png"));
image = glade_xml_get_widget (glade_dialog, "zenity_about_image");
diff --git a/src/calendar.c b/src/calendar.c
index 5936aef..9da633e 100644
--- a/src/calendar.c
+++ b/src/calendar.c
@@ -58,10 +58,7 @@ zenity_calendar (ZenityData *data, ZenityCalendarData *cal_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-calendar.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-calendar.png"));
if (data->width > -1 || data->height > -1)
gtk_window_set_default_size (GTK_WINDOW (dialog), data->width, data->height);
diff --git a/src/eggtrayicon.c b/src/eggtrayicon.c
new file mode 100644
index 0000000..c4aa3e6
--- /dev/null
+++ b/src/eggtrayicon.c
@@ -0,0 +1,468 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.c
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <libintl.h>
+
+#include "eggtrayicon.h"
+
+#include <gdk/gdkx.h>
+#include <X11/Xatom.h>
+
+#ifndef EGG_COMPILATION
+#ifndef _
+#define _(x) dgettext (GETTEXT_PACKAGE, x)
+#define N_(x) x
+#endif
+#else
+#define _(x) x
+#define N_(x) x
+#endif
+
+#define SYSTEM_TRAY_REQUEST_DOCK 0
+#define SYSTEM_TRAY_BEGIN_MESSAGE 1
+#define SYSTEM_TRAY_CANCEL_MESSAGE 2
+
+#define SYSTEM_TRAY_ORIENTATION_HORZ 0
+#define SYSTEM_TRAY_ORIENTATION_VERT 1
+
+enum {
+ PROP_0,
+ PROP_ORIENTATION
+};
+
+static GtkPlugClass *parent_class = NULL;
+
+static void egg_tray_icon_init (EggTrayIcon *icon);
+static void egg_tray_icon_class_init (EggTrayIconClass *klass);
+
+static void egg_tray_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void egg_tray_icon_realize (GtkWidget *widget);
+static void egg_tray_icon_unrealize (GtkWidget *widget);
+
+static void egg_tray_icon_update_manager_window (EggTrayIcon *icon);
+
+GType
+egg_tray_icon_get_type (void)
+{
+ static GType our_type = 0;
+
+ if (our_type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EggTrayIconClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) egg_tray_icon_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EggTrayIcon),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) egg_tray_icon_init
+ };
+
+ our_type = g_type_register_static (GTK_TYPE_PLUG, "EggTrayIcon", &our_info, 0);
+ }
+
+ return our_type;
+}
+
+static void
+egg_tray_icon_init (EggTrayIcon *icon)
+{
+ icon->stamp = 1;
+ icon->orientation = GTK_ORIENTATION_HORIZONTAL;
+
+ gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
+}
+
+static void
+egg_tray_icon_class_init (EggTrayIconClass *klass)
+{
+ GObjectClass *gobject_class = (GObjectClass *)klass;
+ GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ gobject_class->get_property = egg_tray_icon_get_property;
+
+ widget_class->realize = egg_tray_icon_realize;
+ widget_class->unrealize = egg_tray_icon_unrealize;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ORIENTATION,
+ g_param_spec_enum ("orientation",
+ _("Orientation"),
+ _("The orientation of the tray."),
+ GTK_TYPE_ORIENTATION,
+ GTK_ORIENTATION_HORIZONTAL,
+ G_PARAM_READABLE));
+}
+
+static void
+egg_tray_icon_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EggTrayIcon *icon = EGG_TRAY_ICON (object);
+
+ switch (prop_id)
+ {
+ case PROP_ORIENTATION:
+ g_value_set_enum (value, icon->orientation);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+egg_tray_icon_get_orientation_property (EggTrayIcon *icon)
+{
+ Display *xdisplay;
+ Atom type;
+ int format;
+ union {
+ gulong *prop;
+ guchar *prop_ch;
+ } prop = { NULL };
+ gulong nitems;
+ gulong bytes_after;
+ int error, result;
+
+ g_assert (icon->manager_window != None);
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ gdk_error_trap_push ();
+ type = None;
+ result = XGetWindowProperty (xdisplay,
+ icon->manager_window,
+ icon->orientation_atom,
+ 0, G_MAXLONG, FALSE,
+ XA_CARDINAL,
+ &type, &format, &nitems,
+ &bytes_after, &(prop.prop_ch));
+ error = gdk_error_trap_pop ();
+
+ if (error || result != Success)
+ return;
+
+ if (type == XA_CARDINAL)
+ {
+ GtkOrientation orientation;
+
+ orientation = (prop.prop [0] == SYSTEM_TRAY_ORIENTATION_HORZ) ?
+ GTK_ORIENTATION_HORIZONTAL :
+ GTK_ORIENTATION_VERTICAL;
+
+ if (icon->orientation != orientation)
+ {
+ icon->orientation = orientation;
+
+ g_object_notify (G_OBJECT (icon), "orientation");
+ }
+ }
+
+ if (prop.prop)
+ XFree (prop.prop);
+}
+
+static GdkFilterReturn
+egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_data)
+{
+ EggTrayIcon *icon = user_data;
+ XEvent *xev = (XEvent *)xevent;
+
+ if (xev->xany.type == ClientMessage &&
+ xev->xclient.message_type == icon->manager_atom &&
+ xev->xclient.data.l[1] == icon->selection_atom)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ else if (xev->xany.window == icon->manager_window)
+ {
+ if (xev->xany.type == PropertyNotify &&
+ xev->xproperty.atom == icon->orientation_atom)
+ {
+ egg_tray_icon_get_orientation_property (icon);
+ }
+ if (xev->xany.type == DestroyNotify)
+ {
+ egg_tray_icon_update_manager_window (icon);
+ }
+ }
+
+ return GDK_FILTER_CONTINUE;
+}
+
+static void
+egg_tray_icon_unrealize (GtkWidget *widget)
+{
+ EggTrayIcon *icon = EGG_TRAY_ICON (widget);
+ GdkWindow *root_window;
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (widget),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ root_window = gdk_screen_get_root_window (gtk_widget_get_screen (widget));
+
+ gdk_window_remove_filter (root_window, egg_tray_icon_manager_filter, icon);
+
+ if (GTK_WIDGET_CLASS (parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
+}
+
+static void
+egg_tray_icon_send_manager_message (EggTrayIcon *icon,
+ long message,
+ Window window,
+ long data1,
+ long data2,
+ long data3)
+{
+ XClientMessageEvent ev;
+ Display *display;
+
+ ev.type = ClientMessage;
+ ev.window = window;
+ ev.message_type = icon->system_tray_opcode_atom;
+ ev.format = 32;
+ ev.data.l[0] = gdk_x11_get_server_time (GTK_WIDGET (icon)->window);
+ ev.data.l[1] = message;
+ ev.data.l[2] = data1;
+ ev.data.l[3] = data2;
+ ev.data.l[4] = data3;
+
+ display = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ gdk_error_trap_push ();
+ XSendEvent (display,
+ icon->manager_window, False, NoEventMask, (XEvent *)&ev);
+ XSync (display, False);
+ gdk_error_trap_pop ();
+}
+
+static void
+egg_tray_icon_send_dock_request (EggTrayIcon *icon)
+{
+ egg_tray_icon_send_manager_message (icon,
+ SYSTEM_TRAY_REQUEST_DOCK,
+ icon->manager_window,
+ gtk_plug_get_id (GTK_PLUG (icon)),
+ 0, 0);
+}
+
+static void
+egg_tray_icon_update_manager_window (EggTrayIcon *icon)
+{
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_remove_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+ }
+
+ XGrabServer (xdisplay);
+
+ icon->manager_window = XGetSelectionOwner (xdisplay,
+ icon->selection_atom);
+
+ if (icon->manager_window != None)
+ XSelectInput (xdisplay,
+ icon->manager_window, StructureNotifyMask|PropertyChangeMask);
+
+ XUngrabServer (xdisplay);
+ XFlush (xdisplay);
+
+ if (icon->manager_window != None)
+ {
+ GdkWindow *gdkwin;
+
+ gdkwin = gdk_window_lookup_for_display (gtk_widget_get_display (GTK_WIDGET (icon)),
+ icon->manager_window);
+
+ gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
+
+ /* Send a request that we'd like to dock */
+ egg_tray_icon_send_dock_request (icon);
+
+ egg_tray_icon_get_orientation_property (icon);
+ }
+}
+
+static void
+egg_tray_icon_realize (GtkWidget *widget)
+{
+ EggTrayIcon *icon = EGG_TRAY_ICON (widget);
+ GdkScreen *screen;
+ GdkDisplay *display;
+ Display *xdisplay;
+ char buffer[256];
+ GdkWindow *root_window;
+
+ if (GTK_WIDGET_CLASS (parent_class)->realize)
+ GTK_WIDGET_CLASS (parent_class)->realize (widget);
+
+ screen = gtk_widget_get_screen (widget);
+ display = gdk_screen_get_display (screen);
+ xdisplay = gdk_x11_display_get_xdisplay (display);
+
+ /* Now see if there's a manager window around */
+ g_snprintf (buffer, sizeof (buffer),
+ "_NET_SYSTEM_TRAY_S%d",
+ gdk_screen_get_number (screen));
+
+ icon->selection_atom = XInternAtom (xdisplay, buffer, False);
+
+ icon->manager_atom = XInternAtom (xdisplay, "MANAGER", False);
+
+ icon->system_tray_opcode_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_OPCODE",
+ False);
+
+ icon->orientation_atom = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_ORIENTATION",
+ False);
+
+ egg_tray_icon_update_manager_window (icon);
+
+ root_window = gdk_screen_get_root_window (screen);
+
+ /* Add a root window filter so that we get changes on MANAGER */
+ gdk_window_add_filter (root_window,
+ egg_tray_icon_manager_filter, icon);
+}
+
+EggTrayIcon *
+egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
+{
+ g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ return g_object_new (EGG_TYPE_TRAY_ICON, "screen", screen, "title", name, NULL);
+}
+
+EggTrayIcon*
+egg_tray_icon_new (const gchar *name)
+{
+ return g_object_new (EGG_TYPE_TRAY_ICON, "title", name, NULL);
+}
+
+guint
+egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const gchar *message,
+ gint len)
+{
+ guint stamp;
+
+ g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), 0);
+ g_return_val_if_fail (timeout >= 0, 0);
+ g_return_val_if_fail (message != NULL, 0);
+
+ if (icon->manager_window == None)
+ return 0;
+
+ if (len < 0)
+ len = strlen (message);
+
+ stamp = icon->stamp++;
+
+ /* Get ready to send the message */
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_BEGIN_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ timeout, len, stamp);
+
+ /* Now to send the actual message */
+ gdk_error_trap_push ();
+ while (len > 0)
+ {
+ XClientMessageEvent ev;
+ Display *xdisplay;
+
+ xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
+
+ ev.type = ClientMessage;
+ ev.window = (Window)gtk_plug_get_id (GTK_PLUG (icon));
+ ev.format = 8;
+ ev.message_type = XInternAtom (xdisplay,
+ "_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
+ if (len > 20)
+ {
+ memcpy (&ev.data, message, 20);
+ len -= 20;
+ message += 20;
+ }
+ else
+ {
+ memcpy (&ev.data, message, len);
+ len = 0;
+ }
+
+ XSendEvent (xdisplay,
+ icon->manager_window, False, StructureNotifyMask, (XEvent *)&ev);
+ XSync (xdisplay, False);
+ }
+ gdk_error_trap_pop ();
+
+ return stamp;
+}
+
+void
+egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id)
+{
+ g_return_if_fail (EGG_IS_TRAY_ICON (icon));
+ g_return_if_fail (id > 0);
+
+ egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
+ (Window)gtk_plug_get_id (GTK_PLUG (icon)),
+ id, 0, 0);
+}
+
+GtkOrientation
+egg_tray_icon_get_orientation (EggTrayIcon *icon)
+{
+ g_return_val_if_fail (EGG_IS_TRAY_ICON (icon), GTK_ORIENTATION_HORIZONTAL);
+
+ return icon->orientation;
+}
diff --git a/src/eggtrayicon.h b/src/eggtrayicon.h
new file mode 100644
index 0000000..007f4c1
--- /dev/null
+++ b/src/eggtrayicon.h
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* eggtrayicon.h
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EGG_TRAY_ICON_H__
+#define __EGG_TRAY_ICON_H__
+
+#include <gtk/gtkplug.h>
+#include <gdk/gdkx.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_TRAY_ICON (egg_tray_icon_get_type ())
+#define EGG_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_TRAY_ICON, EggTrayIcon))
+#define EGG_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+#define EGG_IS_TRAY_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_TRAY_ICON))
+#define EGG_IS_TRAY_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_TRAY_ICON))
+#define EGG_TRAY_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_TRAY_ICON, EggTrayIconClass))
+
+typedef struct _EggTrayIcon EggTrayIcon;
+typedef struct _EggTrayIconClass EggTrayIconClass;
+
+struct _EggTrayIcon
+{
+ GtkPlug parent_instance;
+
+ guint stamp;
+
+ Atom selection_atom;
+ Atom manager_atom;
+ Atom system_tray_opcode_atom;
+ Atom orientation_atom;
+ Window manager_window;
+
+ GtkOrientation orientation;
+};
+
+struct _EggTrayIconClass
+{
+ GtkPlugClass parent_class;
+};
+
+GType egg_tray_icon_get_type (void);
+
+EggTrayIcon *egg_tray_icon_new_for_screen (GdkScreen *screen,
+ const gchar *name);
+
+EggTrayIcon *egg_tray_icon_new (const gchar *name);
+
+guint egg_tray_icon_send_message (EggTrayIcon *icon,
+ gint timeout,
+ const char *message,
+ gint len);
+void egg_tray_icon_cancel_message (EggTrayIcon *icon,
+ guint id);
+
+GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon);
+
+G_END_DECLS
+
+#endif /* __EGG_TRAY_ICON_H__ */
diff --git a/src/entry.c b/src/entry.c
index 4d24216..46672f8 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -54,10 +54,7 @@ zenity_entry (ZenityData *data, ZenityEntryData *entry_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-entry.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-entry.png"));
if (data->width > -1 || data->height > -1)
gtk_window_set_default_size (GTK_WINDOW (dialog), data->width, data->height);
diff --git a/src/fileselection.c b/src/fileselection.c
index fdd40fd..4d50fb7 100644
--- a/src/fileselection.c
+++ b/src/fileselection.c
@@ -60,10 +60,7 @@ void zenity_fileselection (ZenityData *data, ZenityFileData *file_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-file.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-file.png"));
if (file_data->uri) {
dir = g_path_get_dirname (file_data->uri);
diff --git a/src/main.c b/src/main.c
index 09b1519..4d8c607 100644
--- a/src/main.c
+++ b/src/main.c
@@ -42,6 +42,7 @@ typedef enum {
MODE_TEXTINFO,
MODE_WARNING,
MODE_INFO,
+ MODE_NOTIFICATION,
MODE_ABOUT,
MODE_LAST
} ZenityDialogMode;
@@ -64,6 +65,7 @@ typedef struct {
ZenityProgressData *progress_data;
ZenityTextData *text_data;
ZenityTreeData *tree_data;
+ ZenityNotificationData *notification_data;
} ZenityParsingOptions;
enum {
@@ -79,6 +81,7 @@ enum {
OPTION_TEXTINFO,
OPTION_TEXTEDIT,
OPTION_WARNING,
+ OPTION_NOTIFICATION,
OPTION_TITLE,
OPTION_ICON,
OPTION_WIDTH,
@@ -110,6 +113,8 @@ enum {
OPTION_PRINTCOLUMN,
OPTION_QUESTIONTEXT,
OPTION_WARNINGTEXT,
+ OPTION_NOTIFICATIONICON,
+ OPTION_NOTIFICATIONTEXT,
OPTION_ABOUT,
OPTION_VERSION,
OPTION_LAST,
@@ -186,6 +191,15 @@ struct poptOption options[] = {
NULL
},
{
+ "notification",
+ '\0',
+ POPT_ARG_NONE,
+ NULL,
+ OPTION_NOTIFICATION,
+ N_("Display notification"),
+ NULL
+ },
+ {
"progress",
'\0',
POPT_ARG_NONE,
@@ -548,6 +562,28 @@ struct poptOption list_options[] = {
POPT_TABLEEND
};
+struct poptOption notification_options[] = {
+ {
+ NULL,
+ '\0',
+ POPT_ARG_CALLBACK | POPT_CBFLAG_POST,
+ zenity_parse_options_callback,
+ 0,
+ NULL,
+ NULL
+ },
+ {
+ "text",
+ '\0',
+ POPT_ARG_STRING,
+ NULL,
+ OPTION_NOTIFICATIONTEXT,
+ N_("Set the notification text"),
+ NULL
+ },
+ POPT_TABLEEND
+};
+
struct poptOption progress_options[] = {
{
NULL,
@@ -900,6 +936,15 @@ struct poptOption application_options[] = {
NULL,
'\0',
POPT_ARG_INCLUDE_TABLE,
+ notification_options,
+ 0,
+ N_("Notication options"),
+ NULL
+ },
+ {
+ NULL,
+ '\0',
+ POPT_ARG_INCLUDE_TABLE,
progress_options,
0,
N_("Progress options"),
@@ -979,6 +1024,7 @@ zenity_init_parsing_options (void) {
results->progress_data = g_new0 (ZenityProgressData, 1);
results->text_data = g_new0 (ZenityTextData, 1);
results->tree_data = g_new0 (ZenityTreeData, 1);
+ results->notification_data = g_new0 (ZenityNotificationData, 1);
/* Give some sensible defaults */
results->data->width = -1;
@@ -1056,6 +1102,10 @@ zenity_free_parsing_options (void) {
if (results->tree_data->print_column)
g_free (results->tree_data->print_column);
break;
+ case MODE_NOTIFICATION:
+ if (results->notification_data->notification_text)
+ g_free (results->notification_data->notification_text);
+ break;
default:
break;
}
@@ -1125,6 +1175,9 @@ main (gint argc, gchar **argv) {
results->tree_data->data = poptGetArgs (ctx);
zenity_tree (results->data, results->tree_data);
break;
+ case MODE_NOTIFICATION:
+ zenity_notification (results->data, results->notification_data);
+ break;
case MODE_PROGRESS:
zenity_progress (results->data, results->progress_data);
break;
@@ -1229,6 +1282,12 @@ zenity_parse_options_callback (poptContext ctx,
results->mode = MODE_LIST;
break;
+ case OPTION_NOTIFICATION:
+ if (results->mode != MODE_LAST)
+ zenity_error (NULL, ERROR_DIALOG);
+
+ results->mode = MODE_NOTIFICATION;
+ break;
case OPTION_PROGRESS:
if (results->mode != MODE_LAST)
zenity_error (NULL, ERROR_DIALOG);
@@ -1286,13 +1345,13 @@ zenity_parse_options_callback (poptContext ctx,
case OPTION_PROGRESSTEXT:
case OPTION_LISTTEXT:
case OPTION_WARNINGTEXT:
-
+ case OPTION_NOTIFICATIONTEXT:
/* FIXME: This is an ugly hack because of the way the poptOptions are
* ordered above. When you try and use an --option more than once
* parse_options_callback gets called for each option. Suckage
*/
- if (parse_option_text > 7)
+ if (parse_option_text > 8)
zenity_error ("--text", ERROR_DUPLICATE);
switch (results->mode) {
@@ -1319,6 +1378,10 @@ zenity_parse_options_callback (poptContext ctx,
results->tree_data->dialog_text = g_locale_to_utf8 (g_strcompress (arg),
-1, NULL, NULL, NULL);
break;
+ case MODE_NOTIFICATION:
+ results->notification_data->notification_text = g_locale_to_utf8 (g_strcompress (arg),
+ -1, NULL, NULL, NULL);
+ break;
default:
zenity_error ("--text", ERROR_SUPPORT);
}
diff --git a/src/msg.c b/src/msg.c
index 2728447..ffb2e53 100644
--- a/src/msg.c
+++ b/src/msg.c
@@ -83,29 +83,25 @@ zenity_msg (ZenityData *data, ZenityMsgData *msg_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else {
- switch (msg_data->mode) {
- case ZENITY_MSG_WARNING:
- zenity_util_set_window_icon_from_stock (dialog, GTK_STOCK_DIALOG_WARNING);
- break;
-
- case ZENITY_MSG_QUESTION:
- zenity_util_set_window_icon_from_stock (dialog, GTK_STOCK_DIALOG_QUESTION);
- break;
+ switch (msg_data->mode) {
+ case ZENITY_MSG_WARNING:
+ zenity_util_set_window_icon_from_stock (dialog, data->window_icon, GTK_STOCK_DIALOG_WARNING);
+ break;
+
+ case ZENITY_MSG_QUESTION:
+ zenity_util_set_window_icon_from_stock (dialog, data->window_icon, GTK_STOCK_DIALOG_QUESTION);
+ break;
- case ZENITY_MSG_ERROR:
- zenity_util_set_window_icon_from_stock (dialog, GTK_STOCK_DIALOG_ERROR);
- break;
+ case ZENITY_MSG_ERROR:
+ zenity_util_set_window_icon_from_stock (dialog, data->window_icon, GTK_STOCK_DIALOG_ERROR);
+ break;
- case ZENITY_MSG_INFO:
- zenity_util_set_window_icon_from_stock (dialog, GTK_STOCK_DIALOG_INFO);
- break;
+ case ZENITY_MSG_INFO:
+ zenity_util_set_window_icon_from_stock (dialog, data->window_icon, GTK_STOCK_DIALOG_INFO);
+ break;
- default:
- break;
- }
+ default:
+ break;
}
if (data->width > -1 || data->height > -1)
diff --git a/src/notification.c b/src/notification.c
new file mode 100644
index 0000000..42f72c5
--- /dev/null
+++ b/src/notification.c
@@ -0,0 +1,129 @@
+/*
+ * notification.c
+ *
+ * Copyright (C) 2002 Sun Microsystems, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Authors: Glynn Foster <glynn.foster@sun.com>
+ */
+
+#include <glade/glade.h>
+#include <time.h>
+#include "zenity.h"
+#include "eggtrayicon.h"
+#include "util.h"
+
+EggTrayIcon *tray_icon;
+
+static gboolean
+zenity_notification_icon_press_callback (GtkWidget *widget, GdkEventButton *event, gpointer data)
+{
+ ZenityData *zen_data;
+
+ zen_data = data;
+
+ zen_data->exit_code = zenity_util_return_exit_code (ZENITY_OK);
+ gtk_main_quit ();
+}
+
+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;
+}
+
+static gboolean
+zenity_notification_icon_destroy_callback (GtkWidget *widget, gpointer data)
+{
+ ZenityData *zen_data;
+
+ zen_data = data;
+ gtk_widget_destroy (GTK_WIDGET (tray_icon));
+
+ zen_data->exit_code = zenity_util_return_exit_code (ZENITY_ESC);
+ gtk_main_quit ();
+}
+
+void
+zenity_notification (ZenityData *data, ZenityNotificationData *notification_data)
+{
+ GtkWidget *icon_image;
+ GtkWidget *icon_event_box;
+ GtkTooltips *tooltips;
+ GdkPixbuf *pixbuf = NULL;
+
+ 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 ();
+
+ if (pixbuf) {
+ icon_image = gtk_image_new_from_pixbuf (pixbuf);
+ gdk_pixbuf_unref (pixbuf);
+ } else {
+ g_warning ("Could not load notification icon : %s", ZENITY_IMAGE_FULLPATH ("zenity-notification.png"));
+ return;
+ }
+
+ 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);
+
+ g_signal_connect (tray_icon, "button_press_event",
+ G_CALLBACK (zenity_notification_icon_press_callback), data);
+
+ 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);
+
+ gtk_widget_show_all (GTK_WIDGET (tray_icon));
+
+ /* Does nothing at the moment */
+ gtk_main ();
+}
diff --git a/src/progress.c b/src/progress.c
index 373c5b8..ed727ca 100644
--- a/src/progress.c
+++ b/src/progress.c
@@ -191,10 +191,7 @@ zenity_progress (ZenityData *data, ZenityProgressData *progress_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-progress.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-progress.png"));
if (data->width > -1 || data->height > -1)
gtk_window_set_default_size (GTK_WINDOW (dialog), data->width, data->height);
diff --git a/src/text.c b/src/text.c
index b70bed0..acd1739 100644
--- a/src/text.c
+++ b/src/text.c
@@ -128,10 +128,7 @@ zenity_text (ZenityData *data, ZenityTextData *text_data)
if (data->dialog_title)
gtk_window_set_title (GTK_WINDOW (dialog), data->dialog_title);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-text.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-text.png"));
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
diff --git a/src/tree.c b/src/tree.c
index fed58e2..436f632 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -320,10 +320,7 @@ zenity_tree (ZenityData *data, ZenityTreeData *tree_data)
if (tree_data->dialog_text)
gtk_label_set_text (GTK_LABEL (text), tree_data->dialog_text);
- if (data->window_icon)
- zenity_util_set_window_icon (dialog, data->window_icon);
- else
- zenity_util_set_window_icon (dialog, ZENITY_IMAGE_FULLPATH ("zenity-list.png"));
+ zenity_util_set_window_icon (dialog, data->window_icon, ZENITY_IMAGE_FULLPATH ("zenity-list.png"));
if (data->width > -1 || data->height > -1)
gtk_window_set_default_size (GTK_WINDOW (dialog), data->width, data->height);
diff --git a/src/util.c b/src/util.c
index 3364e30..b839d42 100644
--- a/src/util.c
+++ b/src/util.c
@@ -143,56 +143,53 @@ zenity_util_fill_file_buffer (GtkTextBuffer *buffer, const gchar *filename)
return TRUE;
}
-static GList *
-zenity_util_list_from_char_array (const char **s)
+GdkPixbuf *
+zenity_util_pixbuf_new_from_file (GtkWidget *widget, gchar *filename)
{
- GList *list = NULL;
- gint i;
-
- for (i = 0; s[i]; i++) {
- GdkPixbuf *pixbuf;
-
- pixbuf = gdk_pixbuf_new_from_file (s[i], NULL);
- if (pixbuf)
- list = g_list_prepend (list, pixbuf);
- }
-
- return list;
-}
-
-static void
-zenity_util_free_list (GList *list)
-{
- g_list_foreach (list, (GFunc) g_object_unref, NULL);
- g_list_free (list);
+ if (!strcmp (g_strdown (filename), "warning"))
+ return gtk_widget_render_icon (widget, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_BUTTON, NULL);
+ if (!strcmp (g_strdown (filename), "info"))
+ return gtk_widget_render_icon (widget, GTK_STOCK_DIALOG_INFO, GTK_ICON_SIZE_BUTTON, NULL);
+ if (!strcmp (g_strdown (filename), "question"))
+ return gtk_widget_render_icon (widget, GTK_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_BUTTON, NULL);
+ if (!strcmp (g_strdown (filename), "error"))
+ return gtk_widget_render_icon (widget, GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_BUTTON, NULL);
+ else
+ return gdk_pixbuf_new_from_file (filename, NULL);
}
void
-zenity_util_set_window_icon (GtkWidget *widget, const gchar *filename)
+zenity_util_set_window_icon (GtkWidget *widget, const gchar *filename, const gchar *default_file)
{
- const gchar *filenames[2] = { NULL};
- GList *list;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_WINDOW (widget));
+ GdkPixbuf *pixbuf;
- if (filename == NULL)
- return;
+ if (filename != NULL)
+ pixbuf = zenity_util_pixbuf_new_from_file (widget, (gchar *) filename);
+ else
+ pixbuf = gdk_pixbuf_new_from_file (default_file, NULL);
- filenames[0] = filename;
- list = zenity_util_list_from_char_array (filenames);
- gtk_window_set_icon_list (GTK_WINDOW (widget), list);
- zenity_util_free_list (list);
+ if (pixbuf != NULL) {
+ gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
+ g_object_unref (pixbuf);
+ }
}
void
-zenity_util_set_window_icon_from_stock (GtkWidget *widget, const gchar *stock_id)
+zenity_util_set_window_icon_from_stock (GtkWidget *widget, const gchar *filename, const gchar *default_stock_id)
{
GdkPixbuf *pixbuf;
-
- pixbuf = gtk_widget_render_icon (widget, stock_id, (GtkIconSize) -1, NULL);
- gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
- g_object_unref (pixbuf);
+
+ if (filename != NULL) {
+ pixbuf = zenity_util_pixbuf_new_from_file (widget, (gchar *) filename);
+ }
+ else {
+ pixbuf = gtk_widget_render_icon (widget, default_stock_id, GTK_ICON_SIZE_BUTTON, NULL);
+ }
+
+ if (pixbuf != NULL) {
+ gtk_window_set_icon (GTK_WINDOW (widget), pixbuf);
+ g_object_unref (pixbuf);
+ }
}
void
diff --git a/src/util.h b/src/util.h
index 69ec912..4e3c214 100644
--- a/src/util.h
+++ b/src/util.h
@@ -15,10 +15,14 @@ GladeXML* zenity_util_load_glade_file (const gchar *widge
gchar * zenity_util_strip_newline (gchar *string);
gboolean zenity_util_fill_file_buffer (GtkTextBuffer *buffer,
const gchar *filename);
-void zenity_util_set_window_icon (GtkWidget *widget,
- const gchar *filename);
+void zenity_util_set_window_icon (GtkWidget *widget,
+ const gchar *filename,
+ const gchar *default_file);
void zenity_util_set_window_icon_from_stock (GtkWidget *widget,
- const gchar *stock_id);
+ const gchar *filename,
+ const gchar *default_stock_id);
+GdkPixbuf * zenity_util_pixbuf_new_from_file (GtkWidget *widget,
+ gchar *filename);
void zenity_util_show_help (GError **error);
gint zenity_util_return_exit_code (ZenityExitCode value);
void zenity_util_show_dialog (GtkWidget *widget);
diff --git a/src/zenity.h b/src/zenity.h
index d9aff43..3d4eeea 100644
--- a/src/zenity.h
+++ b/src/zenity.h
@@ -98,6 +98,10 @@ typedef struct {
const gchar **data;
} ZenityTreeData;
+typedef struct {
+ gchar *notification_text;
+} ZenityNotificationData;
+
void zenity_calendar (ZenityData *data,
ZenityCalendarData *calendar_data);
void zenity_msg (ZenityData *data,
@@ -112,6 +116,8 @@ void zenity_text (ZenityData *data,
ZenityTextData *text_data);
void zenity_tree (ZenityData *data,
ZenityTreeData *tree_data);
+void zenity_notification (ZenityData *data,
+ ZenityNotificationData *notification_data);
void zenity_about (ZenityData *data);
G_END_DECLS