sharkcz / rpms / gdm

Forked from rpms/gdm 4 years ago
Clone
9fbd83d
From f304eec1bf7dd80e255092b3cdaade10827fd320 Mon Sep 17 00:00:00 2001
9fbd83d
From: Ray Strode <rstrode@redhat.com>
9fbd83d
Date: Thu, 22 Oct 2009 22:02:51 -0400
9fbd83d
Subject: [PATCH 1/4] Update na-tray to latest upstream code
9fbd83d
9fbd83d
It's a copy and paste from the panel.
9fbd83d
---
9fbd83d
 gui/simple-greeter/libnotificationarea/Makefile.am |    2 +
9fbd83d
 gui/simple-greeter/libnotificationarea/fixedtip.c  |    1 +
9fbd83d
 .../libnotificationarea/na-tray-child.c            |  430 ++++++++++++++++++++
9fbd83d
 .../libnotificationarea/na-tray-child.h            |   68 +++
9fbd83d
 .../libnotificationarea/na-tray-manager.c          |  264 +++++--------
9fbd83d
 .../libnotificationarea/na-tray-manager.h          |   15 +-
9fbd83d
 gui/simple-greeter/libnotificationarea/na-tray.c   |   76 +++-
9fbd83d
 gui/simple-greeter/libnotificationarea/na-tray.h   |    3 +-
9fbd83d
 gui/simple-greeter/libnotificationarea/testtray.c  |    2 +-
9fbd83d
 9 files changed, 674 insertions(+), 187 deletions(-)
9fbd83d
 create mode 100644 gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
 create mode 100644 gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/Makefile.am b/gui/simple-greeter/libnotificationarea/Makefile.am
9fbd83d
index e3a6a1f..4009aaf 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/Makefile.am
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/Makefile.am
9fbd83d
@@ -29,6 +29,8 @@ libnotificationarea_la_SOURCES =		\
9fbd83d
 	obox.h					\
9fbd83d
 	na-tray.c				\
9fbd83d
 	na-tray.h				\
9fbd83d
+	na-tray-child.c				\
9fbd83d
+	na-tray-child.h				\
9fbd83d
 	na-tray-manager.c			\
9fbd83d
 	na-tray-manager.h			\
9fbd83d
 	na-marshal.c				\
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/fixedtip.c b/gui/simple-greeter/libnotificationarea/fixedtip.c
9fbd83d
index cc90e26..53ac923 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/fixedtip.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/fixedtip.c
9fbd83d
@@ -81,6 +81,7 @@ na_fixed_tip_class_init (NaFixedTipClass *class)
9fbd83d
   g_type_class_add_private (class, sizeof (NaFixedTipPrivate));
9fbd83d
 }
9fbd83d
 
9fbd83d
+/* Did you already see this code? Yes, it's gtk_tooltips_ force_window() ;-) */
9fbd83d
 static void
9fbd83d
 na_fixed_tip_init (NaFixedTip *fixedtip)
9fbd83d
 {
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.c b/gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
new file mode 100644
9fbd83d
index 0000000..c7e3f61
9fbd83d
--- /dev/null
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
@@ -0,0 +1,430 @@
9fbd83d
+/* na-tray-child.c
9fbd83d
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
9fbd83d
+ * Copyright (C) 2003-2006 Vincent Untz
9fbd83d
+ * Copyright (C) 2008 Red Hat, Inc.
9fbd83d
+ *
9fbd83d
+ * This library is free software; you can redistribute it and/or
9fbd83d
+ * modify it under the terms of the GNU Lesser General Public
9fbd83d
+ * License as published by the Free Software Foundation; either
9fbd83d
+ * version 2 of the License, or (at your option) any later version.
9fbd83d
+ *
9fbd83d
+ * This library is distributed in the hope that it will be useful,
9fbd83d
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9fbd83d
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9fbd83d
+ * Lesser General Public License for more details.
9fbd83d
+ *
9fbd83d
+ * You should have received a copy of the GNU Lesser General Public
9fbd83d
+ * License along with this library; if not, write to the
9fbd83d
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
9fbd83d
+ * Boston, MA 02111-1307, USA.
9fbd83d
+ */
9fbd83d
+
9fbd83d
+#include <config.h>
9fbd83d
+#include <string.h>
9fbd83d
+
9fbd83d
+#include "na-tray-child.h"
9fbd83d
+
9fbd83d
+#include <glib/gi18n.h>
9fbd83d
+#include <gdk/gdk.h>
9fbd83d
+#include <gdk/gdkx.h>
9fbd83d
+#include <X11/Xatom.h>
9fbd83d
+
9fbd83d
+G_DEFINE_TYPE (NaTrayChild, na_tray_child, GTK_TYPE_SOCKET)
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_finalize (GObject *object)
9fbd83d
+{
9fbd83d
+  G_OBJECT_CLASS (na_tray_child_parent_class)->finalize (object);
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_realize (GtkWidget *widget)
9fbd83d
+{
9fbd83d
+  NaTrayChild *child = NA_TRAY_CHILD (widget);
9fbd83d
+  GdkVisual *visual = gtk_widget_get_visual (widget);
9fbd83d
+
9fbd83d
+  GTK_WIDGET_CLASS (na_tray_child_parent_class)->realize (widget);
9fbd83d
+
9fbd83d
+  if (child->has_alpha)
9fbd83d
+    {
9fbd83d
+      /* We have real transparency with an ARGB visual and the Composite
9fbd83d
+       * extension. */
9fbd83d
+
9fbd83d
+      /* Set a transparent background */
9fbd83d
+      GdkColor transparent = { 0, 0, 0, 0 }; /* only pixel=0 matters */
9fbd83d
+      gdk_window_set_background (widget->window, &transparent);
9fbd83d
+      gdk_window_set_composited (widget->window, TRUE);
9fbd83d
+
9fbd83d
+      child->parent_relative_bg = FALSE;
9fbd83d
+    }
9fbd83d
+  else if (visual == gdk_drawable_get_visual (GDK_DRAWABLE (gdk_window_get_parent (widget->window))))
9fbd83d
+    {
9fbd83d
+      /* Otherwise, if the visual matches the visual of the parent window, we
9fbd83d
+       * can use a parent-relative background and fake transparency. */
9fbd83d
+      gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
9fbd83d
+
9fbd83d
+      child->parent_relative_bg = TRUE;
9fbd83d
+    }
9fbd83d
+  else
9fbd83d
+    {
9fbd83d
+      /* Nothing to do; the icon will sit on top of an ugly gray box */
9fbd83d
+      child->parent_relative_bg = FALSE;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  gdk_window_set_composited (widget->window, child->composited);
9fbd83d
+
9fbd83d
+  gtk_widget_set_app_paintable (GTK_WIDGET (child),
9fbd83d
+                                child->parent_relative_bg || child->has_alpha);
9fbd83d
+
9fbd83d
+  /* Double-buffering will interfere with the parent-relative-background fake
9fbd83d
+   * transparency, since the double-buffer code doesn't know how to fill in the
9fbd83d
+   * background of the double-buffer correctly.
9fbd83d
+   */
9fbd83d
+  gtk_widget_set_double_buffered (GTK_WIDGET (child),
9fbd83d
+                                  child->parent_relative_bg);
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_style_set (GtkWidget *widget,
9fbd83d
+                         GtkStyle  *previous_style)
9fbd83d
+{
9fbd83d
+  /* The default handler resets the background according to the new style.
9fbd83d
+   * We either use a transparent background or a parent-relative background
9fbd83d
+   * and ignore the style background. So, just don't chain up.
9fbd83d
+   */
9fbd83d
+}
9fbd83d
+
9fbd83d
+#if 0
9fbd83d
+/* This is adapted from code that was commented out in na-tray-manager.c; the
9fbd83d
+ * code in na-tray-manager.c wouldn't have worked reliably, this will. So maybe
9fbd83d
+ * it can be reenabled. On other hand, things seem to be working fine without
9fbd83d
+ * it.
9fbd83d
+ *
9fbd83d
+ * If reenabling, you need to hook it up in na_tray_child_class_init().
9fbd83d
+ */
9fbd83d
+static void
9fbd83d
+na_tray_child_size_request (GtkWidget      *widget,
9fbd83d
+                            GtkRequisition *request)
9fbd83d
+{
9fbd83d
+  GTK_WIDGET_CLASS (na_tray_child_parent_class)->size_request (widget, request);
9fbd83d
+
9fbd83d
+  /*
9fbd83d
+   * Make sure the icons have a meaningful size ..
9fbd83d
+   */ 
9fbd83d
+  if ((request->width < 16) || (request->height < 16))
9fbd83d
+    {
9fbd83d
+      gint nw = MAX (24, request->width);
9fbd83d
+      gint nh = MAX (24, request->height);
9fbd83d
+      g_warning ("Tray icon has requested a size of (%ix%i), resizing to (%ix%i)", 
9fbd83d
+                 req.width, req.height, nw, nh);
9fbd83d
+      request->width = nw;
9fbd83d
+      request->height = nh;
9fbd83d
+    }
9fbd83d
+}
9fbd83d
+#endif
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_size_allocate (GtkWidget      *widget,
9fbd83d
+                             GtkAllocation  *allocation)
9fbd83d
+{
9fbd83d
+  NaTrayChild *child = NA_TRAY_CHILD (widget);
9fbd83d
+
9fbd83d
+  gboolean moved = allocation->x != widget->allocation.x ||
9fbd83d
+                   allocation->y != widget->allocation.y;
9fbd83d
+  gboolean resized = allocation->width != widget->allocation.width ||
9fbd83d
+                     allocation->height != widget->allocation.height;
9fbd83d
+
9fbd83d
+  /* When we are allocating the widget while mapped we need special handling
9fbd83d
+   * for both real and fake transparency.
9fbd83d
+   *
9fbd83d
+   * Real transparency: we need to invalidate and trigger a redraw of the old
9fbd83d
+   *   and new areas. (GDK really should handle this for us, but doesn't as of
9fbd83d
+   *   GTK+-2.14)
9fbd83d
+   *
9fbd83d
+   * Fake transparency: if the widget moved, we need to force the contents to
9fbd83d
+   *   be redrawn with the new offset for the parent-relative background.
9fbd83d
+   */
9fbd83d
+  if ((moved || resized) && GTK_WIDGET_MAPPED (widget))
9fbd83d
+    {
9fbd83d
+      if (na_tray_child_has_alpha (child))
9fbd83d
+        gdk_window_invalidate_rect (gdk_window_get_parent (widget->window),
9fbd83d
+                                    &widget->allocation, FALSE);
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  GTK_WIDGET_CLASS (na_tray_child_parent_class)->size_allocate (widget,
9fbd83d
+                                                                allocation);
9fbd83d
+
9fbd83d
+  if ((moved || resized) && GTK_WIDGET_MAPPED (widget))
9fbd83d
+    {
9fbd83d
+      if (na_tray_child_has_alpha (NA_TRAY_CHILD (widget)))
9fbd83d
+        gdk_window_invalidate_rect (gdk_window_get_parent (widget->window),
9fbd83d
+                                    &widget->allocation, FALSE);
9fbd83d
+      else if (moved && child->parent_relative_bg)
9fbd83d
+        na_tray_child_force_redraw (child);
9fbd83d
+    }
9fbd83d
+}
9fbd83d
+
9fbd83d
+/* The plug window should completely occupy the area of the child, so we won't
9fbd83d
+ * get an expose event. But in case we do (the plug unmaps itself, say), this
9fbd83d
+ * expose handler draws with real or fake transparency.
9fbd83d
+ */
9fbd83d
+static gboolean
9fbd83d
+na_tray_child_expose_event (GtkWidget      *widget,
9fbd83d
+                            GdkEventExpose *event)
9fbd83d
+{
9fbd83d
+  NaTrayChild *child = NA_TRAY_CHILD (widget);
9fbd83d
+
9fbd83d
+  if (na_tray_child_has_alpha (child))
9fbd83d
+    {
9fbd83d
+      /* Clear to transparent */
9fbd83d
+      cairo_t *cr = gdk_cairo_create (widget->window);
9fbd83d
+      cairo_set_source_rgba (cr, 0, 0, 0, 0);
9fbd83d
+      cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
9fbd83d
+      gdk_cairo_region (cr, event->region);
9fbd83d
+      cairo_fill (cr);
9fbd83d
+      cairo_destroy (cr);
9fbd83d
+    }
9fbd83d
+  else if (child->parent_relative_bg)
9fbd83d
+    {
9fbd83d
+      /* Clear to parent-relative pixmap */
9fbd83d
+      gdk_window_clear_area (widget->window,
9fbd83d
+                             event->area.x, event->area.y,
9fbd83d
+                             event->area.width, event->area.height);
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  return FALSE;
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_init (NaTrayChild *child)
9fbd83d
+{
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_child_class_init (NaTrayChildClass *klass)
9fbd83d
+{
9fbd83d
+  GObjectClass *gobject_class;
9fbd83d
+  GtkWidgetClass *widget_class;
9fbd83d
+
9fbd83d
+  gobject_class = (GObjectClass *)klass;
9fbd83d
+  widget_class = (GtkWidgetClass *)klass;
9fbd83d
+
9fbd83d
+  gobject_class->finalize = na_tray_child_finalize;
9fbd83d
+  widget_class->style_set = na_tray_child_style_set;
9fbd83d
+  widget_class->realize = na_tray_child_realize;
9fbd83d
+  widget_class->size_allocate = na_tray_child_size_allocate;
9fbd83d
+  widget_class->expose_event = na_tray_child_expose_event;
9fbd83d
+}
9fbd83d
+
9fbd83d
+GtkWidget *
9fbd83d
+na_tray_child_new (GdkScreen *screen,
9fbd83d
+                   Window     icon_window)
9fbd83d
+{
9fbd83d
+  XWindowAttributes window_attributes;
9fbd83d
+  Display *xdisplay;
9fbd83d
+  NaTrayChild *child;
9fbd83d
+  GdkVisual *visual;
9fbd83d
+  gboolean visual_has_alpha;
9fbd83d
+  GdkColormap *colormap;
9fbd83d
+  gboolean new_colormap;
9fbd83d
+  int result;
9fbd83d
+
9fbd83d
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
9fbd83d
+  g_return_val_if_fail (icon_window != None, NULL);
9fbd83d
+
9fbd83d
+  xdisplay = GDK_SCREEN_XDISPLAY (screen);
9fbd83d
+
9fbd83d
+  /* We need to determine the visual of the window we are embedding and create
9fbd83d
+   * the socket in the same visual.
9fbd83d
+   */
9fbd83d
+
9fbd83d
+  gdk_error_trap_push ();
9fbd83d
+  result = XGetWindowAttributes (xdisplay, icon_window,
9fbd83d
+                                 &window_attributes);
9fbd83d
+  gdk_error_trap_pop ();
9fbd83d
+
9fbd83d
+  if (!result) /* Window already gone */
9fbd83d
+    return NULL;
9fbd83d
+
9fbd83d
+  visual = gdk_x11_screen_lookup_visual (screen,
9fbd83d
+                                         window_attributes.visual->visualid);
9fbd83d
+  if (!visual) /* Icon window is on another screen? */
9fbd83d
+    return NULL;
9fbd83d
+
9fbd83d
+  new_colormap = FALSE;
9fbd83d
+
9fbd83d
+  if (visual == gdk_screen_get_rgb_visual (screen))
9fbd83d
+    colormap = gdk_screen_get_rgb_colormap (screen);
9fbd83d
+  else if (visual == gdk_screen_get_rgba_visual (screen))
9fbd83d
+    colormap = gdk_screen_get_rgba_colormap (screen);
9fbd83d
+  else if (visual == gdk_screen_get_system_visual (screen))
9fbd83d
+    colormap = gdk_screen_get_system_colormap (screen);
9fbd83d
+  else
9fbd83d
+    {
9fbd83d
+      colormap = gdk_colormap_new (visual, FALSE);
9fbd83d
+      new_colormap = TRUE;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  child = g_object_new (NA_TYPE_TRAY_CHILD, NULL);
9fbd83d
+  child->icon_window = icon_window;
9fbd83d
+
9fbd83d
+  gtk_widget_set_colormap (GTK_WIDGET (child), colormap);
9fbd83d
+
9fbd83d
+  /* We have alpha if the visual has something other than red, green,
9fbd83d
+   * and blue */
9fbd83d
+  visual_has_alpha = visual->red_prec + visual->blue_prec + visual->green_prec < visual->depth;
9fbd83d
+  child->has_alpha = (visual_has_alpha &&
9fbd83d
+                      gdk_display_supports_composite (gdk_screen_get_display (screen)));
9fbd83d
+
9fbd83d
+  child->composited = child->has_alpha;
9fbd83d
+
9fbd83d
+  if (new_colormap)
9fbd83d
+    g_object_unref (colormap);
9fbd83d
+
9fbd83d
+  return GTK_WIDGET (child);
9fbd83d
+}
9fbd83d
+
9fbd83d
+char *
9fbd83d
+na_tray_child_get_title (NaTrayChild *child)
9fbd83d
+{
9fbd83d
+  char *retval = NULL;
9fbd83d
+  GdkDisplay *display;
9fbd83d
+  Atom utf8_string, atom, type;
9fbd83d
+  int result;
9fbd83d
+  int format;
9fbd83d
+  gulong nitems;
9fbd83d
+  gulong bytes_after;
9fbd83d
+  gchar *val;
9fbd83d
+
9fbd83d
+  g_return_val_if_fail (NA_IS_TRAY_CHILD (child), NULL);
9fbd83d
+
9fbd83d
+  display = gtk_widget_get_display (GTK_WIDGET (child));
9fbd83d
+
9fbd83d
+  utf8_string = gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING");
9fbd83d
+  atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME");
9fbd83d
+
9fbd83d
+  gdk_error_trap_push ();
9fbd83d
+
9fbd83d
+  result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
9fbd83d
+                               child->icon_window,
9fbd83d
+                               atom,
9fbd83d
+                               0, G_MAXLONG,
9fbd83d
+                               False, utf8_string,
9fbd83d
+                               &type, &format, &nitems,
9fbd83d
+                               &bytes_after, (guchar **)&val;;
9fbd83d
+  
9fbd83d
+  if (gdk_error_trap_pop () || result != Success)
9fbd83d
+    return NULL;
9fbd83d
+
9fbd83d
+  if (type != utf8_string ||
9fbd83d
+      format != 8 ||
9fbd83d
+      nitems == 0)
9fbd83d
+    {
9fbd83d
+      if (val)
9fbd83d
+        XFree (val);
9fbd83d
+      return NULL;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  if (!g_utf8_validate (val, nitems, NULL))
9fbd83d
+    {
9fbd83d
+      XFree (val);
9fbd83d
+      return NULL;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  retval = g_strndup (val, nitems);
9fbd83d
+
9fbd83d
+  XFree (val);
9fbd83d
+
9fbd83d
+  return retval;
9fbd83d
+}
9fbd83d
+
9fbd83d
+/**
9fbd83d
+ * na_tray_child_has_alpha;
9fbd83d
+ * @child: a #NaTrayChild
9fbd83d
+ *
9fbd83d
+ * Checks if the child has an ARGB visual and real alpha transparence.
9fbd83d
+ * (as opposed to faked alpha transparency with an parent-relative
9fbd83d
+ * background)
9fbd83d
+ *
9fbd83d
+ * Return value: %TRUE if the child has an alpha transparency
9fbd83d
+ */
9fbd83d
+gboolean
9fbd83d
+na_tray_child_has_alpha (NaTrayChild *child)
9fbd83d
+{
9fbd83d
+  g_return_val_if_fail (NA_IS_TRAY_CHILD (child), FALSE);
9fbd83d
+
9fbd83d
+  return child->has_alpha;
9fbd83d
+}
9fbd83d
+
9fbd83d
+/**
9fbd83d
+ * na_tray_child_set_composited;
9fbd83d
+ * @child: a #NaTrayChild
9fbd83d
+ * @composited: %TRUE if the child's window should be redirected
9fbd83d
+ *
9fbd83d
+ * Sets whether the #GdkWindow of the child should be set redirected
9fbd83d
+ * using gdk_window_set_composited(). By default this is based off of
9fbd83d
+ * na_tray_child_has_alpha(), but it may be useful to override it in
9fbd83d
+ * certain circumstances; for example, if the #NaTrayChild is added
9fbd83d
+ * to a parent window and that parent window is composited against the
9fbd83d
+ * background.
9fbd83d
+ */
9fbd83d
+void
9fbd83d
+na_tray_child_set_composited (NaTrayChild *child,
9fbd83d
+                              gboolean     composited)
9fbd83d
+{
9fbd83d
+  g_return_if_fail (NA_IS_TRAY_CHILD (child));
9fbd83d
+
9fbd83d
+  if (child->composited == composited)
9fbd83d
+    return;
9fbd83d
+
9fbd83d
+  child->composited = composited;
9fbd83d
+  if (GTK_WIDGET_REALIZED (child))
9fbd83d
+    gdk_window_set_composited (GTK_WIDGET (child)->window, composited);
9fbd83d
+}
9fbd83d
+
9fbd83d
+/* If we are faking transparency with a window-relative background, force a
9fbd83d
+ * redraw of the icon. This should be called if the background changes or if
9fbd83d
+ * the child is shifted with respect to the background.
9fbd83d
+ */
9fbd83d
+void
9fbd83d
+na_tray_child_force_redraw (NaTrayChild *child)
9fbd83d
+{
9fbd83d
+  GtkWidget *widget = GTK_WIDGET (child);
9fbd83d
+
9fbd83d
+  if (GTK_WIDGET_MAPPED (child) && child->parent_relative_bg)
9fbd83d
+    {
9fbd83d
+#if 1
9fbd83d
+      /* Sending an ExposeEvent might cause redraw problems if the
9fbd83d
+       * icon is expecting the server to clear-to-background before
9fbd83d
+       * the redraw. It should be ok for GtkStatusIcon or EggTrayIcon.
9fbd83d
+       */
9fbd83d
+      Display *xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
9fbd83d
+      XEvent xev;
9fbd83d
+
9fbd83d
+      xev.xexpose.type = Expose;
9fbd83d
+      xev.xexpose.window = GDK_WINDOW_XWINDOW (GTK_SOCKET (child)->plug_window);
9fbd83d
+      xev.xexpose.x = 0;
9fbd83d
+      xev.xexpose.y = 0;
9fbd83d
+      xev.xexpose.width = widget->allocation.width;
9fbd83d
+      xev.xexpose.height = widget->allocation.height;
9fbd83d
+      xev.xexpose.count = 0;
9fbd83d
+
9fbd83d
+      gdk_error_trap_push ();
9fbd83d
+      XSendEvent (GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget)),
9fbd83d
+                  xev.xexpose.window,
9fbd83d
+                  False, ExposureMask,
9fbd83d
+                  &xev);
9fbd83d
+      /* We have to sync to reliably catch errors from the XSendEvent(),
9fbd83d
+       * since that is asynchronous.
9fbd83d
+       */
9fbd83d
+      XSync (xdisplay, False);
9fbd83d
+      gdk_error_trap_pop ();
9fbd83d
+#else
9fbd83d
+      /* Hiding and showing is the safe way to do it, but can result in more
9fbd83d
+       * flickering.
9fbd83d
+       */
9fbd83d
+      gdk_window_hide (widget->window);
9fbd83d
+      gdk_window_show (widget->window);
9fbd83d
+#endif
9fbd83d
+    }
9fbd83d
+}
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.h b/gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
new file mode 100644
9fbd83d
index 0000000..c174abe
9fbd83d
--- /dev/null
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
@@ -0,0 +1,68 @@
9fbd83d
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
9fbd83d
+/* na-tray-child.h
9fbd83d
+ * Copyright (C) 2002 Anders Carlsson <andersca@gnu.org>
9fbd83d
+ * Copyright (C) 2003-2006 Vincent Untz
9fbd83d
+ * Copyright (C) 2008 Red Hat, Inc.
9fbd83d
+ *
9fbd83d
+ * This library is free software; you can redistribute it and/or
9fbd83d
+ * modify it under the terms of the GNU Lesser General Public
9fbd83d
+ * License as published by the Free Software Foundation; either
9fbd83d
+ * version 2 of the License, or (at your option) any later version.
9fbd83d
+ *
9fbd83d
+ * This library is distributed in the hope that it will be useful,
9fbd83d
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
9fbd83d
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9fbd83d
+ * Lesser General Public License for more details.
9fbd83d
+ *
9fbd83d
+ * You should have received a copy of the GNU Lesser General Public
9fbd83d
+ * License along with this library; if not, write to the
9fbd83d
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
9fbd83d
+ * Boston, MA 02111-1307, USA.
9fbd83d
+ */
9fbd83d
+
9fbd83d
+#ifndef __NA_TRAY_CHILD_H__
9fbd83d
+#define __NA_TRAY_CHILD_H__
9fbd83d
+
9fbd83d
+#include <gtk/gtk.h>
9fbd83d
+#include <gdk/gdkx.h>
9fbd83d
+
9fbd83d
+G_BEGIN_DECLS
9fbd83d
+
9fbd83d
+#define NA_TYPE_TRAY_CHILD		(na_tray_child_get_type ())
9fbd83d
+#define NA_TRAY_CHILD(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), NA_TYPE_TRAY_CHILD, NaTrayChild))
9fbd83d
+#define NA_TRAY_CHILD_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), NA_TYPE_TRAY_CHILD, NaTrayChildClass))
9fbd83d
+#define NA_IS_TRAY_CHILD(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), NA_TYPE_TRAY_CHILD))
9fbd83d
+#define NA_IS_TRAY_CHILD_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), NA_TYPE_TRAY_CHILD))
9fbd83d
+#define NA_TRAY_CHILD_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), NA_TYPE_TRAY_CHILD, NaTrayChildClass))
9fbd83d
+
9fbd83d
+typedef struct _NaTrayChild	  NaTrayChild;
9fbd83d
+typedef struct _NaTrayChildClass  NaTrayChildClass;
9fbd83d
+typedef struct _NaTrayChildChild  NaTrayChildChild;
9fbd83d
+
9fbd83d
+struct _NaTrayChild
9fbd83d
+{
9fbd83d
+  GtkSocket parent_instance;
9fbd83d
+  Window icon_window;
9fbd83d
+  guint has_alpha : 1;
9fbd83d
+  guint composited : 1;
9fbd83d
+  guint parent_relative_bg : 1;
9fbd83d
+};
9fbd83d
+
9fbd83d
+struct _NaTrayChildClass
9fbd83d
+{
9fbd83d
+  GtkSocketClass parent_class;
9fbd83d
+};
9fbd83d
+
9fbd83d
+GType           na_tray_child_get_type        (void);
9fbd83d
+
9fbd83d
+GtkWidget      *na_tray_child_new            (GdkScreen   *screen,
9fbd83d
+                                              Window       icon_window);
9fbd83d
+char           *na_tray_child_get_title      (NaTrayChild *child);
9fbd83d
+gboolean        na_tray_child_has_alpha      (NaTrayChild *child);
9fbd83d
+void            na_tray_child_set_composited (NaTrayChild *child,
9fbd83d
+                                              gboolean     composited);
9fbd83d
+void            na_tray_child_force_redraw   (NaTrayChild *child);
9fbd83d
+
9fbd83d
+G_END_DECLS
9fbd83d
+
9fbd83d
+#endif /* __NA_TRAY_CHILD_H__ */
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.c b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
index 4842a91..1bf54f1 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
@@ -252,120 +252,61 @@ static gboolean
9fbd83d
 na_tray_manager_plug_removed (GtkSocket       *socket,
9fbd83d
 			      NaTrayManager   *manager)
9fbd83d
 {
9fbd83d
-  Window *window;
9fbd83d
+  NaTrayChild *child = NA_TRAY_CHILD (socket);
9fbd83d
 
9fbd83d
-  window = g_object_get_data (G_OBJECT (socket), "na-tray-child-window");
9fbd83d
-
9fbd83d
-  g_hash_table_remove (manager->socket_table, GINT_TO_POINTER (*window));
9fbd83d
-  g_object_set_data (G_OBJECT (socket), "na-tray-child-window",
9fbd83d
-		     NULL);
9fbd83d
-  
9fbd83d
-  g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, socket);
9fbd83d
+  g_hash_table_remove (manager->socket_table,
9fbd83d
+                       GINT_TO_POINTER (child->icon_window));
9fbd83d
+  g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, child);
9fbd83d
 
9fbd83d
   /* This destroys the socket. */
9fbd83d
   return FALSE;
9fbd83d
 }
9fbd83d
 
9fbd83d
 static void
9fbd83d
-na_tray_manager_make_socket_transparent (GtkWidget *widget,
9fbd83d
-                                         gpointer   user_data)
9fbd83d
+na_tray_manager_handle_dock_request (NaTrayManager       *manager,
9fbd83d
+				     XClientMessageEvent *xevent)
9fbd83d
 {
9fbd83d
-  if (GTK_WIDGET_NO_WINDOW (widget))
9fbd83d
-    return;
9fbd83d
+  Window icon_window = xevent->data.l[2];
9fbd83d
+  GtkWidget *child;
9fbd83d
 
9fbd83d
-  gdk_window_set_back_pixmap (widget->window, NULL, TRUE);
9fbd83d
-}
9fbd83d
-
9fbd83d
-static gboolean
9fbd83d
-na_tray_manager_socket_exposed (GtkWidget      *widget,
9fbd83d
-                                GdkEventExpose *event,
9fbd83d
-                                gpointer        user_data)
9fbd83d
-{
9fbd83d
-  gdk_window_clear_area (widget->window,
9fbd83d
-                         event->area.x, event->area.y,
9fbd83d
-                         event->area.width, event->area.height);
9fbd83d
-  return FALSE;
9fbd83d
-}
9fbd83d
+  if (g_hash_table_lookup (manager->socket_table,
9fbd83d
+                           GINT_TO_POINTER (icon_window)))
9fbd83d
+    {
9fbd83d
+      /* We already got this notification earlier, ignore this one */
9fbd83d
+      return;
9fbd83d
+    }
9fbd83d
 
9fbd83d
-static void
9fbd83d
-na_tray_manager_socket_style_set (GtkWidget *widget,
9fbd83d
-                                  GtkStyle  *previous_style,
9fbd83d
-                                  gpointer   user_data)
9fbd83d
-{
9fbd83d
-  if (widget->window == NULL)
9fbd83d
+  child = na_tray_child_new (manager->screen, icon_window);
9fbd83d
+  if (child == NULL) /* already gone or other error */
9fbd83d
     return;
9fbd83d
 
9fbd83d
-  na_tray_manager_make_socket_transparent (widget, user_data);
9fbd83d
-}
9fbd83d
+  g_signal_emit (manager, manager_signals[TRAY_ICON_ADDED], 0,
9fbd83d
+		 child);
9fbd83d
 
9fbd83d
-static void
9fbd83d
-na_tray_manager_handle_dock_request (NaTrayManager       *manager,
9fbd83d
-				     XClientMessageEvent *xevent)
9fbd83d
-{
9fbd83d
-  GtkWidget *socket;
9fbd83d
-  Window *window;
9fbd83d
-  GtkRequisition req;
9fbd83d
+  /* If the child wasn't attached, then destroy it */
9fbd83d
 
9fbd83d
-  if (g_hash_table_lookup (manager->socket_table, GINT_TO_POINTER (xevent->data.l[2])))
9fbd83d
+  if (!GTK_IS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (child))))
9fbd83d
     {
9fbd83d
-      /* We already got this notification earlier, ignore this one */
9fbd83d
+      gtk_widget_destroy (child);
9fbd83d
       return;
9fbd83d
     }
9fbd83d
-  
9fbd83d
-  socket = gtk_socket_new ();
9fbd83d
-
9fbd83d
-  gtk_widget_set_app_paintable (socket, TRUE);
9fbd83d
-  //FIXME: need to find a theme where this (and expose event) is needed
9fbd83d
-  gtk_widget_set_double_buffered (socket, FALSE);
9fbd83d
-  g_signal_connect (socket, "realize",
9fbd83d
-                    G_CALLBACK (na_tray_manager_make_socket_transparent), NULL);
9fbd83d
-  g_signal_connect (socket, "expose_event",
9fbd83d
-                    G_CALLBACK (na_tray_manager_socket_exposed), NULL);
9fbd83d
-  g_signal_connect_after (socket, "style_set",
9fbd83d
-                          G_CALLBACK (na_tray_manager_socket_style_set), NULL);
9fbd83d
-  
9fbd83d
-  /* We need to set the child window here
9fbd83d
-   * so that the client can call _get functions
9fbd83d
-   * in the signal handler
9fbd83d
-   */
9fbd83d
-  window = g_new (Window, 1);
9fbd83d
-  *window = xevent->data.l[2];
9fbd83d
-      
9fbd83d
-  g_object_set_data_full (G_OBJECT (socket),
9fbd83d
-			  "na-tray-child-window",
9fbd83d
-			  window, g_free);
9fbd83d
-  g_signal_emit (manager, manager_signals[TRAY_ICON_ADDED], 0,
9fbd83d
-		 socket);
9fbd83d
 
9fbd83d
-  /* Add the socket only if it's been attached */
9fbd83d
-  if (GTK_IS_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (socket))))
9fbd83d
+  g_signal_connect (child, "plug_removed",
9fbd83d
+		    G_CALLBACK (na_tray_manager_plug_removed), manager);
9fbd83d
+
9fbd83d
+  gtk_socket_add_id (GTK_SOCKET (child), icon_window);
9fbd83d
+
9fbd83d
+  if (!GTK_SOCKET (child)->plug_window)
9fbd83d
     {
9fbd83d
-      g_signal_connect (socket, "plug_removed",
9fbd83d
-			G_CALLBACK (na_tray_manager_plug_removed), manager);
9fbd83d
-      
9fbd83d
-      gtk_socket_add_id (GTK_SOCKET (socket), *window);
9fbd83d
-
9fbd83d
-      g_hash_table_insert (manager->socket_table, GINT_TO_POINTER (*window), socket);
9fbd83d
-
9fbd83d
-      /*
9fbd83d
-       * Make sure the icons have a meaningfull size ...
9fbd83d
-       */ 
9fbd83d
-      req.width = req.height = 1;
9fbd83d
-      gtk_widget_size_request (socket, &req;;
9fbd83d
-      /*
9fbd83d
-      if ((req.width < 16) || (req.height < 16))
9fbd83d
-      {
9fbd83d
-          gint nw = MAX (24, req.width);
9fbd83d
-          gint nh = MAX (24, req.height);
9fbd83d
-          g_warning (_("tray icon has requested a size of (%i x %i), resizing to (%i x %i)"), 
9fbd83d
-                      req.width, req.height, nw, nh);
9fbd83d
-          gtk_widget_set_size_request(icon, nw,  nh);
9fbd83d
-      }
9fbd83d
-      */
9fbd83d
-      gtk_widget_show(socket);
9fbd83d
+      /* Embedding failed, we won't get a plug-removed signal */
9fbd83d
+      g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, child);
9fbd83d
+      gtk_widget_destroy (child);
9fbd83d
+      return;
9fbd83d
     }
9fbd83d
-  else
9fbd83d
-    gtk_widget_destroy (socket);
9fbd83d
+
9fbd83d
+  g_hash_table_insert (manager->socket_table,
9fbd83d
+                       GINT_TO_POINTER (icon_window), child);
9fbd83d
+  gtk_widget_show (child);
9fbd83d
 }
9fbd83d
 
9fbd83d
 static void
9fbd83d
@@ -445,13 +386,13 @@ na_tray_manager_handle_begin_message (NaTrayManager       *manager,
9fbd83d
   /* Check if the same message is already in the queue and remove it if so */
9fbd83d
   for (p = manager->messages; p; p = p->next)
9fbd83d
     {
9fbd83d
-      PendingMessage *message = p->data;
9fbd83d
+      PendingMessage *pmsg = p->data;
9fbd83d
 
9fbd83d
-      if (xevent->window == message->window &&
9fbd83d
-	  xevent->data.l[4] == message->id)
9fbd83d
+      if (xevent->window == pmsg->window &&
9fbd83d
+	  xevent->data.l[4] == pmsg->id)
9fbd83d
 	{
9fbd83d
 	  /* Hmm, we found it, now remove it */
9fbd83d
-	  pending_message_free (message);
9fbd83d
+	  pending_message_free (pmsg);
9fbd83d
 	  manager->messages = g_list_remove_link (manager->messages, p);
9fbd83d
           g_list_free_1 (p);
9fbd83d
 	  break;
9fbd83d
@@ -660,6 +601,58 @@ na_tray_manager_set_orientation_property (NaTrayManager *manager)
9fbd83d
 #endif
9fbd83d
 }
9fbd83d
 
9fbd83d
+static void
9fbd83d
+na_tray_manager_set_visual_property (NaTrayManager *manager)
9fbd83d
+{
9fbd83d
+#ifdef GDK_WINDOWING_X11
9fbd83d
+  GdkDisplay *display;
9fbd83d
+  Visual     *xvisual;
9fbd83d
+  Atom        visual_atom;
9fbd83d
+  gulong      data[1];
9fbd83d
+
9fbd83d
+  if (!manager->invisible || !manager->invisible->window)
9fbd83d
+    return;
9fbd83d
+
9fbd83d
+  /* The visual property is a hint to the tray icons as to what visual they
9fbd83d
+   * should use for their windows. If the X server has RGBA colormaps, then
9fbd83d
+   * we tell the tray icons to use a RGBA colormap and we'll composite the
9fbd83d
+   * icon onto its parents with real transparency. Otherwise, we just tell
9fbd83d
+   * the icon to use our colormap, and we'll do some hacks with parent
9fbd83d
+   * relative backgrounds to simulate transparency.
9fbd83d
+   */
9fbd83d
+
9fbd83d
+  display = gtk_widget_get_display (manager->invisible);
9fbd83d
+  visual_atom = gdk_x11_get_xatom_by_name_for_display (display,
9fbd83d
+						       "_NET_SYSTEM_TRAY_VISUAL");
9fbd83d
+
9fbd83d
+  if (gdk_screen_get_rgba_visual (manager->screen) != NULL &&
9fbd83d
+      gdk_display_supports_composite (display))
9fbd83d
+    {
9fbd83d
+      xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_rgba_visual (manager->screen));
9fbd83d
+    }
9fbd83d
+  else
9fbd83d
+    {
9fbd83d
+      /* We actually want the visual of the tray where the icons will
9fbd83d
+       * be embedded. In almost all cases, this will be the same as the visual
9fbd83d
+       * of the screen.
9fbd83d
+       */
9fbd83d
+      GdkColormap *colormap;
9fbd83d
+
9fbd83d
+      colormap = gdk_screen_get_default_colormap (manager->screen);
9fbd83d
+      xvisual = GDK_VISUAL_XVISUAL (gdk_colormap_get_visual (colormap));
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  data[0] = XVisualIDFromVisual (xvisual);
9fbd83d
+
9fbd83d
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
9fbd83d
+                   GDK_WINDOW_XWINDOW (manager->invisible->window),
9fbd83d
+                   visual_atom,
9fbd83d
+                   XA_VISUALID, 32,
9fbd83d
+                   PropModeReplace,
9fbd83d
+                   (guchar *) &data, 1);
9fbd83d
+#endif
9fbd83d
+}
9fbd83d
+
9fbd83d
 #ifdef GDK_WINDOWING_X11
9fbd83d
 
9fbd83d
 static gboolean
9fbd83d
@@ -682,6 +675,9 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
9fbd83d
   if (na_tray_manager_check_running_screen_x11 (screen))
9fbd83d
     return FALSE;
9fbd83d
 #endif
9fbd83d
+  
9fbd83d
+  manager->screen = screen;
9fbd83d
+
9fbd83d
   display = gdk_screen_get_display (screen);
9fbd83d
   xscreen = GDK_SCREEN_XSCREEN (screen);
9fbd83d
   
9fbd83d
@@ -696,7 +692,11 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
9fbd83d
   manager->selection_atom = gdk_atom_intern (selection_atom_name, FALSE);
9fbd83d
   g_free (selection_atom_name);
9fbd83d
 
9fbd83d
+  manager->invisible = invisible;
9fbd83d
+  g_object_ref (G_OBJECT (manager->invisible));
9fbd83d
+
9fbd83d
   na_tray_manager_set_orientation_property (manager);
9fbd83d
+  na_tray_manager_set_visual_property (manager);
9fbd83d
   
9fbd83d
   timestamp = gdk_x11_get_server_time (invisible->window);
9fbd83d
 
9fbd83d
@@ -728,9 +728,6 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
9fbd83d
 		  RootWindowOfScreen (xscreen),
9fbd83d
 		  False, StructureNotifyMask, (XEvent *)&xev);
9fbd83d
 
9fbd83d
-      manager->invisible = invisible;
9fbd83d
-      g_object_ref (G_OBJECT (manager->invisible));
9fbd83d
-      
9fbd83d
       opcode_atom = gdk_atom_intern ("_NET_SYSTEM_TRAY_OPCODE", FALSE);
9fbd83d
       manager->opcode_atom = gdk_x11_atom_to_xatom_for_display (display,
9fbd83d
                                                                 opcode_atom);
9fbd83d
@@ -761,6 +758,10 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
9fbd83d
   else
9fbd83d
     {
9fbd83d
       gtk_widget_destroy (invisible);
9fbd83d
+      g_object_unref (invisible);
9fbd83d
+      manager->invisible = NULL;
9fbd83d
+
9fbd83d
+      manager->screen = NULL;
9fbd83d
  
9fbd83d
       return FALSE;
9fbd83d
     }
9fbd83d
@@ -819,67 +820,6 @@ na_tray_manager_check_running (GdkScreen *screen)
9fbd83d
 #endif
9fbd83d
 }
9fbd83d
 
9fbd83d
-char *
9fbd83d
-na_tray_manager_get_child_title (NaTrayManager      *manager,
9fbd83d
-				 NaTrayManagerChild *child)
9fbd83d
-{
9fbd83d
-  char *retval = NULL;
9fbd83d
-#ifdef GDK_WINDOWING_X11
9fbd83d
-  GdkDisplay *display;
9fbd83d
-  Window *child_window;
9fbd83d
-  Atom utf8_string, atom, type;
9fbd83d
-  int result;
9fbd83d
-  int format;
9fbd83d
-  gulong nitems;
9fbd83d
-  gulong bytes_after;
9fbd83d
-  gchar *val;
9fbd83d
-
9fbd83d
-  g_return_val_if_fail (NA_IS_TRAY_MANAGER (manager), NULL);
9fbd83d
-  g_return_val_if_fail (GTK_IS_SOCKET (child), NULL);
9fbd83d
-  
9fbd83d
-  display = gdk_screen_get_display (manager->screen);
9fbd83d
-
9fbd83d
-  child_window = g_object_get_data (G_OBJECT (child),
9fbd83d
-				    "na-tray-child-window");
9fbd83d
-
9fbd83d
-  utf8_string = gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING");
9fbd83d
-  atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME");
9fbd83d
-
9fbd83d
-  gdk_error_trap_push ();
9fbd83d
-
9fbd83d
-  result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
9fbd83d
-			       *child_window,
9fbd83d
-			       atom,
9fbd83d
-			       0, G_MAXLONG,
9fbd83d
-			       False, utf8_string,
9fbd83d
-			       &type, &format, &nitems,
9fbd83d
-			       &bytes_after, (guchar **)&val;;
9fbd83d
-  
9fbd83d
-  if (gdk_error_trap_pop () || result != Success)
9fbd83d
-    return NULL;
9fbd83d
-
9fbd83d
-  if (type != utf8_string ||
9fbd83d
-      format != 8 ||
9fbd83d
-      nitems == 0)
9fbd83d
-    {
9fbd83d
-      if (val)
9fbd83d
-	XFree (val);
9fbd83d
-      return NULL;
9fbd83d
-    }
9fbd83d
-
9fbd83d
-  if (!g_utf8_validate (val, nitems, NULL))
9fbd83d
-    {
9fbd83d
-      XFree (val);
9fbd83d
-      return NULL;
9fbd83d
-    }
9fbd83d
-
9fbd83d
-  retval = g_strndup (val, nitems);
9fbd83d
-
9fbd83d
-  XFree (val);
9fbd83d
-#endif
9fbd83d
-  return retval;
9fbd83d
-}
9fbd83d
-
9fbd83d
 void
9fbd83d
 na_tray_manager_set_orientation (NaTrayManager  *manager,
9fbd83d
 				 GtkOrientation  orientation)
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.h b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
index a1781a7..f325453 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
@@ -24,10 +24,12 @@
9fbd83d
 #ifndef __NA_TRAY_MANAGER_H__
9fbd83d
 #define __NA_TRAY_MANAGER_H__
9fbd83d
 
9fbd83d
-#include <gtk/gtk.h>
9fbd83d
 #ifdef GDK_WINDOWING_X11
9fbd83d
 #include <gdk/gdkx.h>
9fbd83d
 #endif
9fbd83d
+#include <gtk/gtk.h>
9fbd83d
+
9fbd83d
+#include "na-tray-child.h"
9fbd83d
 
9fbd83d
 G_BEGIN_DECLS
9fbd83d
 
9fbd83d
@@ -40,7 +42,6 @@ G_BEGIN_DECLS
9fbd83d
 	
9fbd83d
 typedef struct _NaTrayManager	    NaTrayManager;
9fbd83d
 typedef struct _NaTrayManagerClass  NaTrayManagerClass;
9fbd83d
-typedef struct _NaTrayManagerChild  NaTrayManagerChild;
9fbd83d
 
9fbd83d
 struct _NaTrayManager
9fbd83d
 {
9fbd83d
@@ -64,18 +65,18 @@ struct _NaTrayManagerClass
9fbd83d
   GObjectClass parent_class;
9fbd83d
 
9fbd83d
   void (* tray_icon_added)   (NaTrayManager      *manager,
9fbd83d
-			      NaTrayManagerChild *child);
9fbd83d
+			      NaTrayChild        *child);
9fbd83d
   void (* tray_icon_removed) (NaTrayManager      *manager,
9fbd83d
-			      NaTrayManagerChild *child);
9fbd83d
+			      NaTrayChild        *child);
9fbd83d
 
9fbd83d
   void (* message_sent)      (NaTrayManager      *manager,
9fbd83d
-			      NaTrayManagerChild *child,
9fbd83d
+			      NaTrayChild        *child,
9fbd83d
 			      const gchar        *message,
9fbd83d
 			      glong               id,
9fbd83d
 			      glong               timeout);
9fbd83d
   
9fbd83d
   void (* message_cancelled) (NaTrayManager      *manager,
9fbd83d
-			      NaTrayManagerChild *child,
9fbd83d
+			      NaTrayChild        *child,
9fbd83d
 			      glong               id);
9fbd83d
 
9fbd83d
   void (* lost_selection)    (NaTrayManager      *manager);
9fbd83d
@@ -87,8 +88,6 @@ gboolean        na_tray_manager_check_running   (GdkScreen          *screen);
9fbd83d
 NaTrayManager  *na_tray_manager_new             (void);
9fbd83d
 gboolean        na_tray_manager_manage_screen   (NaTrayManager      *manager,
9fbd83d
 						 GdkScreen          *screen);
9fbd83d
-char           *na_tray_manager_get_child_title (NaTrayManager      *manager,
9fbd83d
-						 NaTrayManagerChild *child);
9fbd83d
 void            na_tray_manager_set_orientation (NaTrayManager      *manager,
9fbd83d
 						 GtkOrientation      orientation);
9fbd83d
 GtkOrientation  na_tray_manager_get_orientation (NaTrayManager      *manager);
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
index 7192717..051a811 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
@@ -12,7 +12,7 @@
9fbd83d
  * WITHOUT ANY WARRANTY; without even the implied warranty of
9fbd83d
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9fbd83d
  * General Public License for more details.
9fbd83d
- *
9fbd83d
+ * 
9fbd83d
  * You should have received a copy of the GNU General Public License
9fbd83d
  * along with this program; if not, write to the Free Software
9fbd83d
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
9fbd83d
@@ -26,7 +26,6 @@
9fbd83d
 
9fbd83d
 #include "na-tray-manager.h"
9fbd83d
 #include "fixedtip.h"
9fbd83d
-#include "obox.h"
9fbd83d
 
9fbd83d
 #include "na-tray.h"
9fbd83d
 
9fbd83d
@@ -83,6 +82,27 @@ static TraysScreen *trays_screens = NULL;
9fbd83d
 
9fbd83d
 static void icon_tip_show_next (IconTip *icontip);
9fbd83d
 
9fbd83d
+/* NaBox, an instantiable GtkBox */
9fbd83d
+
9fbd83d
+typedef GtkBox      NaBox;
9fbd83d
+typedef GtkBoxClass NaBoxClass;
9fbd83d
+
9fbd83d
+static GType na_box_get_type (void);
9fbd83d
+
9fbd83d
+G_DEFINE_TYPE (NaBox, na_box, GTK_TYPE_BOX)
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_box_init (NaBox *box)
9fbd83d
+{
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_box_class_init (NaBoxClass *klass)
9fbd83d
+{
9fbd83d
+}
9fbd83d
+
9fbd83d
+/* NaTray */
9fbd83d
+
9fbd83d
 G_DEFINE_TYPE (NaTray, na_tray, GTK_TYPE_BIN)
9fbd83d
 
9fbd83d
 static NaTray *
9fbd83d
@@ -115,7 +135,6 @@ tray_added (NaTrayManager *manager,
9fbd83d
   gtk_box_pack_end (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
9fbd83d
 
9fbd83d
   gtk_widget_show (icon);
9fbd83d
-  na_tray_force_redraw (tray);
9fbd83d
 }
9fbd83d
 
9fbd83d
 static void
9fbd83d
@@ -131,8 +150,6 @@ tray_removed (NaTrayManager *manager,
9fbd83d
 
9fbd83d
   g_assert (tray->priv->trays_screen == trays_screen);
9fbd83d
 
9fbd83d
-  na_tray_force_redraw (tray);
9fbd83d
-
9fbd83d
   g_hash_table_remove (trays_screen->icon_table, icon);
9fbd83d
   /* this will also destroy the tip associated to this icon */
9fbd83d
   g_hash_table_remove (trays_screen->tip_table, icon);
9fbd83d
@@ -247,8 +264,9 @@ icon_tip_show_next (IconTip *icontip)
9fbd83d
   icontip->id = buffer->id;
9fbd83d
 
9fbd83d
   if (buffer->timeout > 0)
9fbd83d
-    icontip->source_id = g_timeout_add (buffer->timeout * 1000,
9fbd83d
-                                        icon_tip_show_next_timeout, icontip);
9fbd83d
+    icontip->source_id = g_timeout_add_seconds (buffer->timeout,
9fbd83d
+                                                icon_tip_show_next_timeout,
9fbd83d
+                                                icontip);
9fbd83d
 
9fbd83d
   icon_tip_buffer_free (buffer, NULL);
9fbd83d
 }
9fbd83d
@@ -375,7 +393,7 @@ update_size_and_orientation (NaTray *tray)
9fbd83d
 {
9fbd83d
   NaTrayPrivate *priv = tray->priv;
9fbd83d
 
9fbd83d
-  na_obox_set_orientation (NA_OBOX (priv->box), priv->orientation);
9fbd83d
+  gtk_orientable_set_orientation (GTK_ORIENTABLE (priv->box), priv->orientation);
9fbd83d
 
9fbd83d
   /* This only happens when setting the property during object construction */
9fbd83d
   if (!priv->trays_screen)
9fbd83d
@@ -399,8 +417,38 @@ update_size_and_orientation (NaTray *tray)
9fbd83d
       gtk_widget_set_size_request (priv->box, -1, MIN_BOX_SIZE);
9fbd83d
       break;
9fbd83d
     }
9fbd83d
+}
9fbd83d
 
9fbd83d
-  na_tray_force_redraw (tray);
9fbd83d
+/* Children with alpha channels have been set to be composited by calling
9fbd83d
+ * gdk_window_set_composited(). We need to paint these children ourselves.
9fbd83d
+ */
9fbd83d
+static void
9fbd83d
+na_tray_expose_icon (GtkWidget *widget,
9fbd83d
+		     gpointer   data)
9fbd83d
+{
9fbd83d
+  cairo_t *cr = data;
9fbd83d
+
9fbd83d
+  if (na_tray_child_has_alpha (NA_TRAY_CHILD (widget)))
9fbd83d
+    {
9fbd83d
+      gdk_cairo_set_source_pixmap (cr, widget->window,
9fbd83d
+				   widget->allocation.x,
9fbd83d
+				   widget->allocation.y);
9fbd83d
+      cairo_paint (cr);
9fbd83d
+    }
9fbd83d
+}
9fbd83d
+
9fbd83d
+static void
9fbd83d
+na_tray_expose_box (GtkWidget      *box,
9fbd83d
+		    GdkEventExpose *event)
9fbd83d
+{
9fbd83d
+  cairo_t *cr = gdk_cairo_create (box->window);
9fbd83d
+
9fbd83d
+  gdk_cairo_region (cr, event->region);
9fbd83d
+  cairo_clip (cr);
9fbd83d
+
9fbd83d
+  gtk_container_foreach (GTK_CONTAINER (box), na_tray_expose_icon, cr);
9fbd83d
+
9fbd83d
+  cairo_destroy (cr);
9fbd83d
 }
9fbd83d
 
9fbd83d
 static void
9fbd83d
@@ -417,7 +465,9 @@ na_tray_init (NaTray *tray)
9fbd83d
   gtk_container_add (GTK_CONTAINER (tray), priv->frame);
9fbd83d
   gtk_widget_show (priv->frame);
9fbd83d
 
9fbd83d
-  priv->box = na_obox_new ();
9fbd83d
+  priv->box = g_object_new (na_box_get_type (), NULL);
9fbd83d
+  g_signal_connect (priv->box, "expose-event",
9fbd83d
+		    G_CALLBACK (na_tray_expose_box), tray);
9fbd83d
   gtk_box_set_spacing (GTK_BOX (priv->box), ICON_SPACING);
9fbd83d
   gtk_container_add (GTK_CONTAINER (priv->frame), priv->box);
9fbd83d
   gtk_widget_show (priv->box);
9fbd83d
@@ -658,9 +708,9 @@ idle_redraw_cb (NaTray *tray)
9fbd83d
 {
9fbd83d
   NaTrayPrivate *priv = tray->priv;
9fbd83d
 
9fbd83d
+  gtk_container_foreach (GTK_CONTAINER (priv->box), (GtkCallback)na_tray_child_force_redraw, tray);
9fbd83d
+  
9fbd83d
   priv->idle_redraw_id = 0;
9fbd83d
-  gtk_widget_hide (priv->box);
9fbd83d
-  gtk_widget_show (priv->box);
9fbd83d
 
9fbd83d
   return FALSE;
9fbd83d
 }
9fbd83d
@@ -671,8 +721,6 @@ na_tray_force_redraw (NaTray *tray)
9fbd83d
   NaTrayPrivate *priv = tray->priv;
9fbd83d
 
9fbd83d
   /* Force the icons to redraw their backgrounds.
9fbd83d
-   * gtk_widget_queue_draw() doesn't work across process boundaries,
9fbd83d
-   * so we do this instead.
9fbd83d
    */
9fbd83d
   if (priv->idle_redraw_id == 0)
9fbd83d
     priv->idle_redraw_id = g_idle_add ((GSourceFunc) idle_redraw_cb, tray);
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.h b/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
index f67062b..57baddd 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
@@ -24,10 +24,10 @@
9fbd83d
 #ifndef __NA_TRAY_H__
9fbd83d
 #define __NA_TRAY_H__
9fbd83d
 
9fbd83d
-#include <gtk/gtk.h>
9fbd83d
 #ifdef GDK_WINDOWING_X11
9fbd83d
 #include <gdk/gdkx.h>
9fbd83d
 #endif
9fbd83d
+#include <gtk/gtk.h>
9fbd83d
 
9fbd83d
 G_BEGIN_DECLS
9fbd83d
 
9fbd83d
@@ -41,7 +41,6 @@ G_BEGIN_DECLS
9fbd83d
 typedef struct _NaTray		NaTray;
9fbd83d
 typedef struct _NaTrayPrivate	NaTrayPrivate;
9fbd83d
 typedef struct _NaTrayClass	NaTrayClass;
9fbd83d
-typedef struct _NaTrayChild	NaTrayChild;
9fbd83d
 
9fbd83d
 struct _NaTray
9fbd83d
 {
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/testtray.c b/gui/simple-greeter/libnotificationarea/testtray.c
9fbd83d
index 42d3732..c0300b6 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/testtray.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/testtray.c
9fbd83d
@@ -66,7 +66,7 @@ static void
9fbd83d
 tray_added_cb (GtkContainer *box, GtkWidget *icon, TrayData *data)
9fbd83d
 {
9fbd83d
   g_print ("[Screen %u tray %p] Child %p added to tray: \"%s\"\n",
9fbd83d
-	   data->screen_num, data->tray, icon, "XXX");//na_tray_manager_get_child_title (manager, icon));
9fbd83d
+	   data->screen_num, data->tray, icon, "XXX");//na_tray_child_get_title (icon));
9fbd83d
 
9fbd83d
   update_child_count (data);
9fbd83d
 }
9fbd83d
-- 
9fbd83d
1.6.5.rc2
9fbd83d
9fbd83d
9fbd83d
From b2bd208cd0057e25b0aac380d519376b243537e0 Mon Sep 17 00:00:00 2001
9fbd83d
From: Ray Strode <rstrode@redhat.com>
9fbd83d
Date: Thu, 22 Oct 2009 22:07:52 -0400
9fbd83d
Subject: [PATCH 2/4] Add ordering patch to na-tray
9fbd83d
9fbd83d
This makes sure system utilities come up in the right order.
9fbd83d
---
9fbd83d
 .../libnotificationarea/na-tray-child.c            |   81 ++++++++++++++++++
9fbd83d
 .../libnotificationarea/na-tray-child.h            |    5 +-
9fbd83d
 gui/simple-greeter/libnotificationarea/na-tray.c   |   89 +++++++++++++++++++-
9fbd83d
 3 files changed, 172 insertions(+), 3 deletions(-)
9fbd83d
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.c b/gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
index c7e3f61..98769bd 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.c
9fbd83d
@@ -428,3 +428,84 @@ na_tray_child_force_redraw (NaTrayChild *child)
9fbd83d
 #endif
9fbd83d
     }
9fbd83d
 }
9fbd83d
+
9fbd83d
+
9fbd83d
+/* from libwnck xutils.c */
9fbd83d
+static char *
9fbd83d
+latin1_to_utf8 (const char *latin1)
9fbd83d
+{
9fbd83d
+  GString *str;
9fbd83d
+  const char *p;
9fbd83d
+
9fbd83d
+  str = g_string_new (NULL);
9fbd83d
+
9fbd83d
+  p = latin1;
9fbd83d
+  while (*p)
9fbd83d
+    {
9fbd83d
+      g_string_append_unichar (str, (gunichar) *p);
9fbd83d
+      ++p;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  return g_string_free (str, FALSE);
9fbd83d
+}
9fbd83d
+
9fbd83d
+/* derived from libwnck xutils.c */
9fbd83d
+static void
9fbd83d
+_get_wmclass (Display *xdisplay,
9fbd83d
+              Window   xwindow,
9fbd83d
+              char   **res_class,
9fbd83d
+              char   **res_name)
9fbd83d
+{
9fbd83d
+  XClassHint ch;
9fbd83d
+  char *retval;
9fbd83d
+
9fbd83d
+  gdk_error_trap_push ();
9fbd83d
+
9fbd83d
+  ch.res_name = NULL;
9fbd83d
+  ch.res_class = NULL;
9fbd83d
+
9fbd83d
+  XGetClassHint (xdisplay, xwindow, &ch);
9fbd83d
+
9fbd83d
+  gdk_error_trap_pop ();
9fbd83d
+
9fbd83d
+  retval = NULL;
9fbd83d
+
9fbd83d
+  if (res_class)
9fbd83d
+    *res_class = NULL;
9fbd83d
+
9fbd83d
+  if (res_name)
9fbd83d
+    *res_name = NULL;
9fbd83d
+
9fbd83d
+  if (ch.res_name)
9fbd83d
+    {
9fbd83d
+      if (res_name)
9fbd83d
+        *res_name = latin1_to_utf8 (ch.res_name);
9fbd83d
+
9fbd83d
+      XFree (ch.res_name);
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  if (ch.res_class)
9fbd83d
+    {
9fbd83d
+      if (res_class)
9fbd83d
+        *res_class = latin1_to_utf8 (ch.res_class);
9fbd83d
+
9fbd83d
+      XFree (ch.res_class);
9fbd83d
+    }
9fbd83d
+}
9fbd83d
+
9fbd83d
+void
9fbd83d
+na_tray_child_get_wm_class (NaTrayChild *child,
9fbd83d
+                            char **res_name,
9fbd83d
+                            char **res_class)
9fbd83d
+{
9fbd83d
+  GdkDisplay *display;
9fbd83d
+
9fbd83d
+  g_return_if_fail (NA_IS_TRAY_CHILD (child));
9fbd83d
+
9fbd83d
+  display = gtk_widget_get_display (GTK_WIDGET (child));
9fbd83d
+
9fbd83d
+  _get_wmclass (GDK_DISPLAY_XDISPLAY (display),
9fbd83d
+                child->icon_window,
9fbd83d
+                res_class,
9fbd83d
+                res_name);
9fbd83d
+}
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.h b/gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
index c174abe..ff036a7 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.h
9fbd83d
@@ -61,7 +61,10 @@ char           *na_tray_child_get_title      (NaTrayChild *child);
9fbd83d
 gboolean        na_tray_child_has_alpha      (NaTrayChild *child);
9fbd83d
 void            na_tray_child_set_composited (NaTrayChild *child,
9fbd83d
                                               gboolean     composited);
9fbd83d
-void            na_tray_child_force_redraw   (NaTrayChild *child);
9fbd83d
+void            na_tray_child_force_redraw   (NaTrayChild  *child);
9fbd83d
+void            na_tray_child_get_wm_class   (NaTrayChild  *child,
9fbd83d
+					      char        **res_name,
9fbd83d
+			     		      char        **res_class);
9fbd83d
 
9fbd83d
 G_END_DECLS
9fbd83d
 
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
index 051a811..3bd1258 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
@@ -114,6 +114,51 @@ get_tray (TraysScreen *trays_screen)
9fbd83d
   return trays_screen->all_trays->data;
9fbd83d
 }
9fbd83d
 
9fbd83d
+const char *roles[] = {
9fbd83d
+  "keyboard",
9fbd83d
+  "volume",
9fbd83d
+  "bluetooth",
9fbd83d
+  "network",
9fbd83d
+  "battery",
9fbd83d
+  NULL
9fbd83d
+};
9fbd83d
+
9fbd83d
+const char *wmclass_roles[] = {
9fbd83d
+  "Bluetooth-applet", "bluetooth",
9fbd83d
+  "Gnome-volume-control-applet", "volume",
9fbd83d
+  "Nm-applet", "network",
9fbd83d
+  "Gnome-power-manager", "battery",
9fbd83d
+  NULL,
9fbd83d
+};
9fbd83d
+
9fbd83d
+static const char *
9fbd83d
+find_role (const char *wmclass)
9fbd83d
+{
9fbd83d
+  int i;
9fbd83d
+
9fbd83d
+  for (i = 0; wmclass_roles[i]; i += 2)
9fbd83d
+    {
9fbd83d
+      if (strcmp (wmclass, wmclass_roles[i]) == 0)
9fbd83d
+        return wmclass_roles[i + 1];
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  return NULL;
9fbd83d
+}
9fbd83d
+
9fbd83d
+static int
9fbd83d
+find_role_pos (const char *role)
9fbd83d
+{
9fbd83d
+  int i;
9fbd83d
+
9fbd83d
+  for (i = 0; roles[i]; i++)
9fbd83d
+    {
9fbd83d
+      if (strcmp (role, roles[i]) == 0)
9fbd83d
+        break;
9fbd83d
+    }
9fbd83d
+
9fbd83d
+  return i + 1;
9fbd83d
+}
9fbd83d
+
9fbd83d
 static void
9fbd83d
 tray_added (NaTrayManager *manager,
9fbd83d
             GtkWidget     *icon,
9fbd83d
@@ -121,6 +166,11 @@ tray_added (NaTrayManager *manager,
9fbd83d
 {
9fbd83d
   NaTray *tray;
9fbd83d
   NaTrayPrivate *priv;
9fbd83d
+  GList *l, *children;
9fbd83d
+  int position;
9fbd83d
+  char *class_a;
9fbd83d
+  const char *role;
9fbd83d
+  int role_position;
9fbd83d
 
9fbd83d
   tray = get_tray (trays_screen);
9fbd83d
   if (tray == NULL)
9fbd83d
@@ -129,10 +179,45 @@ tray_added (NaTrayManager *manager,
9fbd83d
   priv = tray->priv;
9fbd83d
 
9fbd83d
   g_assert (priv->trays_screen == trays_screen);
9fbd83d
-  
9fbd83d
+
9fbd83d
   g_hash_table_insert (trays_screen->icon_table, icon, tray);
9fbd83d
 
9fbd83d
-  gtk_box_pack_end (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
9fbd83d
+  position = 0;
9fbd83d
+
9fbd83d
+  class_a = NULL;
9fbd83d
+  na_tray_child_get_wm_class (NA_TRAY_CHILD (icon), NULL, &class_a);
9fbd83d
+  if (!class_a)
9fbd83d
+    goto insert;
9fbd83d
+
9fbd83d
+  role = find_role (class_a);
9fbd83d
+  g_free (class_a);
9fbd83d
+  if (!role)
9fbd83d
+    goto insert;
9fbd83d
+
9fbd83d
+  role_position = find_role_pos (role);
9fbd83d
+  g_object_set_data (G_OBJECT (icon), "role-position", GINT_TO_POINTER (role_position));
9fbd83d
+
9fbd83d
+  children = gtk_container_get_children (GTK_CONTAINER (priv->box));
9fbd83d
+  for (l = g_list_last (children); l; l = l->prev)
9fbd83d
+    {
9fbd83d
+      GtkWidget *child = l->data;
9fbd83d
+      gint rp;
9fbd83d
+
9fbd83d
+      rp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "role-position"));
9fbd83d
+      if (rp == 0 || rp < role_position)
9fbd83d
+        {
9fbd83d
+          position = g_list_index (children, child) + 1;
9fbd83d
+          break;
9fbd83d
+        }
9fbd83d
+    }
9fbd83d
+  g_list_free (children);
9fbd83d
+
9fbd83d
+  if (position < 0)
9fbd83d
+    position = 0;
9fbd83d
+
9fbd83d
+insert:
9fbd83d
+  gtk_box_pack_start (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
9fbd83d
+  gtk_box_reorder_child (GTK_BOX (priv->box), icon, position);
9fbd83d
 
9fbd83d
   gtk_widget_show (icon);
9fbd83d
 }
9fbd83d
-- 
9fbd83d
1.6.5.rc2
9fbd83d
9fbd83d
9fbd83d
From ab7c74cca138c404338ebaf3ee3c1e3f6e92f083 Mon Sep 17 00:00:00 2001
9fbd83d
From: Ray Strode <rstrode@redhat.com>
9fbd83d
Date: Thu, 22 Oct 2009 22:08:18 -0400
9fbd83d
Subject: [PATCH 3/4] Add the ability to have padding between icons in tray
9fbd83d
9fbd83d
---
9fbd83d
 .../libnotificationarea/na-tray-manager.c          |   41 ++++++++++++++++++++
9fbd83d
 .../libnotificationarea/na-tray-manager.h          |    3 +
9fbd83d
 gui/simple-greeter/libnotificationarea/na-tray.c   |   12 ++++++
9fbd83d
 gui/simple-greeter/libnotificationarea/na-tray.h   |    2 +
9fbd83d
 4 files changed, 58 insertions(+), 0 deletions(-)
9fbd83d
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.c b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
index 1bf54f1..d49c646 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
9fbd83d
@@ -653,6 +653,32 @@ na_tray_manager_set_visual_property (NaTrayManager *manager)
9fbd83d
 #endif
9fbd83d
 }
9fbd83d
 
9fbd83d
+static void
9fbd83d
+na_tray_manager_set_padding_property (NaTrayManager *manager)
9fbd83d
+{
9fbd83d
+#ifdef GDK_WINDOWING_X11
9fbd83d
+  GdkDisplay *display;
9fbd83d
+  Atom        orientation_atom;
9fbd83d
+  gulong      data[1];
9fbd83d
+
9fbd83d
+  if (!manager->invisible || !manager->invisible->window)
9fbd83d
+    return;
9fbd83d
+
9fbd83d
+  display = gtk_widget_get_display (manager->invisible);
9fbd83d
+  orientation_atom = gdk_x11_get_xatom_by_name_for_display (display,
9fbd83d
+                                                            "_NET_SYSTEM_TRAY_PADDING");
9fbd83d
+
9fbd83d
+  data[0] = manager->padding;
9fbd83d
+
9fbd83d
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
9fbd83d
+		   GDK_WINDOW_XWINDOW (manager->invisible->window),
9fbd83d
+                   orientation_atom,
9fbd83d
+		   XA_CARDINAL, 32,
9fbd83d
+		   PropModeReplace,
9fbd83d
+		   (guchar *) &data, 1);
9fbd83d
+#endif
9fbd83d
+}
9fbd83d
+
9fbd83d
 #ifdef GDK_WINDOWING_X11
9fbd83d
 
9fbd83d
 static gboolean
9fbd83d
@@ -697,6 +723,7 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
9fbd83d
 
9fbd83d
   na_tray_manager_set_orientation_property (manager);
9fbd83d
   na_tray_manager_set_visual_property (manager);
9fbd83d
+  na_tray_manager_set_padding_property (manager);
9fbd83d
   
9fbd83d
   timestamp = gdk_x11_get_server_time (invisible->window);
9fbd83d
 
9fbd83d
@@ -836,6 +863,20 @@ na_tray_manager_set_orientation (NaTrayManager  *manager,
9fbd83d
     }
9fbd83d
 }
9fbd83d
 
9fbd83d
+void
9fbd83d
+na_tray_manager_set_padding (NaTrayManager *manager,
9fbd83d
+                             gint           padding)
9fbd83d
+{
9fbd83d
+  g_return_if_fail (NA_IS_TRAY_MANAGER (manager));
9fbd83d
+
9fbd83d
+  if (manager->padding != padding)
9fbd83d
+    {
9fbd83d
+      manager->padding = padding;
9fbd83d
+
9fbd83d
+      na_tray_manager_set_padding_property (manager);
9fbd83d
+    }
9fbd83d
+}
9fbd83d
+
9fbd83d
 GtkOrientation
9fbd83d
 na_tray_manager_get_orientation (NaTrayManager *manager)
9fbd83d
 {
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.h b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
index f325453..e93882e 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
9fbd83d
@@ -55,6 +55,7 @@ struct _NaTrayManager
9fbd83d
   GtkWidget *invisible;
9fbd83d
   GdkScreen *screen;
9fbd83d
   GtkOrientation orientation;
9fbd83d
+  gint padding;
9fbd83d
 
9fbd83d
   GList *messages;
9fbd83d
   GHashTable *socket_table;
9fbd83d
@@ -91,6 +92,8 @@ gboolean        na_tray_manager_manage_screen   (NaTrayManager      *manager,
9fbd83d
 void            na_tray_manager_set_orientation (NaTrayManager      *manager,
9fbd83d
 						 GtkOrientation      orientation);
9fbd83d
 GtkOrientation  na_tray_manager_get_orientation (NaTrayManager      *manager);
9fbd83d
+void            na_tray_manager_set_padding      (NaTrayManager      *manager,
9fbd83d
+						  gint                padding);
9fbd83d
 
9fbd83d
 G_END_DECLS
9fbd83d
 
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
index 3bd1258..40845c1 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
9fbd83d
@@ -599,6 +599,8 @@ na_tray_constructor (GType type,
9fbd83d
         {
9fbd83d
           trays_screens [screen_number].tray_manager = tray_manager;
9fbd83d
 
9fbd83d
+          na_tray_manager_set_padding (tray_manager, 0);
9fbd83d
+
9fbd83d
           g_signal_connect (tray_manager, "tray_icon_added",
9fbd83d
                             G_CALLBACK (tray_added),
9fbd83d
                             &trays_screens [screen_number]);
9fbd83d
@@ -801,6 +803,16 @@ idle_redraw_cb (NaTray *tray)
9fbd83d
 }
9fbd83d
 
9fbd83d
 void
9fbd83d
+na_tray_set_padding (NaTray *tray,
9fbd83d
+                     gint    padding)
9fbd83d
+{
9fbd83d
+  NaTrayPrivate *priv = tray->priv;
9fbd83d
+
9fbd83d
+  if (get_tray (priv->trays_screen) == tray)
9fbd83d
+    na_tray_manager_set_padding (priv->trays_screen->tray_manager, padding);
9fbd83d
+}
9fbd83d
+
9fbd83d
+void
9fbd83d
 na_tray_force_redraw (NaTray *tray)
9fbd83d
 {
9fbd83d
   NaTrayPrivate *priv = tray->priv;
9fbd83d
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.h b/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
index 57baddd..1ead20f 100644
9fbd83d
--- a/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
+++ b/gui/simple-greeter/libnotificationarea/na-tray.h
9fbd83d
@@ -60,6 +60,8 @@ NaTray         *na_tray_new_for_screen  (GdkScreen     *screen,
9fbd83d
 void            na_tray_set_orientation	(NaTray        *tray,
9fbd83d
 					 GtkOrientation orientation);
9fbd83d
 GtkOrientation  na_tray_get_orientation (NaTray        *tray);
9fbd83d
+void            na_tray_set_padding     (NaTray        *tray,
9fbd83d
+                                         gint           padding);
9fbd83d
 void		na_tray_force_redraw	(NaTray        *tray);
9fbd83d
 
9fbd83d
 G_END_DECLS
9fbd83d
-- 
9fbd83d
1.6.5.rc2
9fbd83d
9fbd83d
9fbd83d
From 050879701489074492a35b0427f0ac7cf21ebf82 Mon Sep 17 00:00:00 2001
9fbd83d
From: Ray Strode <rstrode@redhat.com>
9fbd83d
Date: Thu, 22 Oct 2009 22:13:58 -0400
9fbd83d
Subject: [PATCH 4/4] Read padding from notification area applet and use it.
9fbd83d
9fbd83d
---
9fbd83d
 gui/simple-greeter/gdm-greeter-panel.c |    5 +++++
9fbd83d
 1 files changed, 5 insertions(+), 0 deletions(-)
9fbd83d
9fbd83d
diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
9fbd83d
index 03c4122..43b91d5 100644
9fbd83d
--- a/gui/simple-greeter/gdm-greeter-panel.c
9fbd83d
+++ b/gui/simple-greeter/gdm-greeter-panel.c
9fbd83d
@@ -65,6 +65,7 @@
9fbd83d
 #define GPM_DBUS_INTERFACE "org.freedesktop.PowerManagement"
9fbd83d
 
9fbd83d
 #define KEY_DISABLE_RESTART_BUTTONS "/apps/gdm/simple-greeter/disable_restart_buttons"
9fbd83d
+#define KEY_NOTIFICATION_AREA_PADDING "/apps/notification_area_applet/prefs/padding"
9fbd83d
 
9fbd83d
 #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
9fbd83d
 
9fbd83d
@@ -824,6 +825,7 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
9fbd83d
 {
9fbd83d
         NaTray    *tray;
9fbd83d
         GtkWidget *spacer;
9fbd83d
+        int padding;
9fbd83d
 
9fbd83d
         gdm_profile_start (NULL);
9fbd83d
 
9fbd83d
@@ -955,6 +957,9 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
9fbd83d
 
9fbd83d
         tray = na_tray_new_for_screen (gtk_window_get_screen (GTK_WINDOW (panel)),
9fbd83d
                                        GTK_ORIENTATION_HORIZONTAL);
9fbd83d
+
9fbd83d
+        padding = gconf_client_get_int (panel->priv->client, KEY_NOTIFICATION_AREA_PADDING, NULL);
9fbd83d
+        na_tray_set_padding (tray, padding);
9fbd83d
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6);
9fbd83d
         gtk_widget_show (GTK_WIDGET (tray));
9fbd83d
         gdm_greeter_panel_hide_user_options (panel);
9fbd83d
-- 
9fbd83d
1.6.5.rc2
9fbd83d