[Xfce4-commits] <xfce4-panel:devel> Support transparent status icon.
Nick Schermer
nick at xfce.org
Tue Aug 11 20:32:24 CEST 2009
Updating branch refs/heads/devel
to 4b2f1f87c598e6a73bb15e2369017df2592d0110 (commit)
from 628471e74812a5b6c290977643eb81e54472b37e (commit)
commit 4b2f1f87c598e6a73bb15e2369017df2592d0110
Author: Nick Schermer <nick at xfce.org>
Date: Fri May 22 21:21:57 2009 +0200
Support transparent status icon.
Use code from the Gnome panel to support transparent tray icon.
plugins/systray/Makefile.am | 4 +-
plugins/systray/systray-box.c | 49 +++++-
plugins/systray/systray-manager.c | 136 +++------------
plugins/systray/systray-manager.h | 24 ++--
plugins/systray/systray-socket.c | 355 +++++++++++++++++++++++++++++++++++++
plugins/systray/systray-socket.h | 53 ++++++
plugins/systray/systray.c | 6 +-
7 files changed, 496 insertions(+), 131 deletions(-)
diff --git a/plugins/systray/Makefile.am b/plugins/systray/Makefile.am
index 4b3ac13..3d2eb60 100644
--- a/plugins/systray/Makefile.am
+++ b/plugins/systray/Makefile.am
@@ -24,7 +24,9 @@ libsystray_la_SOURCES = \
systray-box.c \
systray-box.h \
systray-manager.c \
- systray-manager.h
+ systray-manager.h \
+ systray-socket.c \
+ systray-socket.h
libsystray_la_CFLAGS = \
$(LIBX11_CFLAGS) \
diff --git a/plugins/systray/systray-box.c b/plugins/systray/systray-box.c
index e264e86..2cd3f3c 100644
--- a/plugins/systray/systray-box.c
+++ b/plugins/systray/systray-box.c
@@ -30,6 +30,7 @@
#include <common/panel-private.h>
#include "systray-box.h"
+#include "systray-socket.h"
#define BUTTON_SIZE (16)
#define SPACING (2)
@@ -44,6 +45,8 @@ static void systray_box_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void systray_box_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
+static gboolean systray_box_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
static void systray_box_add (GtkContainer *container,
GtkWidget *child);
static void systray_box_remove (GtkContainer *container,
@@ -132,6 +135,7 @@ systray_box_class_init (SystrayBoxClass *klass)
gtkwidget_class = GTK_WIDGET_CLASS (klass);
gtkwidget_class->size_request = systray_box_size_request;
gtkwidget_class->size_allocate = systray_box_size_allocate;
+ gtkwidget_class->expose_event = systray_box_expose_event;
gtkcontainer_class = GTK_CONTAINER_CLASS (klass);
gtkcontainer_class->add = systray_box_add;
@@ -432,7 +436,50 @@ systray_box_size_allocate (GtkWidget *widget,
/* allocate widget size */
gtk_widget_size_allocate (child_info->widget, &child_allocation);
- }
+ }
+}
+
+
+
+static gboolean
+systray_box_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ SystrayBox *box = XFCE_SYSTRAY_BOX (widget);
+ cairo_t *cr;
+ SystrayBoxChild *child_info;
+ GSList *li;
+ gboolean result;
+
+ result = GTK_WIDGET_CLASS (systray_box_parent_class)->expose_event (widget, event);
+
+ if (gtk_widget_is_composited (widget))
+ {
+ cr = gdk_cairo_create (widget->window);
+ gdk_cairo_region (cr, event->region);
+ cairo_clip (cr);
+
+ for (li = box->childeren; li != NULL; li = li->next)
+ {
+ child_info = li->data;
+
+ /* skip invisible or not composited children */
+ if (child_info->invalid
+ || (child_info->auto_hide && !box->show_hidden)
+ || !systray_socket_is_composited (XFCE_SYSTRAY_SOCKET (child_info->widget)))
+ continue;
+
+ /* paint the child */
+ gdk_cairo_set_source_pixmap (cr, child_info->widget->window,
+ child_info->widget->allocation.x,
+ child_info->widget->allocation.y);
+ cairo_paint (cr);
+ }
+
+ cairo_destroy (cr);
+ }
+
+ return result;
}
diff --git a/plugins/systray/systray-manager.c b/plugins/systray/systray-manager.c
index f7f29c3..c1de20c 100644
--- a/plugins/systray/systray-manager.c
+++ b/plugins/systray/systray-manager.c
@@ -40,6 +40,7 @@
#include <libxfce4util/libxfce4util.h>
#include "systray-manager.h"
+#include "systray-socket.h"
#include "systray-marshal.h"
@@ -139,7 +140,6 @@ struct _SystrayMessage
static guint systray_manager_signals[LAST_SIGNAL];
-static GQuark xwindow_quark = 0;
@@ -202,9 +202,6 @@ systray_manager_class_init (SystrayManagerClass *klass)
0, NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
-
- /* initialize quark */
- xwindow_quark = g_quark_from_static_string ("systray-manager-xwindow");
}
@@ -656,7 +653,8 @@ static void
systray_manager_handle_cancel_message (SystrayManager *manager,
XClientMessageEvent *xevent)
{
- GtkSocket *socket;
+ GtkSocket *socket;
+ GdkNativeWindow window = xevent->data.l[2];
panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
@@ -666,12 +664,10 @@ systray_manager_handle_cancel_message (SystrayManager *manager,
/* try to find the window in the list of known tray icons */
socket = g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (xevent->window));
- if (G_LIKELY (socket))
- {
- /* emit the cancelled signal */
- g_signal_emit (manager, systray_manager_signals[MESSAGE_CANCELLED], 0,
- socket, xevent->data.l[2]);
- }
+ /* emit the cancelled signal */
+ if (G_LIKELY (socket != NULL))
+ g_signal_emit (manager, systray_manager_signals[MESSAGE_CANCELLED],
+ 0, socket, window);
}
@@ -680,66 +676,23 @@ static void
systray_manager_handle_dock_request (SystrayManager *manager,
XClientMessageEvent *xevent)
{
- GtkWidget *socket;
- Window *xwindow;
- XWindowAttributes attr;
- GdkVisual *visual;
- GdkColormap *colormap;
- gint result;
- GdkScreen *screen;
- GdkDisplay *display;
- gboolean release_colormap = FALSE;
+ GtkWidget *socket;
+ GdkScreen *screen;
+ GdkNativeWindow window = xevent->data.l[2];
panel_return_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager));
panel_return_if_fail (GTK_IS_INVISIBLE (manager->invisible));
- /* check if we already have this notification */
- if (g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (xevent->data.l[2])))
+ /* check if we already have this window */
+ if (g_hash_table_lookup (manager->sockets, GUINT_TO_POINTER (window)))
return;
- /* get the window attributes, leave if this fails */
- display = gtk_widget_get_display (manager->invisible);
- gdk_error_trap_push ();
- result = XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (display),
- xevent->data.l[2], &attr);
- if (gdk_error_trap_pop () != 0 || result == 0)
- return;
-
- /* get the windows visual */
+ /* create the socket */
screen = gtk_widget_get_screen (manager->invisible);
- visual = gdk_x11_screen_lookup_visual (screen, attr.visual->visualid);
- if (visual == NULL)
+ socket = systray_socket_new (screen, window);
+ if (G_UNLIKELY (socket == NULL))
return;
- /* get the correct colormap */
- if (visual == gdk_screen_get_rgb_visual (screen))
- colormap = gdk_screen_get_rgb_colormap (screen);
- else if (visual == gdk_screen_get_rgba_visual (screen))
- colormap = gdk_screen_get_rgba_colormap (screen);
- else if (visual == gdk_screen_get_system_visual (screen))
- colormap = gdk_screen_get_system_colormap (screen);
- else
- {
- /* create custom colormap */
- colormap = gdk_colormap_new (visual, FALSE);
- release_colormap = TRUE;
- }
-
- /* create a new socket */
- socket = gtk_socket_new ();
- gtk_widget_set_colormap (GTK_WIDGET (socket), colormap);
-
- /* allocate and set the xwindow */
- xwindow = g_new (Window, 1);
- *xwindow = xevent->data.l[2];
-
- /* release the custom colormap */
- if (release_colormap)
- g_object_unref (G_OBJECT (colormap));
-
- /* connect the xwindow data to the socket */
- g_object_set_qdata_full (G_OBJECT (socket), xwindow_quark, xwindow, g_free);
-
/* add the icon to the tray */
g_signal_emit (manager, systray_manager_signals[ICON_ADDED], 0, socket);
@@ -752,10 +705,10 @@ systray_manager_handle_dock_request (SystrayManager *manager,
G_CALLBACK (systray_manager_handle_undock_request), manager);
/* register the xembed client window id for this socket */
- gtk_socket_add_id (GTK_SOCKET (socket), *xwindow);
+ gtk_socket_add_id (GTK_SOCKET (socket), window);
/* add the socket to the list of known sockets */
- g_hash_table_insert (manager->sockets, GUINT_TO_POINTER (*xwindow), socket);
+ g_hash_table_insert (manager->sockets, GUINT_TO_POINTER (window), socket);
}
else
{
@@ -773,8 +726,8 @@ static gboolean
systray_manager_handle_undock_request (GtkSocket *socket,
gpointer user_data)
{
- SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
- Window *xwindow;
+ SystrayManager *manager = XFCE_SYSTRAY_MANAGER (user_data);
+ GdkNativeWindow *window;
panel_return_val_if_fail (XFCE_IS_SYSTRAY_MANAGER (manager), FALSE);
@@ -782,13 +735,10 @@ systray_manager_handle_undock_request (GtkSocket *socket,
g_signal_emit (manager, systray_manager_signals[ICON_REMOVED], 0, socket);
/* get the xwindow */
- xwindow = g_object_get_qdata (G_OBJECT (socket), xwindow_quark);
+ window = systray_socket_get_window (XFCE_SYSTRAY_SOCKET (socket));
/* remove the socket from the list */
- g_hash_table_remove (manager->sockets, GUINT_TO_POINTER (*xwindow));
-
- /* unset object data */
- g_object_set_qdata (G_OBJECT (socket), xwindow_quark, NULL);
+ g_hash_table_remove (manager->sockets, GUINT_TO_POINTER (*window));
/* destroy the socket */
return FALSE;
@@ -881,50 +831,6 @@ systray_manager_set_orientation (SystrayManager *manager,
-gchar *
-systray_manager_get_application_name (GtkWidget *socket)
-{
- gchar *name = NULL;
- GdkDisplay *display;
- gint succeed;
- XTextProperty xprop;
- Window *xwindow;
-
- /* get the xwindow */
- xwindow = g_object_get_qdata (G_OBJECT (socket), xwindow_quark);
-
- if (G_LIKELY (xwindow != NULL))
- {
- /* get the display of the socket */
- display = gtk_widget_get_display (socket);
-
- /* avoid exiting the application on X errors */
- gdk_error_trap_push ();
-
- /* try to get the wm name (this is more relaiable with qt applications) */
- succeed = XGetWMName (GDK_DISPLAY_XDISPLAY (display), *xwindow, &xprop);
-
- /* check if everything went fine */
- if (G_LIKELY (gdk_error_trap_pop () == 0 && succeed >= Success))
- {
- /* check the xprop content */
- if (G_LIKELY (xprop.value && xprop.nitems > 0))
- {
- /* get the lowercase name if it's utf-8 valid */
- if (G_LIKELY (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL)))
- name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
-
- /* cleanup */
- XFree (xprop.value);
- }
- }
- }
-
- return name;
-}
-
-
-
/**
* tray messages
**/
diff --git a/plugins/systray/systray-manager.h b/plugins/systray/systray-manager.h
index 455761f..aaec6b2 100644
--- a/plugins/systray/systray-manager.h
+++ b/plugins/systray/systray-manager.h
@@ -47,26 +47,26 @@ enum
-GType systray_manager_get_type (void) G_GNUC_CONST;
+GType systray_manager_get_type (void) G_GNUC_CONST;
-void systray_manager_register_type (GTypeModule *type_module);
+void systray_manager_register_type (GTypeModule *type_module);
-GQuark systray_manager_error_quark (void);
+GQuark systray_manager_error_quark (void);
-SystrayManager *systray_manager_new (void) G_GNUC_MALLOC;
+SystrayManager *systray_manager_new (void) G_GNUC_MALLOC;
-gboolean systray_manager_check_running (GdkScreen *screen);
+gboolean systray_manager_check_running (GdkScreen *screen);
-gboolean systray_manager_register (SystrayManager *manager,
- GdkScreen *screen,
- GError **error);
+gboolean systray_manager_register (SystrayManager *manager,
+ GdkScreen *screen,
+ GError **error);
-void systray_manager_unregister (SystrayManager *manager);
+void systray_manager_unregister (SystrayManager *manager);
-void systray_manager_set_orientation (SystrayManager *manager,
- GtkOrientation orientation);
+void systray_manager_set_orientation (SystrayManager *manager,
+ GtkOrientation orientation);
-gchar *systray_manager_get_application_name (GtkWidget *socket) G_GNUC_MALLOC;
+gchar *systray_manager_get_application_name (GtkWidget *socket) G_GNUC_MALLOC;
#endif /* !__SYSTRAY_MANAGER_H__ */
diff --git a/plugins/systray/systray-socket.c b/plugins/systray/systray-socket.c
new file mode 100644
index 0000000..d942fd0
--- /dev/null
+++ b/plugins/systray/systray-socket.c
@@ -0,0 +1,355 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2002 Anders Carlsson <andersca at gnu.org>
+ * Copyright (c) 2003-2006 Vincent Untz
+ * Copyright (c) 2008 Red Hat, Inc.
+ * Copyright (c) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+#include <gtk/gtk.h>
+
+#include <libxfce4panel/libxfce4panel.h>
+#include "systray-socket.h"
+
+
+
+struct _SystraySocketClass
+{
+ GtkSocketClass __parent__;
+};
+
+struct _SystraySocket
+{
+ GtkSocket __parent__;
+
+ /* plug window */
+ GdkNativeWindow window;
+
+ guint is_composited : 1;
+ guint parent_relative_bg : 1;
+};
+
+
+
+static void systray_socket_realize (GtkWidget *widget);
+static void systray_socket_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean systray_socket_expose_event (GtkWidget *widget,
+ GdkEventExpose *event);
+static void systray_socket_style_set (GtkWidget *widget,
+ GtkStyle *previous_style);
+
+
+
+XFCE_PANEL_DEFINE_TYPE (SystraySocket, systray_socket, GTK_TYPE_SOCKET)
+
+
+
+static void
+systray_socket_class_init (SystraySocketClass *klass)
+{
+ GtkWidgetClass *gtkwidget_class;
+
+ gtkwidget_class = GTK_WIDGET_CLASS (klass);
+ gtkwidget_class->realize = systray_socket_realize;
+ gtkwidget_class->size_allocate = systray_socket_size_allocate;
+ gtkwidget_class->expose_event = systray_socket_expose_event;
+ gtkwidget_class->style_set = systray_socket_style_set;
+}
+
+
+
+static void
+systray_socket_init (SystraySocket *socket)
+{
+}
+
+
+
+static void
+systray_socket_realize (GtkWidget *widget)
+{
+ SystraySocket *socket = XFCE_SYSTRAY_SOCKET (widget);
+ GdkVisual *visual;
+ GdkColor transparent = { 0, 0, 0, 0 };
+
+ GTK_WIDGET_CLASS (systray_socket_parent_class)->realize (widget);
+
+ visual = gtk_widget_get_visual (widget);
+ if (visual->red_prec + visual->blue_prec + visual->green_prec < visual->depth
+ && gdk_display_supports_composite (gtk_widget_get_display (widget)))
+ {
+ gdk_window_set_background (widget->window, &transparent);
+ gdk_window_set_composited (widget->window, TRUE);
+
+ socket->is_composited = TRUE;
+ socket->parent_relative_bg = FALSE;
+ }
+ else if (visual == gdk_drawable_get_visual (
+ GDK_DRAWABLE (gdk_window_get_parent (widget->window))))
+ {
+ gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
+
+ socket->is_composited = FALSE;
+ socket->parent_relative_bg = TRUE;
+ }
+ else
+ {
+ socket->is_composited = FALSE;
+ socket->parent_relative_bg = FALSE;
+ }
+
+ gtk_widget_set_app_paintable (widget,
+ socket->parent_relative_bg || socket->is_composited);
+
+ gtk_widget_set_double_buffered (widget, socket->parent_relative_bg);
+}
+
+
+
+static void
+systray_socket_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ SystraySocket *socket = XFCE_SYSTRAY_SOCKET (widget);
+ gboolean moved = allocation->x != widget->allocation.x
+ || allocation->y != widget->allocation.y;
+ gboolean resized = allocation->width != widget->allocation.width
+ ||allocation->height != widget->allocation.height;
+
+ if ((moved || resized) && GTK_WIDGET_MAPPED (widget))
+ {
+ if (socket->is_composited)
+ gdk_window_invalidate_rect (gdk_window_get_parent (widget->window),
+ &widget->allocation, FALSE);
+ }
+
+ GTK_WIDGET_CLASS (systray_socket_parent_class)->size_allocate (widget, allocation);
+
+ if ((moved || resized) && GTK_WIDGET_MAPPED (widget))
+ {
+ if (socket->is_composited)
+ gdk_window_invalidate_rect (gdk_window_get_parent (widget->window),
+ &widget->allocation, FALSE);
+ else if (moved && socket->parent_relative_bg)
+ systray_socket_force_redraw (socket);
+ }
+}
+
+
+static gboolean
+systray_socket_expose_event (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ SystraySocket *socket = XFCE_SYSTRAY_SOCKET (widget);
+ cairo_t *cr;
+
+ if (socket->is_composited)
+ {
+ /* clear to transparent */
+ cr = gdk_cairo_create (widget->window);
+ cairo_set_source_rgba (cr, 0, 0, 0, 0);
+ cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+ gdk_cairo_region (cr, event->region);
+ cairo_fill (cr);
+ cairo_destroy (cr);
+ }
+ else if (socket->parent_relative_bg)
+ {
+ /* clear to parent-relative pixmap */
+ gdk_window_clear_area (widget->window,
+ event->area.x,
+ event->area.y,
+ event->area.width,
+ event->area.height);
+ }
+
+ return FALSE;
+}
+
+
+
+static void
+systray_socket_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+}
+
+
+
+GtkWidget *
+systray_socket_new (GdkScreen *screen,
+ GdkNativeWindow window)
+{
+ SystraySocket *socket;
+ GdkDisplay *display;
+ XWindowAttributes attr;
+ gint result;
+ GdkVisual *visual;
+ GdkColormap *colormap;
+ gboolean release_colormap = FALSE;
+
+ panel_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+ /* get the window attributes */
+ display = gdk_screen_get_display (screen);
+ gdk_error_trap_push ();
+ result = XGetWindowAttributes (GDK_DISPLAY_XDISPLAY (display),
+ window, &attr);
+
+ /* leave on an error or is the window does not exist */
+ if (gdk_error_trap_pop () != 0 || result == 0)
+ return NULL;
+
+ /* get the windows visual */
+ visual = gdk_x11_screen_lookup_visual (screen, attr.visual->visualid);
+ if (G_UNLIKELY (visual == NULL))
+ return NULL;
+
+ /* get the correct colormap */
+ if (visual == gdk_screen_get_rgb_visual (screen))
+ colormap = gdk_screen_get_rgb_colormap (screen);
+ else if (visual == gdk_screen_get_rgba_visual (screen))
+ colormap = gdk_screen_get_rgba_colormap (screen);
+ else if (visual == gdk_screen_get_system_visual (screen))
+ colormap = gdk_screen_get_system_colormap (screen);
+ else
+ {
+ /* create custom colormap */
+ colormap = gdk_colormap_new (visual, FALSE);
+ release_colormap = TRUE;
+ }
+
+ /* create a new socket */
+ socket = g_object_new (XFCE_TYPE_SYSTRAY_SOCKET, NULL);
+ gtk_widget_set_colormap (GTK_WIDGET (socket), colormap);
+ socket->window = window;
+
+ /* release the custom colormap */
+ if (release_colormap)
+ g_object_unref (G_OBJECT (colormap));
+
+ return GTK_WIDGET (socket);
+}
+
+
+
+void
+systray_socket_force_redraw (SystraySocket *socket)
+{
+ GtkWidget *widget = GTK_WIDGET (socket);
+ XEvent xev;
+ GdkDisplay *display;
+
+ panel_return_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket));
+
+ if (GTK_WIDGET_MAPPED (socket) && socket->parent_relative_bg)
+ {
+ display = gtk_widget_get_display (widget);
+
+ xev.xexpose.type = Expose;
+ xev.xexpose.window = GDK_WINDOW_XWINDOW (GTK_SOCKET (socket)->plug_window);
+ xev.xexpose.x = 0;
+ xev.xexpose.y = 0;
+ xev.xexpose.width = widget->allocation.width;
+ xev.xexpose.height = widget->allocation.height;
+ xev.xexpose.count = 0;
+
+ gdk_error_trap_push ();
+ XSendEvent (GDK_DISPLAY_XDISPLAY (display),
+ xev.xexpose.window,
+ False, ExposureMask,
+ &xev);
+ /* We have to sync to reliably catch errors from the XSendEvent(),
+ * since that is asynchronous.
+ */
+ XSync (GDK_DISPLAY_XDISPLAY (display), False);
+ gdk_error_trap_pop ();
+ }
+}
+
+
+
+gboolean
+systray_socket_is_composited (SystraySocket *socket)
+{
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket), FALSE);
+
+ return socket->is_composited;
+}
+
+
+
+gchar *
+systray_socket_get_title (SystraySocket *socket)
+{
+ gchar *name = NULL;
+ GdkDisplay *display;
+ gint succeed;
+ XTextProperty xprop;
+
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket), NULL);
+
+ /* get the display of the socket */
+ display = gtk_widget_get_display (GTK_WIDGET (socket));
+
+ /* avoid exiting the application on X errors */
+ gdk_error_trap_push ();
+
+ /* try to get the wm name (this is more relaiable with qt applications) */
+ succeed = XGetWMName (GDK_DISPLAY_XDISPLAY (display), socket->window, &xprop);
+
+ /* check if everything went fine */
+ if (G_LIKELY (gdk_error_trap_pop () == 0 && succeed >= Success))
+ {
+ /* check the xprop content */
+ if (G_LIKELY (xprop.value && xprop.nitems > 0))
+ {
+ /* get the lowercase name if it's utf-8 valid */
+ if (g_utf8_validate ((const gchar *) xprop.value, xprop.nitems, NULL))
+ name = g_utf8_strdown ((const gchar *) xprop.value, xprop.nitems);
+
+ /* cleanup */
+ XFree (xprop.value);
+ }
+ }
+
+ return name;
+}
+
+
+
+GdkNativeWindow *
+systray_socket_get_window (SystraySocket *socket)
+{
+ panel_return_val_if_fail (XFCE_IS_SYSTRAY_SOCKET (socket), NULL);
+
+ return &socket->window;
+}
diff --git a/plugins/systray/systray-socket.h b/plugins/systray/systray-socket.h
new file mode 100644
index 0000000..942df6d
--- /dev/null
+++ b/plugins/systray/systray-socket.h
@@ -0,0 +1,53 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2002 Anders Carlsson <andersca at gnu.org>
+ * Copyright (c) 2003-2006 Vincent Untz
+ * Copyright (c) 2008 Red Hat, Inc.
+ * Copyright (c) 2009 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program 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 General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __SYSTRAY_SOCKET_H__
+#define __SYSTRAY_SOCKET_H__
+
+#include <gtk/gtk.h>
+
+typedef struct _SystraySocketClass SystraySocketClass;
+typedef struct _SystraySocket SystraySocket;
+
+#define XFCE_TYPE_SYSTRAY_SOCKET (systray_socket_get_type ())
+#define XFCE_SYSTRAY_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), XFCE_TYPE_SYSTRAY_SOCKET, SystraySocket))
+#define XFCE_SYSTRAY_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), XFCE_TYPE_SYSTRAY_SOCKET, SystraySocketClass))
+#define XFCE_IS_SYSTRAY_SOCKET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), XFCE_TYPE_SYSTRAY_SOCKET))
+#define XFCE_IS_SYSTRAY_SOCKET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), XFCE_TYPE_SYSTRAY_SOCKET))
+#define XFCE_SYSTRAY_SOCKET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), XFCE_TYPE_SYSTRAY_SOCKET, SystraySocketClass))
+
+GType systray_socket_get_type (void) G_GNUC_CONST;
+
+void systray_socket_register_type (GTypeModule *type_module);
+
+GtkWidget *systray_socket_new (GdkScreen *screen,
+ GdkNativeWindow window) G_GNUC_MALLOC;
+
+void systray_socket_force_redraw (SystraySocket *socket);
+
+gboolean systray_socket_is_composited (SystraySocket *socket);
+
+gchar *systray_socket_get_title (SystraySocket *socket) G_GNUC_MALLOC;
+
+GdkNativeWindow *systray_socket_get_window (SystraySocket *socket);
+
+#endif /* !__SYSTRAY_SOCKET_H__ */
diff --git a/plugins/systray/systray.c b/plugins/systray/systray.c
index bdbac93..9774016 100644
--- a/plugins/systray/systray.c
+++ b/plugins/systray/systray.c
@@ -30,6 +30,7 @@
#include "systray.h"
#include "systray-box.h"
+#include "systray-socket.h"
#include "systray-manager.h"
#include "systray-dialog_glade.h"
@@ -102,7 +103,8 @@ enum
/* define the plugin */
XFCE_PANEL_DEFINE_PLUGIN (SystrayPlugin, systray_plugin,
systray_box_register_type,
- systray_manager_register_type)
+ systray_manager_register_type,
+ systray_socket_register_type)
@@ -512,7 +514,7 @@ systray_plugin_icon_added (SystrayManager *manager,
panel_return_if_fail (GTK_IS_WIDGET (icon));
/* get the application name */
- name = systray_manager_get_application_name (icon);
+ name = systray_socket_get_title (XFCE_SYSTRAY_SOCKET (icon));
/* add the icon to the widget */
systray_box_add_with_name (XFCE_SYSTRAY_BOX (plugin->box), icon, name);
More information about the Xfce4-commits
mailing list