Add new notification icon. Update for new files. Restructure code a little

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.
This commit is contained in:
Glynn Foster 2004-09-13 07:51:51 +00:00 committed by Glynn Foster
parent 03f3e5b060
commit 3e05834b4c
23 changed files with 917 additions and 91 deletions

View File

@ -1,3 +1,18 @@
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

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 898 B

View File

@ -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
@ -152,6 +155,13 @@ Allow changes to text
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
@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1,5 @@
#!/bin/sh
/gnome/head/cvs/zenity/src/zenity --notification \
--window-icon="info" \
--text="There are system updates necessary!"

View File

@ -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:
@ -457,6 +462,20 @@
</listitem>
</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>
@ -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">

View File

@ -12,6 +12,9 @@ zenity_SOURCES = \
text.c \
progress.c \
tree.c \
notification.c \
eggtrayicon.c \
eggtrayicon.h \
about.c \
util.h \
util.c

View File

@ -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");

View File

@ -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);

468
src/eggtrayicon.c Normal file
View File

@ -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;
}

77
src/eggtrayicon.h Normal file
View File

@ -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__ */

View File

@ -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);

View File

@ -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);

View File

@ -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,
@ -185,6 +190,15 @@ struct poptOption options[] = {
N_("Display list dialog"),
NULL
},
{
"notification",
'\0',
POPT_ARG_NONE,
NULL,
OPTION_NOTIFICATION,
N_("Display notification"),
NULL
},
{
"progress",
'\0',
@ -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,
@ -896,6 +932,15 @@ struct poptOption application_options[] = {
N_("List options"),
NULL
},
{
NULL,
'\0',
POPT_ARG_INCLUDE_TABLE,
notification_options,
0,
N_("Notication options"),
NULL
},
{
NULL,
'\0',
@ -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);
}

View File

@ -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;
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, GTK_STOCK_DIALOG_QUESTION);
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)

129
src/notification.c Normal file
View File

@ -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 ();
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
GdkPixbuf *pixbuf;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_WINDOW (widget));
if (filename != NULL)
pixbuf = zenity_util_pixbuf_new_from_file (widget, (gchar *) filename);
else
pixbuf = gdk_pixbuf_new_from_file (default_file, NULL);
if (filename == NULL)
return;
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

View File

@ -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);

View File

@ -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