Revision: 5979
Author: ek.kato
Date: Thu Jul 30 23:18:22 2009
Log: * helper/eggtrayicon.c
* helper/eggtrayicon.h
- Support transparent background (from fraxbe, issue #8 on
googlecode).
http://code.google.com/p/uim/source/detail?r=5979
Modified:
/trunk/helper/eggtrayicon.c
/trunk/helper/eggtrayicon.h
=======================================
--- /trunk/helper/eggtrayicon.c Sat May 20 18:31:02 2006
+++ /trunk/helper/eggtrayicon.c Thu Jul 30 23:18:22 2009
@@ -33,6 +33,16 @@
#include <gdk/gdkwin32.h>
#endif
+#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
@@ -44,7 +54,7 @@
PROP_0,
PROP_ORIENTATION
};
-
+
static GtkPlugClass *parent_class = NULL;
static void egg_tray_icon_init (EggTrayIcon *icon);
@@ -58,6 +68,9 @@
static void egg_tray_icon_realize (GtkWidget *widget);
static void egg_tray_icon_unrealize (GtkWidget *widget);
+static void egg_tray_icon_add (GtkContainer *container,
+ GtkWidget *widget);
+
#ifdef GDK_WINDOWING_X11
static void egg_tray_icon_update_manager_window (EggTrayIcon *icon,
gboolean
dock_if_realized);
@@ -95,7 +108,7 @@
{
icon->stamp = 1;
icon->orientation = GTK_ORIENTATION_HORIZONTAL;
-
+
gtk_widget_add_events (GTK_WIDGET (icon), GDK_PROPERTY_CHANGE_MASK);
}
@@ -104,6 +117,7 @@
{
GObjectClass *gobject_class = (GObjectClass *)klass;
GtkWidgetClass *widget_class = (GtkWidgetClass *)klass;
+ GtkContainerClass *container_class = (GtkContainerClass *)klass;
parent_class = g_type_class_peek_parent (klass);
@@ -112,6 +126,8 @@
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",
@@ -166,7 +182,7 @@
int error, result;
g_assert (icon->manager_window != None);
-
+
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET
(icon)));
gdk_error_trap_push ();
@@ -211,7 +227,7 @@
if (xev->xany.type == ClientMessage &&
xev->xclient.message_type == icon->manager_atom &&
- xev->xclient.data.l[1] == (int)icon->selection_atom)
+ xev->xclient.data.l[1] == icon->selection_atom)
{
egg_tray_icon_update_manager_window (icon, TRUE);
}
@@ -230,7 +246,7 @@
return GDK_FILTER_CONTINUE;
}
-#endif
+#endif
static void
egg_tray_icon_unrealize (GtkWidget *widget)
@@ -270,7 +286,7 @@
{
XClientMessageEvent ev;
Display *display;
-
+
ev.type = ClientMessage;
ev.window = window;
ev.message_type = icon->system_tray_opcode_atom;
@@ -282,7 +298,7 @@
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);
@@ -305,14 +321,14 @@
gboolean dock_if_realized)
{
Display *xdisplay;
-
+
if (icon->manager_window != None)
return;
xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (GTK_WIDGET
(icon)));
-
+
XGrabServer (xdisplay);
-
+
icon->manager_window = XGetSelectionOwner (xdisplay,
icon->selection_atom);
@@ -322,14 +338,14 @@
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);
if (dock_if_realized && GTK_WIDGET_REALIZED (icon))
@@ -343,12 +359,12 @@
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;
@@ -357,6 +373,36 @@
}
#endif
+
+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_realize (GtkWidget *widget)
@@ -372,6 +418,8 @@
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);
@@ -382,9 +430,9 @@
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);
@@ -397,12 +445,20 @@
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 *
egg_tray_icon_new_for_screen (GdkScreen *screen, const char *name)
@@ -425,11 +481,11 @@
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);
-
+
#ifdef GDK_WINDOWING_X11
if (icon->manager_window == None)
return 0;
@@ -439,11 +495,11 @@
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)),
+ icon->manager_window,
timeout, len, stamp);
/* Now to send the actual message */
@@ -454,9 +510,9 @@
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.window = icon->manager_window;
ev.format = 8;
ev.message_type = XInternAtom (xdisplay,
"_NET_SYSTEM_TRAY_MESSAGE_DATA", False);
@@ -488,7 +544,7 @@
{
g_return_if_fail (EGG_IS_TRAY_ICON (icon));
g_return_if_fail (id > 0);
-#ifdef GDK_WINDOWING_X11
+#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);
=======================================
--- /trunk/helper/eggtrayicon.h Sat Mar 29 01:44:36 2008
+++ /trunk/helper/eggtrayicon.h Thu Jul 30 23:18:22 2009
@@ -34,7 +34,7 @@
#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;
@@ -43,7 +43,7 @@
GtkPlug parent_instance;
guint stamp;
-
+
#ifdef GDK_WINDOWING_X11
Atom selection_atom;
Atom manager_atom;
@@ -74,7 +74,7 @@
guint id);
GtkOrientation egg_tray_icon_get_orientation (EggTrayIcon *icon);
-
+
G_END_DECLS
#endif /* UIM_EGG_TRAY_ICON_H */