added eggtrayicon from mail-notification.

This should make tray icon transparent for non-
gnome desktops.
This commit is contained in:
Dimitur Kirov 2006-05-16 08:51:48 +00:00
parent 956ae9c34b
commit c4d7ec992a
2 changed files with 139 additions and 49 deletions

View file

@ -1,4 +1,3 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* eggtrayicon.c
* Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
*
@ -18,25 +17,30 @@
* Boston, MA 02111-1307, USA.
*/
//#include <config.h>
#include <string.h>
#include <glib/gi18n.h>
#include <libintl.h>
#include "eggtrayicon.h"
#include <gdkconfig.h>
#if defined (GDK_WINDOWING_X11)
#include <gdk/gdkx.h>
#include <X11/Xatom.h>
#elif defined (GDK_WINDOWING_WIN32)
#include <gdk/gdkwin32.h>
#endif
/*#ifndef EGG_COMPILATION
#ifndef EGG_COMPILATION
#ifndef _
#define _(x) dgettext ('gajim', x)
#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
@ -59,10 +63,16 @@ static void egg_tray_icon_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void egg_tray_icon_add (GtkContainer *container, GtkWidget *widget);
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);
#ifdef GDK_WINDOWING_X11
static void egg_tray_icon_update_manager_window (EggTrayIcon *icon,
gboolean dock_if_realized);
static void egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon);
#endif
GType
egg_tray_icon_get_type (void)
@ -104,6 +114,7 @@ egg_tray_icon_class_init (EggTrayIconClass *klass)
{
GObjectClass *gobject_class = (GObjectClass *)klass;
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
GtkContainerClass *container_class = (GtkContainerClass *)klass;
parent_class = g_type_class_peek_parent (klass);
@ -112,16 +123,24 @@ egg_tray_icon_class_init (EggTrayIconClass *klass)
widget_class->realize = egg_tray_icon_realize;
widget_class->unrealize = egg_tray_icon_unrealize;
container_class->add = egg_tray_icon_add;
g_object_class_install_property (gobject_class,
PROP_ORIENTATION,
g_param_spec_enum ("orientation",
"Orientation",
"The orientation of the tray.",
// _("Orientation"),
// _("The orientation of the tray."),
_("Orientation"),
_("The orientation of the tray."),
GTK_TYPE_ORIENTATION,
GTK_ORIENTATION_HORIZONTAL,
G_PARAM_READABLE));
#if defined (GDK_WINDOWING_X11)
/* Nothing */
#elif defined (GDK_WINDOWING_WIN32)
g_warning ("Port eggtrayicon to Win32");
#else
g_warning ("Port eggtrayicon to this GTK+ backend");
#endif
}
static void
@ -143,6 +162,8 @@ egg_tray_icon_get_property (GObject *object,
}
}
#ifdef GDK_WINDOWING_X11
static void
egg_tray_icon_get_orientation_property (EggTrayIcon *icon)
{
@ -205,7 +226,7 @@ egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_
xev->xclient.message_type == icon->manager_atom &&
xev->xclient.data.l[1] == icon->selection_atom)
{
egg_tray_icon_update_manager_window (icon);
egg_tray_icon_update_manager_window (icon, TRUE);
}
else if (xev->xany.window == icon->manager_window)
{
@ -216,16 +237,18 @@ egg_tray_icon_manager_filter (GdkXEvent *xevent, GdkEvent *event, gpointer user_
}
if (xev->xany.type == DestroyNotify)
{
egg_tray_icon_update_manager_window (icon);
egg_tray_icon_manager_window_destroyed (icon);
}
}
return GDK_FILTER_CONTINUE;
}
#endif
static void
egg_tray_icon_unrealize (GtkWidget *widget)
{
#ifdef GDK_WINDOWING_X11
EggTrayIcon *icon = EGG_TRAY_ICON (widget);
GdkWindow *root_window;
@ -245,8 +268,11 @@ egg_tray_icon_unrealize (GtkWidget *widget)
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
#endif
}
#ifdef GDK_WINDOWING_X11
static void
egg_tray_icon_send_manager_message (EggTrayIcon *icon,
long message,
@ -288,21 +314,15 @@ egg_tray_icon_send_dock_request (EggTrayIcon *icon)
}
static void
egg_tray_icon_update_manager_window (EggTrayIcon *icon)
egg_tray_icon_update_manager_window (EggTrayIcon *icon,
gboolean dock_if_realized)
{
Display *xdisplay;
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
if (icon->manager_window != None)
{
GdkWindow *gdkwin;
return;
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);
}
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET (icon)));
XGrabServer (xdisplay);
@ -325,16 +345,66 @@ egg_tray_icon_update_manager_window (EggTrayIcon *icon)
gdk_window_add_filter (gdkwin, egg_tray_icon_manager_filter, icon);
/* Send a request that we'd like to dock */
if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
egg_tray_icon_send_dock_request (icon);
egg_tray_icon_get_orientation_property (icon);
}
}
static gboolean
transparent_expose_event (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
{
gdk_window_clear_area (widget->window, event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
static void
make_transparent_again (GtkWidget *widget, GtkStyle *previous_style,
gpointer user_data)
{
gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
}
static void
make_transparent (GtkWidget *widget, gpointer user_data)
{
if (GTK_WIDGET_NO_WINDOW (widget) || GTK_WIDGET_APP_PAINTABLE (widget))
return;
gtk_widget_set_app_paintable (widget, TRUE);
gtk_widget_set_double_buffered (widget, FALSE);
gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
g_signal_connect (widget, "expose_event",
G_CALLBACK (transparent_expose_event), NULL);
g_signal_connect_after (widget, "style_set",
G_CALLBACK (make_transparent_again), NULL);
}
static void
egg_tray_icon_manager_window_destroyed (EggTrayIcon *icon)
{
GdkWindow *gdkwin;
g_return_if_fail (icon->manager_window != None);
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);
icon->manager_window = None;
egg_tray_icon_update_manager_window (icon, TRUE);
}
#endif
static void
egg_tray_icon_realize (GtkWidget *widget)
{
#ifdef GDK_WINDOWING_X11
EggTrayIcon *icon = EGG_TRAY_ICON (widget);
GdkScreen *screen;
GdkDisplay *display;
@ -345,6 +415,8 @@ egg_tray_icon_realize (GtkWidget *widget)
if (GTK_WIDGET_CLASS (parent_class)->realize)
GTK_WIDGET_CLASS (parent_class)->realize (widget);
make_transparent (widget, NULL);
screen = gtk_widget_get_screen (widget);
display = gdk_screen_get_display (screen);
xdisplay = gdk_x11_display_get_xdisplay (display);
@ -366,13 +438,23 @@ egg_tray_icon_realize (GtkWidget *widget)
"_NET_SYSTEM_TRAY_ORIENTATION",
False);
egg_tray_icon_update_manager_window (icon);
egg_tray_icon_update_manager_window (icon, FALSE);
egg_tray_icon_send_dock_request (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);
#endif
}
static void
egg_tray_icon_add (GtkContainer *container, GtkWidget *widget)
{
g_signal_connect (widget, "realize",
G_CALLBACK (make_transparent), NULL);
GTK_CONTAINER_CLASS (parent_class)->add (container, widget);
}
EggTrayIcon *
@ -401,14 +483,17 @@ egg_tray_icon_send_message (EggTrayIcon *icon,
g_return_val_if_fail (timeout >= 0, 0);
g_return_val_if_fail (message != NULL, 0);
#ifdef GDK_WINDOWING_X11
if (icon->manager_window == None)
return 0;
#endif
if (len < 0)
len = strlen (message);
stamp = icon->stamp++;
#ifdef GDK_WINDOWING_X11
/* 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)),
@ -445,6 +530,7 @@ egg_tray_icon_send_message (EggTrayIcon *icon,
XSync (xdisplay, False);
}
gdk_error_trap_pop ();
#endif
return stamp;
}
@ -455,10 +541,11 @@ egg_tray_icon_cancel_message (EggTrayIcon *icon,
{
g_return_if_fail (EGG_IS_TRAY_ICON (icon));
g_return_if_fail (id > 0);
#ifdef GDK_WINDOWING_X11
egg_tray_icon_send_manager_message (icon, SYSTEM_TRAY_CANCEL_MESSAGE,
(Window)gtk_plug_get_id (GTK_PLUG (icon)),
id, 0, 0);
#endif
}
GtkOrientation

View file

@ -22,7 +22,9 @@
#define __EGG_TRAY_ICON_H__
#include <gtk/gtkplug.h>
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#endif
G_BEGIN_DECLS
@ -42,12 +44,13 @@ struct _EggTrayIcon
guint stamp;
#ifdef GDK_WINDOWING_X11
Atom selection_atom;
Atom manager_atom;
Atom system_tray_opcode_atom;
Atom orientation_atom;
Window manager_window;
#endif
GtkOrientation orientation;
};