rpms/gdm/F-12 fix-na-tray.patch, NONE, 1.1 fix-timer.patch, NONE, 1.1 gdm-2.28.1-move-shutdown-functions.patch, 1.1, 1.2 gdm-multistack.patch, 1.1, 1.2 gdm.spec, 1.498, 1.499

Ray Strode rstrode at fedoraproject.org
Fri Oct 23 02:27:30 UTC 2009


Author: rstrode

Update of /cvs/pkgs/rpms/gdm/F-12
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv11344

Modified Files:
	gdm-2.28.1-move-shutdown-functions.patch gdm-multistack.patch 
	gdm.spec 
Added Files:
	fix-na-tray.patch fix-timer.patch 
Log Message:
- Fix autologin window spasms
- Fix autologin timer animation
- Make autologin and multistack play better together
- Add padding to notification tray


fix-na-tray.patch:
 b/gui/simple-greeter/gdm-greeter-panel.c                   |    6 
 b/gui/simple-greeter/libnotificationarea/Makefile.am       |    2 
 b/gui/simple-greeter/libnotificationarea/fixedtip.c        |    1 
 b/gui/simple-greeter/libnotificationarea/na-tray-child.c   |  430 +++++++++++++
 b/gui/simple-greeter/libnotificationarea/na-tray-child.h   |   68 ++
 b/gui/simple-greeter/libnotificationarea/na-tray-manager.c |  264 +++----
 b/gui/simple-greeter/libnotificationarea/na-tray-manager.h |   15 
 b/gui/simple-greeter/libnotificationarea/na-tray.c         |   76 +-
 b/gui/simple-greeter/libnotificationarea/na-tray.h         |    3 
 b/gui/simple-greeter/libnotificationarea/testtray.c        |    3 
 gui/simple-greeter/libnotificationarea/na-tray-child.c     |   81 ++
 gui/simple-greeter/libnotificationarea/na-tray-child.h     |    5 
 gui/simple-greeter/libnotificationarea/na-tray-manager.c   |   41 +
 gui/simple-greeter/libnotificationarea/na-tray-manager.h   |    3 
 gui/simple-greeter/libnotificationarea/na-tray.c           |  102 ++-
 gui/simple-greeter/libnotificationarea/na-tray.h           |    3 
 16 files changed, 909 insertions(+), 194 deletions(-)

--- NEW FILE fix-na-tray.patch ---
>From f304eec1bf7dd80e255092b3cdaade10827fd320 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 22:02:51 -0400
Subject: [PATCH 1/4] Update na-tray to latest upstream code

It's a copy and paste from the panel.
---
 gui/simple-greeter/libnotificationarea/Makefile.am |    2 +
 gui/simple-greeter/libnotificationarea/fixedtip.c  |    1 +
 .../libnotificationarea/na-tray-child.c            |  430 ++++++++++++++++++++
 .../libnotificationarea/na-tray-child.h            |   68 +++
 .../libnotificationarea/na-tray-manager.c          |  264 +++++--------
 .../libnotificationarea/na-tray-manager.h          |   15 +-
 gui/simple-greeter/libnotificationarea/na-tray.c   |   76 +++-
 gui/simple-greeter/libnotificationarea/na-tray.h   |    3 +-
 gui/simple-greeter/libnotificationarea/testtray.c  |    2 +-
 9 files changed, 674 insertions(+), 187 deletions(-)
 create mode 100644 gui/simple-greeter/libnotificationarea/na-tray-child.c
 create mode 100644 gui/simple-greeter/libnotificationarea/na-tray-child.h

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


>From b2bd208cd0057e25b0aac380d519376b243537e0 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 22:07:52 -0400
Subject: [PATCH 2/4] Add ordering patch to na-tray

This makes sure system utilities come up in the right order.
---
 .../libnotificationarea/na-tray-child.c            |   81 ++++++++++++++++++
 .../libnotificationarea/na-tray-child.h            |    5 +-
 gui/simple-greeter/libnotificationarea/na-tray.c   |   89 +++++++++++++++++++-
 3 files changed, 172 insertions(+), 3 deletions(-)

diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.c b/gui/simple-greeter/libnotificationarea/na-tray-child.c
index c7e3f61..98769bd 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-child.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.c
@@ -428,3 +428,84 @@ na_tray_child_force_redraw (NaTrayChild *child)
 #endif
     }
 }
+
+
+/* from libwnck xutils.c */
+static char *
+latin1_to_utf8 (const char *latin1)
+{
+  GString *str;
+  const char *p;
+
+  str = g_string_new (NULL);
+
+  p = latin1;
+  while (*p)
+    {
+      g_string_append_unichar (str, (gunichar) *p);
+      ++p;
+    }
+
+  return g_string_free (str, FALSE);
+}
+
+/* derived from libwnck xutils.c */
+static void
+_get_wmclass (Display *xdisplay,
+              Window   xwindow,
+              char   **res_class,
+              char   **res_name)
+{
+  XClassHint ch;
+  char *retval;
+
+  gdk_error_trap_push ();
+
+  ch.res_name = NULL;
+  ch.res_class = NULL;
+
+  XGetClassHint (xdisplay, xwindow, &ch);
+
+  gdk_error_trap_pop ();
+
+  retval = NULL;
+
+  if (res_class)
+    *res_class = NULL;
+
+  if (res_name)
+    *res_name = NULL;
+
+  if (ch.res_name)
+    {
+      if (res_name)
+        *res_name = latin1_to_utf8 (ch.res_name);
+
+      XFree (ch.res_name);
+    }
+
+  if (ch.res_class)
+    {
+      if (res_class)
+        *res_class = latin1_to_utf8 (ch.res_class);
+
+      XFree (ch.res_class);
+    }
+}
+
+void
+na_tray_child_get_wm_class (NaTrayChild *child,
+                            char **res_name,
+                            char **res_class)
+{
+  GdkDisplay *display;
+
+  g_return_if_fail (NA_IS_TRAY_CHILD (child));
+
+  display = gtk_widget_get_display (GTK_WIDGET (child));
+
+  _get_wmclass (GDK_DISPLAY_XDISPLAY (display),
+                child->icon_window,
+                res_class,
+                res_name);
+}
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.h b/gui/simple-greeter/libnotificationarea/na-tray-child.h
index c174abe..ff036a7 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-child.h
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.h
@@ -61,7 +61,10 @@ char           *na_tray_child_get_title      (NaTrayChild *child);
 gboolean        na_tray_child_has_alpha      (NaTrayChild *child);
 void            na_tray_child_set_composited (NaTrayChild *child,
                                               gboolean     composited);
-void            na_tray_child_force_redraw   (NaTrayChild *child);
+void            na_tray_child_force_redraw   (NaTrayChild  *child);
+void            na_tray_child_get_wm_class   (NaTrayChild  *child,
+					      char        **res_name,
+			     		      char        **res_class);
 
 G_END_DECLS
 
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
index 051a811..3bd1258 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
@@ -114,6 +114,51 @@ get_tray (TraysScreen *trays_screen)
   return trays_screen->all_trays->data;
 }
 
+const char *roles[] = {
+  "keyboard",
+  "volume",
+  "bluetooth",
+  "network",
+  "battery",
+  NULL
+};
+
+const char *wmclass_roles[] = {
+  "Bluetooth-applet", "bluetooth",
+  "Gnome-volume-control-applet", "volume",
+  "Nm-applet", "network",
+  "Gnome-power-manager", "battery",
+  NULL,
+};
+
+static const char *
+find_role (const char *wmclass)
+{
+  int i;
+
+  for (i = 0; wmclass_roles[i]; i += 2)
+    {
+      if (strcmp (wmclass, wmclass_roles[i]) == 0)
+        return wmclass_roles[i + 1];
+    }
+
+  return NULL;
+}
+
+static int
+find_role_pos (const char *role)
+{
+  int i;
+
+  for (i = 0; roles[i]; i++)
+    {
+      if (strcmp (role, roles[i]) == 0)
+        break;
+    }
+
+  return i + 1;
+}
+
 static void
 tray_added (NaTrayManager *manager,
             GtkWidget     *icon,
@@ -121,6 +166,11 @@ tray_added (NaTrayManager *manager,
 {
   NaTray *tray;
   NaTrayPrivate *priv;
+  GList *l, *children;
+  int position;
+  char *class_a;
+  const char *role;
+  int role_position;
 
   tray = get_tray (trays_screen);
   if (tray == NULL)
@@ -129,10 +179,45 @@ tray_added (NaTrayManager *manager,
   priv = tray->priv;
 
   g_assert (priv->trays_screen == trays_screen);
-  
+
   g_hash_table_insert (trays_screen->icon_table, icon, tray);
 
-  gtk_box_pack_end (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
+  position = 0;
+
+  class_a = NULL;
+  na_tray_child_get_wm_class (NA_TRAY_CHILD (icon), NULL, &class_a);
+  if (!class_a)
+    goto insert;
+
+  role = find_role (class_a);
+  g_free (class_a);
+  if (!role)
+    goto insert;
+
+  role_position = find_role_pos (role);
+  g_object_set_data (G_OBJECT (icon), "role-position", GINT_TO_POINTER (role_position));
+
+  children = gtk_container_get_children (GTK_CONTAINER (priv->box));
+  for (l = g_list_last (children); l; l = l->prev)
+    {
+      GtkWidget *child = l->data;
+      gint rp;
+
+      rp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "role-position"));
+      if (rp == 0 || rp < role_position)
+        {
+          position = g_list_index (children, child) + 1;
+          break;
+        }
+    }
+  g_list_free (children);
+
+  if (position < 0)
+    position = 0;
+
+insert:
+  gtk_box_pack_start (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
+  gtk_box_reorder_child (GTK_BOX (priv->box), icon, position);
 
   gtk_widget_show (icon);
 }
-- 
1.6.5.rc2


>From ab7c74cca138c404338ebaf3ee3c1e3f6e92f083 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 22:08:18 -0400
Subject: [PATCH 3/4] Add the ability to have padding between icons in tray

---
 .../libnotificationarea/na-tray-manager.c          |   41 ++++++++++++++++++++
 .../libnotificationarea/na-tray-manager.h          |    3 +
 gui/simple-greeter/libnotificationarea/na-tray.c   |   12 ++++++
 gui/simple-greeter/libnotificationarea/na-tray.h   |    2 +
 4 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.c b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
index 1bf54f1..d49c646 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
@@ -653,6 +653,32 @@ na_tray_manager_set_visual_property (NaTrayManager *manager)
 #endif
 }
 
+static void
+na_tray_manager_set_padding_property (NaTrayManager *manager)
+{
+#ifdef GDK_WINDOWING_X11
+  GdkDisplay *display;
+  Atom        orientation_atom;
+  gulong      data[1];
+
+  if (!manager->invisible || !manager->invisible->window)
+    return;
+
+  display = gtk_widget_get_display (manager->invisible);
+  orientation_atom = gdk_x11_get_xatom_by_name_for_display (display,
+                                                            "_NET_SYSTEM_TRAY_PADDING");
+
+  data[0] = manager->padding;
+
+  XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
+		   GDK_WINDOW_XWINDOW (manager->invisible->window),
+                   orientation_atom,
+		   XA_CARDINAL, 32,
+		   PropModeReplace,
+		   (guchar *) &data, 1);
+#endif
+}
+
 #ifdef GDK_WINDOWING_X11
 
 static gboolean
@@ -697,6 +723,7 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
 
   na_tray_manager_set_orientation_property (manager);
   na_tray_manager_set_visual_property (manager);
+  na_tray_manager_set_padding_property (manager);
   
   timestamp = gdk_x11_get_server_time (invisible->window);
 
@@ -836,6 +863,20 @@ na_tray_manager_set_orientation (NaTrayManager  *manager,
     }
 }
 
+void
+na_tray_manager_set_padding (NaTrayManager *manager,
+                             gint           padding)
+{
+  g_return_if_fail (NA_IS_TRAY_MANAGER (manager));
+
+  if (manager->padding != padding)
+    {
+      manager->padding = padding;
+
+      na_tray_manager_set_padding_property (manager);
+    }
+}
+
 GtkOrientation
 na_tray_manager_get_orientation (NaTrayManager *manager)
 {
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.h b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
index f325453..e93882e 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.h
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.h
@@ -55,6 +55,7 @@ struct _NaTrayManager
   GtkWidget *invisible;
   GdkScreen *screen;
   GtkOrientation orientation;
+  gint padding;
 
   GList *messages;
   GHashTable *socket_table;
@@ -91,6 +92,8 @@ gboolean        na_tray_manager_manage_screen   (NaTrayManager      *manager,
 void            na_tray_manager_set_orientation (NaTrayManager      *manager,
 						 GtkOrientation      orientation);
 GtkOrientation  na_tray_manager_get_orientation (NaTrayManager      *manager);
+void            na_tray_manager_set_padding      (NaTrayManager      *manager,
+						  gint                padding);
 
 G_END_DECLS
 
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
index 3bd1258..40845c1 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
@@ -599,6 +599,8 @@ na_tray_constructor (GType type,
         {
           trays_screens [screen_number].tray_manager = tray_manager;
 
+          na_tray_manager_set_padding (tray_manager, 0);
+
           g_signal_connect (tray_manager, "tray_icon_added",
                             G_CALLBACK (tray_added),
                             &trays_screens [screen_number]);
@@ -801,6 +803,16 @@ idle_redraw_cb (NaTray *tray)
 }
 
 void
+na_tray_set_padding (NaTray *tray,
+                     gint    padding)
+{
+  NaTrayPrivate *priv = tray->priv;
+
+  if (get_tray (priv->trays_screen) == tray)
+    na_tray_manager_set_padding (priv->trays_screen->tray_manager, padding);
+}
+
+void
 na_tray_force_redraw (NaTray *tray)
 {
   NaTrayPrivate *priv = tray->priv;
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.h b/gui/simple-greeter/libnotificationarea/na-tray.h
index 57baddd..1ead20f 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray.h
+++ b/gui/simple-greeter/libnotificationarea/na-tray.h
@@ -60,6 +60,8 @@ NaTray         *na_tray_new_for_screen  (GdkScreen     *screen,
 void            na_tray_set_orientation	(NaTray        *tray,
 					 GtkOrientation orientation);
 GtkOrientation  na_tray_get_orientation (NaTray        *tray);
+void            na_tray_set_padding     (NaTray        *tray,
+                                         gint           padding);
 void		na_tray_force_redraw	(NaTray        *tray);
 
 G_END_DECLS
-- 
1.6.5.rc2


>From 050879701489074492a35b0427f0ac7cf21ebf82 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 22:13:58 -0400
Subject: [PATCH 4/4] Read padding from notification area applet and use it.

---
 gui/simple-greeter/gdm-greeter-panel.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
index 03c4122..43b91d5 100644
--- a/gui/simple-greeter/gdm-greeter-panel.c
+++ b/gui/simple-greeter/gdm-greeter-panel.c
@@ -65,6 +65,7 @@
 #define GPM_DBUS_INTERFACE "org.freedesktop.PowerManagement"
 
 #define KEY_DISABLE_RESTART_BUTTONS "/apps/gdm/simple-greeter/disable_restart_buttons"
+#define KEY_NOTIFICATION_AREA_PADDING "/apps/notification_area_applet/prefs/padding"
 
 #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
 
@@ -824,6 +825,7 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
 {
         NaTray    *tray;
         GtkWidget *spacer;
+        int padding;
 
         gdm_profile_start (NULL);
 
@@ -955,6 +957,9 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
 
         tray = na_tray_new_for_screen (gtk_window_get_screen (GTK_WINDOW (panel)),
                                        GTK_ORIENTATION_HORIZONTAL);
+
+        padding = gconf_client_get_int (panel->priv->client, KEY_NOTIFICATION_AREA_PADDING, NULL);
+        na_tray_set_padding (tray, padding);
         gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6);
         gtk_widget_show (GTK_WIDGET (tray));
         gdm_greeter_panel_hide_user_options (panel);
-- 
1.6.5.rc2


fix-timer.patch:
 b/gui/simple-greeter/gdm-cell-renderer-timer.c |   13 ++-----------
 gui/simple-greeter/gdm-cell-renderer-timer.c   |    2 --
 2 files changed, 2 insertions(+), 13 deletions(-)

--- NEW FILE fix-timer.patch ---
>From 88d4e5d79ca5ded0f9e88af67044d53342ff0897 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 17:39:27 -0400
Subject: [PATCH 1/2] Force cell renderer to be a specific height

Before it was growing and shrinking all the time causing,
flicker.
---
 gui/simple-greeter/gdm-cell-renderer-timer.c |   12 ++----------
 1 files changed, 2 insertions(+), 10 deletions(-)

diff --git a/gui/simple-greeter/gdm-cell-renderer-timer.c b/gui/simple-greeter/gdm-cell-renderer-timer.c
index 7918b48..9453d7e 100644
--- a/gui/simple-greeter/gdm-cell-renderer-timer.c
+++ b/gui/simple-greeter/gdm-cell-renderer-timer.c
@@ -108,19 +108,11 @@ gdm_cell_renderer_timer_get_size (GtkCellRenderer *cell,
         }
 
         if (width != NULL) {
-                if (cell->width >= 0) {
-                        *width = cell->width;
-                } else {
-                        *width = renderer->priv->value <= G_MINDOUBLE?  0 : 64;
-                }
+                *width = cell->xpad * 2 + 42;
         }
 
         if (height != NULL) {
-                if (cell->height >= 0) {
-                        *height = cell->height;
-                } else {
-                        *height = renderer->priv->value <= G_MINDOUBLE?  0 : 64;
-                }
+                *height = cell->ypad * 2 + 42;
         }
 }
 
-- 
1.6.5.rc2


>From a87b05fac2c2de7cff80a183e397f33416bfc893 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode at redhat.com>
Date: Thu, 22 Oct 2009 17:45:13 -0400
Subject: [PATCH 2/2] Drop set_operator (SOURCE) in cell renderer

I'm not sure why I was doing it, when it looks
find using OVER, so I'm going to take it out.
---
 gui/simple-greeter/gdm-cell-renderer-timer.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/gui/simple-greeter/gdm-cell-renderer-timer.c b/gui/simple-greeter/gdm-cell-renderer-timer.c
index 9453d7e..0fb404c 100644
--- a/gui/simple-greeter/gdm-cell-renderer-timer.c
+++ b/gui/simple-greeter/gdm-cell-renderer-timer.c
@@ -164,7 +164,6 @@ draw_timer (GdmCellRendererTimer *renderer,
         cairo_arc (context, 0, 0, radius + 1, 0, 2 * G_PI);
         cairo_fill (context);
 
-        cairo_set_operator (context, CAIRO_OPERATOR_SOURCE);
         cairo_set_source_rgb (context,
                               bg->red / 65535.0,
                               bg->green / 65535.0,
-- 
1.6.5.rc2

gdm-2.28.1-move-shutdown-functions.patch:
 b/gui/simple-greeter/Makefile.am                    |    2 
 b/gui/simple-greeter/gdm-greeter-login-window.c     |  294 --------------------
 b/gui/simple-greeter/gdm-greeter-login-window.glade |  194 -------------
 b/gui/simple-greeter/gdm-greeter-panel.c            |  263 +++++++++++++++++
 b/gui/simple-greeter/gdm-greeter-panel.h            |    3 
 b/gui/simple-greeter/gdm-greeter-session.c          |    4 
 b/gui/simple-greeter/test-greeter-panel.c           |    3 
 gui/simple-greeter/gdm-greeter-panel.c              |   89 ++++--
 8 files changed, 334 insertions(+), 518 deletions(-)

Index: gdm-2.28.1-move-shutdown-functions.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gdm/F-12/gdm-2.28.1-move-shutdown-functions.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gdm-2.28.1-move-shutdown-functions.patch	20 Oct 2009 23:45:00 -0000	1.1
+++ gdm-2.28.1-move-shutdown-functions.patch	23 Oct 2009 02:27:30 -0000	1.2
@@ -1,7 +1,82 @@
-diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c
---- gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c.move-shutdown-functions	2009-10-20 18:10:14.222638248 -0400
-+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.c	2009-10-20 18:16:01.124636507 -0400
-@@ -37,11 +37,6 @@
+commit 7b3be6884096a2d21af3c6c26090641c16988b15
+Merge: f0a0955 4c20614
+Author: Ray Strode <rstrode at redhat.com>
+Date:   Tue Oct 20 17:56:09 2009 -0400
+
+    Move Shutdown functions to panel instead of login window
+    
+    Robert Ancell gives a good rationale for the move:
+    "In GDM 2.28/master on startup the user is presented with a window
+    containing:
+    - A list of users to log in as with the first user selected
+    - Two buttons, restart and shutdown, below the user list
+    
+    Since the first user is selected, users who are unfamiliar/not paying
+    close attention sometimes click on the shutdown button as this is placed
+    where the default action (in this case login) is conventionally placed
+    (the lower right hand corner of the window).  The penalty of making this
+    mistake is for the computer to shut down immediately with no chance of
+    aborting this mistake.
+    
+    An additional mistake users can make is to miss clicking on their user
+    and then click on the shutdown button (as this button is replaced with
+    the login button after selecting a user).
+    
+    Recommended behaviour:
+    
+    Move the shutdown actions (shutdown, sleep, hibernate, restart) to a
+    menu on the GDM panel.
+    
+    The shutdown buttons do not need to be prominently located as:
+    - They are used less frequently than the login buttons (normal operation
+      is to shutdown from within your session).
+    - Most hardware has a dedicated power button that performs the same
+      action
+    - It is better to have them in a location where they are less likely to
+      be accidentally activated"
+    
+    (see https://bugs.gnome.org/596151)
+
+From e53b45310bc0b83ab14fdfde1cac6e6ea22d82b7 Mon Sep 17 00:00:00 2001
+From: Robert Ancell <robert.ancell at canonical.com>
+Date: Thu, 24 Sep 2009 15:51:10 +1000
+Subject: [PATCH 1/3] Move shutdown buttons to menu in panel (Bug #596151)
+
+---
+ gui/simple-greeter/Makefile.am                    |    2 +-
+ gui/simple-greeter/gdm-greeter-login-window.c     |  294 ---------------------
+ gui/simple-greeter/gdm-greeter-login-window.glade |  194 --------------
+ gui/simple-greeter/gdm-greeter-panel.c            |  263 ++++++++++++++++++-
+ gui/simple-greeter/gdm-greeter-panel.h            |    3 +-
+ gui/simple-greeter/gdm-greeter-session.c          |    4 +-
+ gui/simple-greeter/test-greeter-panel.c           |    2 +-
+ 7 files changed, 267 insertions(+), 495 deletions(-)
+
+diff --git a/gui/simple-greeter/Makefile.am b/gui/simple-greeter/Makefile.am
+index 4c06bc3..519e652 100644
+--- a/gui/simple-greeter/Makefile.am
++++ b/gui/simple-greeter/Makefile.am
+@@ -92,7 +92,6 @@ test_greeter_login_window_LDADD =	\
+ 	libgdmuser.la			\
+ 	$(COMMON_LIBS)			\
+ 	$(SIMPLE_GREETER_LIBS)		\
+-	$(DEVKIT_POWER_LIBS)		\
+ 	$(RBAC_LIBS)			\
+ 	$(NULL)
+ 
+@@ -144,6 +143,7 @@ test_greeter_panel_LDADD =	\
+ 	$(GTK_LIBS)			\
+ 	$(GCONF_LIBS)			\
+ 	$(LIBXKLAVIER_LIBS)		\
++	$(DEVKIT_POWER_LIBS)		\
+ 	$(NULL)
+ 
+ test_remote_login_window_SOURCES = 	\
+diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
+index 10a5132..9a29a2e 100644
+--- a/gui/simple-greeter/gdm-greeter-login-window.c
++++ b/gui/simple-greeter/gdm-greeter-login-window.c
+@@ -34,11 +34,6 @@
  #include <errno.h>
  #include <pwd.h>
  
@@ -13,7 +88,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  #include <glib.h>
  #include <glib/gi18n.h>
  #include <glib/gstdio.h>
-@@ -59,10 +54,6 @@
+@@ -56,10 +51,6 @@
  #include <dbus/dbus-glib.h>
  #include <dbus/dbus-glib-lowlevel.h>
  
@@ -21,10 +96,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 -#include <devkit-power-gobject/devicekit-power.h>
 -#endif
 -
- #include "gdm-marshal.h"
- 
  #include "gdm-settings-client.h"
-@@ -97,7 +88,6 @@
+ #include "gdm-settings-keys.h"
+ #include "gdm-profile.h"
+@@ -90,7 +81,6 @@
  #define KEY_BANNER_MESSAGE_TEXT     KEY_GREETER_DIR "/banner_message_text"
  #define KEY_BANNER_MESSAGE_TEXT_NOCHOOSER     KEY_GREETER_DIR "/banner_message_text_nochooser"
  #define KEY_LOGO                    KEY_GREETER_DIR "/logo_icon_name"
@@ -32,7 +107,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  #define GDM_GREETER_LOGIN_WINDOW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_LOGIN_WINDOW, GdmGreeterLoginWindowPrivate))
  
  enum {
-@@ -134,8 +124,6 @@ struct GdmGreeterLoginWindowPrivate
+@@ -125,8 +115,6 @@ struct GdmGreeterLoginWindowPrivate
          char            *timed_login_username;
          guint            timed_login_timeout_id;
  
@@ -41,7 +116,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
          guint            login_button_handler_id;
          guint            start_session_handler_id;
  };
-@@ -378,37 +366,6 @@ sensitize_widget (GdmGreeterLoginWindow 
+@@ -353,37 +341,6 @@ sensitize_widget (GdmGreeterLoginWindow *login_window,
          }
  }
  
@@ -77,9 +152,9 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 -}
 -
  static void
- on_login_button_clicked_timed_login (GtkButton             *button,
-                                      GdmGreeterLoginWindow *login_window)
-@@ -562,61 +519,6 @@ adjust_other_login_visibility(GdmGreeter
+ on_login_button_clicked_answer_query (GtkButton             *button,
+                                       GdmGreeterLoginWindow *login_window)
+@@ -477,61 +434,6 @@ adjust_other_login_visibility(GdmGreeterLoginWindow *login_window)
          }
  }
  
@@ -141,13 +216,12 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  static void
  switch_mode (GdmGreeterLoginWindow *login_window,
               int                    number)
-@@ -624,17 +526,7 @@ switch_mode (GdmGreeterLoginWindow *logi
+@@ -539,16 +441,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
          const char *default_name;
          GtkWidget  *user_chooser;
          GtkWidget  *box;
 -        gboolean    show_restart_buttons;
 -        gboolean    show_suspend_button;
-         int         number_of_tasks;
 -
 -        show_restart_buttons = get_show_restart_buttons (login_window);
 -
@@ -159,7 +233,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  
          /* we want to run this even if we're supposed to
             be in the mode already so that we reset everything
-@@ -643,30 +534,15 @@ switch_mode (GdmGreeterLoginWindow *logi
+@@ -557,38 +449,20 @@ switch_mode (GdmGreeterLoginWindow *login_window,
  
          default_name = NULL;
  
@@ -180,8 +254,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 -                show_widget (login_window, "disconnect-button",
 -                             ! login_window->priv->display_is_local);
 -
-                 show_widget (login_window, "auth-page-box", FALSE);
-                 show_widget (login_window, "conversation-list", FALSE);
+                 show_widget (login_window, "auth-input-box", FALSE);
  
 -                add_sensitize_power_buttons_timeout (login_window);
 -                sensitize_widget (login_window, "shutdown-button", FALSE);
@@ -190,21 +263,19 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
                  sensitize_widget (login_window, "disconnect-button", FALSE);
  
                  default_name = NULL;
-@@ -676,9 +552,6 @@ switch_mode (GdmGreeterLoginWindow *logi
-                                              GTK_WIDGET (login_window)->allocation.width,
-                                              -1);
+                 break;
+         case MODE_AUTHENTICATION:
                  show_widget (login_window, "cancel-button", TRUE);
 -                show_widget (login_window, "shutdown-button", FALSE);
 -                show_widget (login_window, "restart-button", FALSE);
 -                show_widget (login_window, "suspend-button", FALSE);
                  show_widget (login_window, "disconnect-button", FALSE);
-                 show_widget (login_window, "auth-page-box", TRUE);
- 
-@@ -723,32 +596,6 @@ switch_mode (GdmGreeterLoginWindow *logi
-         }
+                 default_name = "log-in-button";
+                 break;
+@@ -629,32 +503,6 @@ switch_mode (GdmGreeterLoginWindow *login_window,
  }
  
--static void
+ static void
 -do_disconnect (GdmGreeterLoginWindow *login_window)
 -{
 -        gtk_main_quit ();
@@ -230,10 +301,11 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 -}
 -#endif
 -
- static gboolean
- task_has_service_name (GdmTaskList *task_list,
-                        GdmTask     *task,
-@@ -1229,16 +1076,6 @@ gdm_greeter_login_window_get_property (G
+-static void
+ delete_entry_text (GtkWidget *entry)
+ {
+         const char *typed_text;
+@@ -968,16 +816,6 @@ gdm_greeter_login_window_get_property (GObject    *object,
  }
  
  static void
@@ -250,7 +322,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  cancel_button_clicked (GtkButton             *button,
                         GdmGreeterLoginWindow *login_window)
  {
-@@ -1246,125 +1083,6 @@ cancel_button_clicked (GtkButton        
+@@ -985,125 +823,6 @@ cancel_button_clicked (GtkButton             *button,
  }
  
  static void
@@ -376,9 +448,9 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  on_user_chooser_visibility_changed (GdmGreeterLoginWindow *login_window)
  {
          update_banner_message (login_window);
-@@ -1877,20 +1595,9 @@ load_theme (GdmGreeterLoginWindow *login
+@@ -1400,20 +1119,9 @@ load_theme (GdmGreeterLoginWindow *login_window)
+         login_window->priv->auth_banner_label = glade_xml_get_widget (login_window->priv->xml, "auth-banner-label");
          /*make_label_small_italic (login_window->priv->auth_banner_label);*/
-         login_window->priv->auth_page_box = glade_xml_get_widget (login_window->priv->xml, "auth-page-box");
  
 -        button = glade_xml_get_widget (login_window->priv->xml, "suspend-button");
 -        g_signal_connect (button, "clicked", G_CALLBACK (suspend_button_clicked), login_window);
@@ -394,10 +466,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 -        button = glade_xml_get_widget (login_window->priv->xml, "shutdown-button");
 -        g_signal_connect (button, "clicked", G_CALLBACK (shutdown_button_clicked), login_window);
 -
-         create_computer_info (login_window);
- 
-         box = glade_xml_get_widget (login_window->priv->xml, "computer-info-event-box");
-@@ -2484,8 +2191,6 @@ gdm_greeter_login_window_finalize (GObje
+         entry = glade_xml_get_widget (login_window->priv->xml, "auth-prompt-entry");
+         /* Only change the invisible character if it '*' otherwise assume it is OK */
+         if ('*' == gtk_entry_get_invisible_char (GTK_ENTRY (entry))) {
+@@ -1780,8 +1488,6 @@ gdm_greeter_login_window_finalize (GObject *object)
                  g_object_unref (login_window->priv->client);
          }
  
@@ -406,9 +478,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
          G_OBJECT_CLASS (gdm_greeter_login_window_parent_class)->finalize (object);
  }
  
-diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade
---- gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade.move-shutdown-functions	2009-10-20 18:10:14.224636470 -0400
-+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-login-window.glade	2009-10-20 18:10:14.326876724 -0400
+diff --git a/gui/simple-greeter/gdm-greeter-login-window.glade b/gui/simple-greeter/gdm-greeter-login-window.glade
+index d972c82..7c6e94b 100644
+--- a/gui/simple-greeter/gdm-greeter-login-window.glade
++++ b/gui/simple-greeter/gdm-greeter-login-window.glade
 @@ -337,200 +337,6 @@
  		  <property name="spacing">6</property>
  
@@ -610,9 +683,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  		    <widget class="GtkButton" id="cancel-button">
  		      <property name="visible">True</property>
  		      <property name="can_focus">True</property>
-diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c
---- gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
-+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.c	2009-10-20 18:10:14.338886522 -0400
+diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
+index dbdef29..dd0cb32 100644
+--- a/gui/simple-greeter/gdm-greeter-panel.c
++++ b/gui/simple-greeter/gdm-greeter-panel.c
 @@ -27,12 +27,22 @@
  #include <unistd.h>
  #include <string.h>
@@ -653,16 +727,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  #define GDM_GREETER_PANEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GDM_TYPE_GREETER_PANEL, GdmGreeterPanelPrivate))
  
  struct GdmGreeterPanelPrivate
-@@ -57,6 +77,8 @@ struct GdmGreeterPanelPrivate
-         GtkWidget              *option_hbox;
-         GtkWidget              *hostname_label;
-         GtkWidget              *clock;
-+        GtkWidget              *shutdown_button;
-+        GtkWidget              *shutdown_menu;
-         GtkWidget              *language_option_widget;
-         GtkWidget              *layout_option_widget;
-         GtkWidget              *session_option_widget;
-@@ -66,11 +88,15 @@ struct GdmGreeterPanelPrivate
+@@ -66,11 +86,15 @@ struct GdmGreeterPanelPrivate
  
          char                   *default_session_name;
          char                   *default_language_name;
@@ -679,7 +744,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  };
  
  enum {
-@@ -107,6 +133,13 @@ gdm_greeter_panel_set_monitor (GdmGreete
+@@ -107,6 +131,13 @@ gdm_greeter_panel_set_monitor (GdmGreeterPanel *panel,
  }
  
  static void
@@ -693,7 +758,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  gdm_greeter_panel_set_property (GObject        *object,
                                  guint           prop_id,
                                  const GValue   *value,
-@@ -120,6 +153,9 @@ gdm_greeter_panel_set_property (GObject 
+@@ -120,6 +151,9 @@ gdm_greeter_panel_set_property (GObject        *object,
          case PROP_MONITOR:
                  gdm_greeter_panel_set_monitor (self, g_value_get_int (value));
                  break;
@@ -703,7 +768,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
          default:
                  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                  break;
-@@ -140,6 +176,9 @@ gdm_greeter_panel_get_property (GObject 
+@@ -140,6 +174,9 @@ gdm_greeter_panel_get_property (GObject        *object,
          case PROP_MONITOR:
                  g_value_set_int (value, self->priv->monitor);
                  break;
@@ -713,7 +778,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
          default:
                  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                  break;
-@@ -477,6 +516,13 @@ gdm_greeter_panel_class_init (GdmGreeter
+@@ -477,6 +514,13 @@ gdm_greeter_panel_class_init (GdmGreeterPanelClass *klass)
                                                             G_MAXINT,
                                                             0,
                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
@@ -727,7 +792,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  
          g_type_class_add_private (klass, sizeof (GdmGreeterPanelPrivate));
  }
-@@ -563,6 +609,216 @@ on_animation_tick (GdmGreeterPanel *pane
+@@ -563,11 +607,185 @@ on_animation_tick (GdmGreeterPanel *panel,
          gtk_widget_queue_resize (GTK_WIDGET (panel));
  }
  
@@ -903,48 +968,17 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
 +        return show;
 +}
 +
-+static void
-+position_shutdown_menu (GtkMenu         *menu,
-+                        int             *x,
-+                        int             *y,
-+                        gboolean        *push_in,
-+                        GdmGreeterPanel *panel)
-+{
-+        GtkRequisition menu_requisition;
-+
-+        *push_in = TRUE;
-+
-+        *x = panel->priv->shutdown_button->allocation.x;
-+        gtk_window_get_position (GTK_WINDOW (panel), NULL, y);
-+
-+        gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
-+
-+        *y -= menu_requisition.height;
-+}
-+
-+static void
-+on_shutdown_button_toggled (GdmGreeterPanel *panel)
-+{
-+        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button))) {
-+                gtk_menu_popup (GTK_MENU (panel->priv->shutdown_menu), NULL, NULL,
-+                                (GtkMenuPositionFunc) position_shutdown_menu,
-+                                panel, 0, 0);
-+        } else {
-+                gtk_menu_popdown (GTK_MENU (panel->priv->shutdown_menu));
-+        }
-+}
-+
-+static void
-+on_shutdown_menu_deactivate (GdmGreeterPanel *panel)
-+{
-+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button),
-+                                      FALSE);
-+}
-+
  static void
  gdm_greeter_panel_init (GdmGreeterPanel *panel)
  {
-@@ -603,6 +859,8 @@ gdm_greeter_panel_init (GdmGreeterPanel 
+         NaTray    *tray;
+         GtkWidget *spacer;
++        GtkWidget *shutdown_menu;
++        GtkWidget *menu, *menu_item;
+ 
+         gdm_profile_start (NULL);
+ 
+@@ -603,6 +821,8 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
          spacer = gtk_label_new ("");
          gtk_box_pack_start (GTK_BOX (panel->priv->option_hbox), spacer, TRUE, TRUE, 6);
          gtk_widget_show (spacer);
@@ -953,59 +987,50 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  
          gdm_profile_start ("creating option widget");
          panel->priv->language_option_widget = gdm_language_option_widget_new ();
-@@ -642,6 +900,51 @@ gdm_greeter_panel_init (GdmGreeterPanel 
+@@ -642,6 +862,42 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
                  gtk_widget_show (panel->priv->hostname_label);
          }
  
 +        if (panel->priv->display_is_local || get_show_restart_buttons (panel)) {
-+                GtkWidget *menu_item;
-+                GtkWidget *image;
++                shutdown_menu = gtk_menu_bar_new ();
 +
-+                panel->priv->shutdown_button = gtk_toggle_button_new ();
-+                gtk_button_set_relief (GTK_BUTTON (panel->priv->shutdown_button),
-+                                       GTK_RELIEF_NONE);
-+
-+                panel->priv->shutdown_menu = gtk_menu_new ();
-+                gtk_menu_attach_to_widget (GTK_MENU (panel->priv->shutdown_menu),
-+                                           panel->priv->shutdown_button, NULL);
-+                g_signal_connect_swapped (panel->priv->shutdown_button, "toggled",
-+                                          G_CALLBACK (on_shutdown_button_toggled), panel);
-+                g_signal_connect_swapped (panel->priv->shutdown_menu, "deactivate",
-+                                          G_CALLBACK (on_shutdown_menu_deactivate), panel);
-+
-+                image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON);
-+                gtk_widget_show (image);
-+                gtk_container_add (GTK_CONTAINER (panel->priv->shutdown_button), image);
++                menu_item = gtk_image_menu_item_new ();
++                menu = gtk_menu_new ();
++                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
++                gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
++                gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), "");
++                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
++                                               gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON));
++                gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), menu_item);
 +
 +                if (panel->priv->display_is_local) {
 +                        menu_item = gtk_menu_item_new_with_label ("Disconnect");
 +                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_disconnect), NULL);
-+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 +                } else {
 +                        if (can_suspend ()) {
-+                                menu_item = gtk_menu_item_new_with_label (_("Suspend"));
++                                menu_item = gtk_menu_item_new_with_label ("Suspend");
 +                                g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
-+                                gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
++                                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 +                        }
 +
-+                        menu_item = gtk_menu_item_new_with_label (_("Restart"));
++                        menu_item = gtk_menu_item_new_with_label ("Restart");
 +                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
-+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 +
-+                        menu_item = gtk_menu_item_new_with_label (_("Shut Down"));
++                        menu_item = gtk_menu_item_new_with_label ("Shut Down");
 +                        g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
-+                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
 +                }
 +
-+                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (panel->priv->shutdown_button), FALSE, FALSE, 0);
-+                gtk_widget_show_all (panel->priv->shutdown_menu);
-+                gtk_widget_show_all (GTK_WIDGET (panel->priv->shutdown_button));
++                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (shutdown_menu), FALSE, FALSE, 0);
++                gtk_widget_show_all (GTK_WIDGET (shutdown_menu));
 +        }
 +
          panel->priv->clock = gdm_clock_widget_new ();
          gtk_box_pack_end (GTK_BOX (panel->priv->hbox),
                              GTK_WIDGET (panel->priv->clock), FALSE, FALSE, 6);
-@@ -651,7 +954,6 @@ gdm_greeter_panel_init (GdmGreeterPanel 
+@@ -651,7 +907,6 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
                                         GTK_ORIENTATION_HORIZONTAL);
          gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (tray), FALSE, FALSE, 6);
          gtk_widget_show (GTK_WIDGET (tray));
@@ -1013,7 +1038,7 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
          gdm_greeter_panel_hide_user_options (panel);
  
          panel->priv->progress = 0.0;
-@@ -684,13 +986,15 @@ gdm_greeter_panel_finalize (GObject *obj
+@@ -684,13 +939,15 @@ gdm_greeter_panel_finalize (GObject *object)
  
  GtkWidget *
  gdm_greeter_panel_new (GdkScreen *screen,
@@ -1030,9 +1055,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
                                 NULL);
  
          return GTK_WIDGET (object);
-diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h
---- gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
-+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-panel.h	2009-10-20 18:10:14.330886648 -0400
+diff --git a/gui/simple-greeter/gdm-greeter-panel.h b/gui/simple-greeter/gdm-greeter-panel.h
+index 1e637f5..625c80d 100644
+--- a/gui/simple-greeter/gdm-greeter-panel.h
++++ b/gui/simple-greeter/gdm-greeter-panel.h
 @@ -60,7 +60,8 @@ typedef struct
  GType                  gdm_greeter_panel_get_type                       (void);
  
@@ -1043,10 +1069,11 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  
  void                   gdm_greeter_panel_show_user_options              (GdmGreeterPanel *panel);
  void                   gdm_greeter_panel_hide_user_options              (GdmGreeterPanel *panel);
-diff -up gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c
---- gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c.move-shutdown-functions	2009-10-20 18:10:14.231637268 -0400
-+++ gdm-2.28.1/gui/simple-greeter/gdm-greeter-session.c	2009-10-20 18:10:14.332887524 -0400
-@@ -369,13 +369,15 @@ toggle_panel (GdmGreeterSession *session
+diff --git a/gui/simple-greeter/gdm-greeter-session.c b/gui/simple-greeter/gdm-greeter-session.c
+index 167b693..e7d206a 100644
+--- a/gui/simple-greeter/gdm-greeter-session.c
++++ b/gui/simple-greeter/gdm-greeter-session.c
+@@ -332,13 +332,15 @@ toggle_panel (GdmGreeterSession *session,
                  GdkScreen  *screen;
                  int         monitor;
                  int         x, y;
@@ -1063,28 +1090,10 @@ diff -up gdm-2.28.1/gui/simple-greeter/g
  
                  g_signal_connect_swapped (session->priv->panel,
                                            "language-selected",
-diff -up gdm-2.28.1/gui/simple-greeter/Makefile.am.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/Makefile.am
---- gdm-2.28.1/gui/simple-greeter/Makefile.am.move-shutdown-functions	2009-10-20 18:10:14.254638094 -0400
-+++ gdm-2.28.1/gui/simple-greeter/Makefile.am	2009-10-20 18:10:14.319892618 -0400
-@@ -103,7 +103,6 @@ test_greeter_login_window_LDADD =	\
- 	libgdmuser.la			\
- 	$(COMMON_LIBS)			\
- 	$(SIMPLE_GREETER_LIBS)		\
--	$(DEVKIT_POWER_LIBS)		\
- 	$(RBAC_LIBS)			\
- 	$(NULL)
- 
-@@ -156,6 +155,7 @@ test_greeter_panel_LDADD =	\
- 	$(GTK_LIBS)			\
- 	$(GCONF_LIBS)			\
- 	$(LIBXKLAVIER_LIBS)		\
-+	$(DEVKIT_POWER_LIBS)		\
- 	$(NULL)
- 
- test_remote_login_window_SOURCES = 	\
-diff -up gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c.move-shutdown-functions gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c
---- gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c.move-shutdown-functions	2009-10-19 18:12:45.000000000 -0400
-+++ gdm-2.28.1/gui/simple-greeter/test-greeter-panel.c	2009-10-20 18:10:14.334888750 -0400
+diff --git a/gui/simple-greeter/test-greeter-panel.c b/gui/simple-greeter/test-greeter-panel.c
+index 80ef0a9..86adae3 100644
+--- a/gui/simple-greeter/test-greeter-panel.c
++++ b/gui/simple-greeter/test-greeter-panel.c
 @@ -53,7 +53,7 @@ main (int argc, char *argv[])
          gdk_display_get_pointer (display, &screen, &x, &y, NULL);
          monitor = gdk_screen_get_monitor_at_point (screen, x, y);
@@ -1094,3 +1103,185 @@ diff -up gdm-2.28.1/gui/simple-greeter/t
          gdm_greeter_panel_show_user_options (GDM_GREETER_PANEL (panel));
  
          gtk_widget_show (panel);
+-- 
+1.6.5.rc2
+
+
+From 4ee17e4732cbdc4c91e93da732de6849c4f95a86 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Tue, 20 Oct 2009 17:06:58 -0400
+Subject: [PATCH 2/3] Use button instead of menu bar
+
+The menu bar isn't a great fit for the panel
+---
+ gui/simple-greeter/gdm-greeter-panel.c |   81 +++++++++++++++++++++++++-------
+ 1 files changed, 64 insertions(+), 17 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
+index dd0cb32..d5dd820 100644
+--- a/gui/simple-greeter/gdm-greeter-panel.c
++++ b/gui/simple-greeter/gdm-greeter-panel.c
+@@ -77,6 +77,8 @@ struct GdmGreeterPanelPrivate
+         GtkWidget              *option_hbox;
+         GtkWidget              *hostname_label;
+         GtkWidget              *clock;
++        GtkWidget              *shutdown_button;
++        GtkWidget              *shutdown_menu;
+         GtkWidget              *language_option_widget;
+         GtkWidget              *layout_option_widget;
+         GtkWidget              *session_option_widget;
+@@ -780,12 +782,48 @@ get_show_restart_buttons (GdmGreeterPanel *panel)
+ }
+ 
+ static void
++position_shutdown_menu (GtkMenu         *menu,
++                        int             *x,
++                        int             *y,
++                        gboolean        *push_in,
++                        GdmGreeterPanel *panel)
++{
++        GtkRequisition menu_requisition;
++
++        *push_in = TRUE;
++
++        *x = panel->priv->shutdown_button->allocation.x;
++        gtk_window_get_position (GTK_WINDOW (panel), NULL, y);
++
++        gtk_widget_size_request (GTK_WIDGET (menu), &menu_requisition);
++
++        *y -= menu_requisition.height;
++}
++
++static void
++on_shutdown_button_toggled (GdmGreeterPanel *panel)
++{
++        if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button))) {
++                gtk_menu_popup (GTK_MENU (panel->priv->shutdown_menu), NULL, NULL,
++                                (GtkMenuPositionFunc) position_shutdown_menu,
++                                panel, 0, 0);
++        } else {
++                gtk_menu_popdown (GTK_MENU (panel->priv->shutdown_menu));
++        }
++}
++
++static void
++on_shutdown_menu_deactivate (GdmGreeterPanel *panel)
++{
++        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (panel->priv->shutdown_button),
++                                      FALSE);
++}
++
++static void
+ gdm_greeter_panel_init (GdmGreeterPanel *panel)
+ {
+         NaTray    *tray;
+         GtkWidget *spacer;
+-        GtkWidget *shutdown_menu;
+-        GtkWidget *menu, *menu_item;
+ 
+         gdm_profile_start (NULL);
+ 
+@@ -863,39 +901,48 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
+         }
+ 
+         if (panel->priv->display_is_local || get_show_restart_buttons (panel)) {
+-                shutdown_menu = gtk_menu_bar_new ();
++                GtkWidget *menu_item;
++                GtkWidget *image;
++
++                panel->priv->shutdown_button = gtk_toggle_button_new ();
++                gtk_button_set_relief (GTK_BUTTON (panel->priv->shutdown_button),
++                                       GTK_RELIEF_NONE);
++
++                panel->priv->shutdown_menu = gtk_menu_new ();
++                gtk_menu_attach_to_widget (GTK_MENU (panel->priv->shutdown_menu),
++                                           panel->priv->shutdown_button, NULL);
++                g_signal_connect_swapped (panel->priv->shutdown_button, "toggled",
++                                          G_CALLBACK (on_shutdown_button_toggled), panel);
++                g_signal_connect_swapped (panel->priv->shutdown_menu, "deactivate",
++                                          G_CALLBACK (on_shutdown_menu_deactivate), panel);
+ 
+-                menu_item = gtk_image_menu_item_new ();
+-                menu = gtk_menu_new ();
+-                gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), menu);
+-                gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menu_item), TRUE);
+-                gtk_menu_item_set_label (GTK_MENU_ITEM (menu_item), "");
+-                gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item),
+-                                               gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON));
+-                gtk_menu_shell_append (GTK_MENU_SHELL (shutdown_menu), menu_item);
++                image = gtk_image_new_from_icon_name ("system-shutdown", GTK_ICON_SIZE_BUTTON);
++                gtk_widget_show (image);
++                gtk_container_add (GTK_CONTAINER (panel->priv->shutdown_button), image);
+ 
+                 if (panel->priv->display_is_local) {
+                         menu_item = gtk_menu_item_new_with_label ("Disconnect");
+                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_disconnect), NULL);
+-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                 } else {
+                         if (can_suspend ()) {
+                                 menu_item = gtk_menu_item_new_with_label ("Suspend");
+                                 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
+-                                gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
++                                gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                         }
+ 
+                         menu_item = gtk_menu_item_new_with_label ("Restart");
+                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
+-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+ 
+                         menu_item = gtk_menu_item_new_with_label ("Shut Down");
+                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
+-                        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
++                        gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                 }
+ 
+-                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (shutdown_menu), FALSE, FALSE, 0);
+-                gtk_widget_show_all (GTK_WIDGET (shutdown_menu));
++                gtk_box_pack_end (GTK_BOX (panel->priv->hbox), GTK_WIDGET (panel->priv->shutdown_button), FALSE, FALSE, 0);
++                gtk_widget_show_all (panel->priv->shutdown_menu);
++                gtk_widget_show_all (GTK_WIDGET (panel->priv->shutdown_button));
+         }
+ 
+         panel->priv->clock = gdm_clock_widget_new ();
+-- 
+1.6.5.rc2
+
+
+From 4c206142ddb22315d9beb42eae9d868f449bdf11 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Tue, 20 Oct 2009 17:23:15 -0400
+Subject: [PATCH 3/3] Mark Shutdown, Restart, and Suspend for translation
+
+---
+ gui/simple-greeter/gdm-greeter-panel.c |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-greeter-panel.c b/gui/simple-greeter/gdm-greeter-panel.c
+index d5dd820..016f636 100644
+--- a/gui/simple-greeter/gdm-greeter-panel.c
++++ b/gui/simple-greeter/gdm-greeter-panel.c
+@@ -926,16 +926,16 @@ gdm_greeter_panel_init (GdmGreeterPanel *panel)
+                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                 } else {
+                         if (can_suspend ()) {
+-                                menu_item = gtk_menu_item_new_with_label ("Suspend");
++                                menu_item = gtk_menu_item_new_with_label (_("Suspend"));
+                                 g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_suspend), NULL);
+                                 gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                         }
+ 
+-                        menu_item = gtk_menu_item_new_with_label ("Restart");
++                        menu_item = gtk_menu_item_new_with_label (_("Restart"));
+                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_restart), NULL);
+                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+ 
+-                        menu_item = gtk_menu_item_new_with_label ("Shut Down");
++                        menu_item = gtk_menu_item_new_with_label (_("Shut Down"));
+                         g_signal_connect (G_OBJECT (menu_item), "activate", G_CALLBACK (do_system_stop), NULL);
+                         gtk_menu_shell_append (GTK_MENU_SHELL (panel->priv->shutdown_menu), menu_item);
+                 }
+-- 
+1.6.5.rc2
+

gdm-multistack.patch:
 b/common/gdm-marshal.list                                            |    1 
 b/configure.ac                                                       |   45 
 b/daemon/gdm-factory-slave.c                                         |   13 
 b/daemon/gdm-greeter-server.c                                        |    2 
 b/daemon/gdm-greeter-server.h                                        |    5 
 b/daemon/gdm-product-slave.c                                         |   47 
 b/daemon/gdm-session-direct.c                                        |   14 
 b/daemon/gdm-session-private.h                                       |    3 
 b/daemon/gdm-session-relay.c                                         |   29 
 b/daemon/gdm-session-worker-job.c                                    |   11 
 b/daemon/gdm-session-worker-job.h                                    |    2 
 b/daemon/gdm-session-worker.c                                        |   27 
 b/daemon/gdm-session.c                                               |   20 
 b/daemon/gdm-session.h                                               |    9 
 b/daemon/gdm-simple-slave.c                                          |    3 
 b/daemon/test-session.c                                              |   14 
 b/gui/simple-greeter/Makefile.am                                     |    4 
 b/gui/simple-greeter/gdm-chooser-widget.c                            |   32 
 b/gui/simple-greeter/gdm-chooser-widget.h                            |    3 
 b/gui/simple-greeter/gdm-greeter-client.c                            |   18 
 b/gui/simple-greeter/gdm-greeter-client.h                            |    4 
 b/gui/simple-greeter/gdm-greeter-login-window.c                      |   91 
 b/gui/simple-greeter/gdm-greeter-login-window.glade                  |   39 
 b/gui/simple-greeter/gdm-greeter-login-window.h                      |   11 
 b/gui/simple-greeter/gdm-greeter-plugin.c                            |  255 +
 b/gui/simple-greeter/gdm-greeter-plugin.h                            |   61 
 b/gui/simple-greeter/gdm-greeter-session.c                           |    5 
 b/gui/simple-greeter/gdm-plugin-manager.c                            |  478 +++
 b/gui/simple-greeter/gdm-plugin-manager.h                            |   66 
 b/gui/simple-greeter/gdm-task-list.c                                 |  198 +
 b/gui/simple-greeter/gdm-task-list.h                                 |   65 
 b/gui/simple-greeter/gdm-user-chooser-widget.c                       |   23 
 b/gui/simple-greeter/libgdmsimplegreeter/Makefile.am                 |   46 
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c          |  147 +
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h          |   87 
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.c     |   93 
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-greeter-extension.h     |   55 
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.c                  |  117 
 b/gui/simple-greeter/libgdmsimplegreeter/gdm-task.h                  |   62 
 b/gui/simple-greeter/libgdmsimplegreeter/gdmsimplegreeter.pc.in      |   11 
 b/gui/simple-greeter/plugins/Makefile.am                             |    1 
 b/gui/simple-greeter/plugins/fingerprint/Makefile.am                 |   56 
 b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c |  299 ++
 b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.h |   56 
 b/gui/simple-greeter/plugins/fingerprint/gdm-fingerprint.pam         |   17 
 b/gui/simple-greeter/plugins/fingerprint/icons/16x16/Makefile.am     |    5 
 b/gui/simple-greeter/plugins/fingerprint/icons/48x48/Makefile.am     |    5 
 b/gui/simple-greeter/plugins/fingerprint/icons/Makefile.am           |    1 
 b/gui/simple-greeter/plugins/fingerprint/page.ui                     |   56 
 b/gui/simple-greeter/plugins/fingerprint/plugin.c                    |   41 
 b/gui/simple-greeter/plugins/password/Makefile.am                    |   53 
 b/gui/simple-greeter/plugins/password/gdm-password-extension.c       |  316 ++
 b/gui/simple-greeter/plugins/password/gdm-password-extension.h       |   56 
 b/gui/simple-greeter/plugins/password/gdm-password.pam               |   19 
 b/gui/simple-greeter/plugins/password/page.ui                        |   56 
 b/gui/simple-greeter/plugins/password/plugin.c                       |   41 
 b/gui/simple-greeter/plugins/smartcard/Makefile.am                   |   77 
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c     |  420 +++
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.h     |   56 
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.c       | 1394 ++++++++++
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-manager.h       |   86 
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard-worker.c        |  167 +
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.c               |  558 ++++
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.h               |   94 
 b/gui/simple-greeter/plugins/smartcard/gdm-smartcard.pam             |   18 
 b/gui/simple-greeter/plugins/smartcard/icons/16x16/Makefile.am       |    5 
 b/gui/simple-greeter/plugins/smartcard/icons/48x48/Makefile.am       |    5 
 b/gui/simple-greeter/plugins/smartcard/icons/Makefile.am             |    1 
 b/gui/simple-greeter/plugins/smartcard/page.ui                       |   56 
 b/gui/simple-greeter/plugins/smartcard/plugin.c                      |   41 
 configure.ac                                                         |   15 
 daemon/gdm-factory-slave.c                                           |  103 
 daemon/gdm-greeter-server.c                                          |  187 +
 daemon/gdm-greeter-server.h                                          |   19 
 daemon/gdm-product-slave.c                                           |  263 +
 daemon/gdm-session-direct.c                                          | 1120 +++++---
 daemon/gdm-session-private.h                                         |   29 
 daemon/gdm-session-relay.c                                           |  190 +
 daemon/gdm-session-worker-job.c                                      |   73 
 daemon/gdm-session-worker-job.h                                      |    6 
 daemon/gdm-session-worker.c                                          |   20 
 daemon/gdm-session.c                                                 |  229 +
 daemon/gdm-session.h                                                 |   59 
 daemon/gdm-simple-slave.c                                            |  223 +
 daemon/test-session.c                                                |   22 
 gui/simple-greeter/Makefile.am                                       |   15 
 gui/simple-greeter/gdm-chooser-widget.c                              |    9 
 gui/simple-greeter/gdm-chooser-widget.h                              |    3 
 gui/simple-greeter/gdm-greeter-client.c                              |  209 +
 gui/simple-greeter/gdm-greeter-client.h                              |   18 
 gui/simple-greeter/gdm-greeter-login-window.c                        | 1105 ++++++-
 gui/simple-greeter/gdm-greeter-login-window.glade                    |  144 -
 gui/simple-greeter/gdm-greeter-login-window.h                        |   21 
 gui/simple-greeter/gdm-greeter-session.c                             |  133 
 gui/simple-greeter/gdm-task-list.c                                   |  228 +
 gui/simple-greeter/gdm-task-list.h                                   |   36 
 gui/simple-greeter/libgdmsimplegreeter/Makefile.am                   |    2 
 gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.c            |   51 
 gui/simple-greeter/libgdmsimplegreeter/gdm-conversation.h            |   13 
 gui/simple-greeter/libgdmsimplegreeter/gdm-task.c                    |    6 
 gui/simple-greeter/libgdmsimplegreeter/gdm-task.h                    |    2 
 gui/simple-greeter/plugins/Makefile.am                               |    4 
 gui/simple-greeter/plugins/fingerprint/gdm-fingerprint-extension.c   |   10 
 gui/simple-greeter/plugins/password/gdm-password-extension.c         |    7 
 gui/simple-greeter/plugins/smartcard/gdm-smartcard-extension.c       |   35 
 105 files changed, 9623 insertions(+), 1258 deletions(-)

View full diff with command:
/usr/bin/cvs -n -f diff -kk -u -p -N -r 1.1 -r 1.2 gdm-multistack.patchIndex: gdm-multistack.patch
===================================================================
RCS file: /cvs/pkgs/rpms/gdm/F-12/gdm-multistack.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -p -r1.1 -r1.2
--- gdm-multistack.patch	23 Sep 2009 23:39:05 -0000	1.1
+++ gdm-multistack.patch	23 Oct 2009 02:27:30 -0000	1.2
@@ -1,1434 +1,1351 @@
-diff -up gdm-2.28.0/common/gdm-marshal.list.multistack gdm-2.28.0/common/gdm-marshal.list
---- gdm-2.28.0/common/gdm-marshal.list.multistack	2009-09-21 16:05:27.000000000 -0400
-+++ gdm-2.28.0/common/gdm-marshal.list	2009-09-23 18:46:06.861400723 -0400
-@@ -5,3 +5,4 @@ VOID:STRING,STRING
- VOID:UINT,UINT
- VOID:STRING,INT
- VOID:DOUBLE
-+BOOLEAN:STRING
-diff -up gdm-2.28.0/configure.ac.multistack gdm-2.28.0/configure.ac
---- gdm-2.28.0/configure.ac.multistack	2009-09-23 18:46:06.497641172 -0400
-+++ gdm-2.28.0/configure.ac	2009-09-23 18:46:06.800400573 -0400
-@@ -18,6 +18,22 @@ AC_PROG_CXX
- AM_PROG_CC_C_O
- AC_PROG_LIBTOOL()
+From 2d9281ddbcf51f7dac5591cdf300a2527dc1a09f Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 20 Feb 2009 13:52:19 -0500
+Subject: [PATCH 04/40] Add a comment marking protected api in chooser
+
+The chooser widget has methods that only its
+subclasses are supposed to call.  We should
+mark them as such.
+---
+ gui/simple-greeter/gdm-chooser-widget.h |    2 ++
+ 1 files changed, 2 insertions(+), 0 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-chooser-widget.h b/gui/simple-greeter/gdm-chooser-widget.h
+index 578e613..7e3e59c 100644
+--- a/gui/simple-greeter/gdm-chooser-widget.h
++++ b/gui/simple-greeter/gdm-chooser-widget.h
+@@ -136,6 +136,8 @@ int            gdm_chooser_widget_get_number_of_items          (GdmChooserWidget
+ void           gdm_chooser_widget_activate_if_one_item         (GdmChooserWidget          *widget);
+ void           gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget          *widget);
  
-+## increment if the plugin interface has additions, changes, removals.
-+LT_CURRENT=1
++/* Protected
++ */
+ void           gdm_chooser_widget_loaded                       (GdmChooserWidget          *widget);
+ 
+ G_END_DECLS
+-- 
+1.6.5.rc2
+
+
+From 85e51354d6715a476763246b92f525ade2ff38e5 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 6 Feb 2009 17:44:37 -0500
+Subject: [PATCH 05/40] Drop duplicated entry introspection output
+
+---
+ daemon/gdm-greeter-server.c |    1 -
+ 1 files changed, 0 insertions(+), 1 deletions(-)
+
+diff --git a/daemon/gdm-greeter-server.c b/daemon/gdm-greeter-server.c
+index 2e01d33..cecce83 100644
+--- a/daemon/gdm-greeter-server.c
++++ b/daemon/gdm-greeter-server.c
+@@ -752,7 +752,6 @@ do_introspect (DBusConnection *connection,
+                                "      <arg name=\"layout_name\" type=\"s\"/>\n"
+                                "    </signal>\n"
+                                "    <signal name=\"DefaultSessionNameChanged\">\n"
+-                               "    <signal name=\"DefaultSessionNameChanged\">\n"
+                                "      <arg name=\"session_name\" type=\"s\"/>\n"
+                                "    </signal>\n"
+                                "    <signal name=\"TimedLoginRequested\">\n"
+-- 
+1.6.5.rc2
+
+
+From 1e38ed6f70ef52e7e62c7487d8ca9adb03bf7655 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Mon, 2 Mar 2009 10:07:03 -0500
+Subject: [PATCH 06/40] Make lookup_item not warn when passing NULL for args
+
+gtk_tree_model_get doesn't like NULL, and we allow
+NULL for optional return values.
+
+We now check each argument for NULL and call
+gtk_tree_model_get individually N times (one for
+each argument) instead of just once.
+---
+ gui/simple-greeter/gdm-chooser-widget.c |   31 ++++++++++++++++++++++++-------
+ 1 files changed, 24 insertions(+), 7 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-chooser-widget.c b/gui/simple-greeter/gdm-chooser-widget.c
+index 2875456..cbd5072 100644
+--- a/gui/simple-greeter/gdm-chooser-widget.c
++++ b/gui/simple-greeter/gdm-chooser-widget.c
+@@ -2171,13 +2171,30 @@ gdm_chooser_widget_lookup_item (GdmChooserWidget *widget,
+         }
+         g_free (active_item_id);
+ 
+-        gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
+-                            CHOOSER_IMAGE_COLUMN, image,
+-                            CHOOSER_NAME_COLUMN, name,
+-                            CHOOSER_PRIORITY_COLUMN, priority,
+-                            CHOOSER_ITEM_IS_IN_USE_COLUMN, is_in_use,
+-                            CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate,
+-                            -1);
++        if (image != NULL) {
++                gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
++                                    CHOOSER_IMAGE_COLUMN, image, -1);
++        }
 +
-+## increment any time the source changes; set to
-+##  0 if you increment CURRENT
-+LT_REVISION=0
++        if (name != NULL) {
++                gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
++                                    CHOOSER_NAME_COLUMN, name, -1);
++        }
 +
-+## increment if any interfaces have been added; set to 0
-+## if any interfaces have been changed or removed. removal has
-+## precedence over adding, so set to 0 if both happened.
-+LT_AGE=0
++        if (priority != NULL) {
++                gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
++                                    CHOOSER_PRIORITY_COLUMN, priority, -1);
++        }
 +
-+AC_SUBST(LT_CURRENT)
-+AC_SUBST(LT_REVISION)
-+AC_SUBST(LT_AGE)
++        if (is_in_use != NULL) {
++                gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
++                                    CHOOSER_ITEM_IS_IN_USE_COLUMN, is_in_use, -1);
++        }
 +
- AC_HEADER_STDC
++        if (is_separate != NULL) {
++                gtk_tree_model_get (GTK_TREE_MODEL (widget->priv->list_store), &iter,
++                                    CHOOSER_ITEM_IS_SEPARATED_COLUMN, is_separate, -1);
++        }
  
- AC_SUBST(VERSION)
-@@ -51,6 +67,7 @@ LIBXKLAVIER_REQUIRED_VERSION=4.0
- LIBCANBERRA_GTK_REQUIRED_VERSION=0.4
- #FONTCONFIG_REQUIRED_VERSION=2.6.0
- FONTCONFIG_REQUIRED_VERSION=2.5.0
-+NSS_REQUIRED_VERSION=3.11.1
+         return TRUE;
+ }
+-- 
+1.6.5.rc2
+
+
+From 185301a9f9b00eb3d1dac89a1b0a956c1a30c304 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 6 Feb 2009 15:35:00 -0500
+Subject: [PATCH 07/40] Drop "stopped" signal from worker-job class
+
+It was unused, dead code.
+---
+ daemon/gdm-session-direct.c     |   14 --------------
+ daemon/gdm-session-worker-job.c |   11 -----------
+ daemon/gdm-session-worker-job.h |    1 -
+ 3 files changed, 0 insertions(+), 26 deletions(-)
+
+diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
+index 47a5778..b6abae4 100644
+--- a/daemon/gdm-session-direct.c
++++ b/daemon/gdm-session-direct.c
+@@ -1539,13 +1539,6 @@ gdm_session_direct_init (GdmSessionDirect *session)
+ }
  
- EXTRA_COMPILE_WARNINGS(yes)
+ static void
+-worker_stopped (GdmSessionWorkerJob *job,
+-                GdmSessionDirect    *session)
+-{
+-        g_debug ("GdmSessionDirect: Worker job stopped");
+-}
+-
+-static void
+ worker_started (GdmSessionWorkerJob *job,
+                 GdmSessionDirect    *session)
+ {
+@@ -1588,10 +1581,6 @@ start_worker (GdmSessionDirect *session)
+         session->priv->job = gdm_session_worker_job_new ();
+         gdm_session_worker_job_set_server_address (session->priv->job, session->priv->server_address);
+         g_signal_connect (session->priv->job,
+-                          "stopped",
+-                          G_CALLBACK (worker_stopped),
+-                          session);
+-        g_signal_connect (session->priv->job,
+                           "started",
+                           G_CALLBACK (worker_started),
+                           session);
+@@ -1613,9 +1602,6 @@ static void
[...24033 lines suppressed...]
-+ * (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.
-+ *
-+ * Written By: Ray Strode <rstrode at redhat.com>
-+ *
-+ */
++static void
+ gdm_session_direct_start_session (GdmSession *session,
+                                   const char *service_name)
+ {
+@@ -2267,12 +2301,20 @@ gdm_session_direct_start_session (GdmSession *session,
+         g_return_if_fail (session != NULL);
+         g_return_if_fail (impl->priv->is_running == FALSE);
+ 
++        conversation = find_conversation_by_name (impl, service_name);
 +
-+#include "gdm-smartcard-extension.h"
++        if (conversation == NULL) {
++                g_warning ("GdmSessionDirect: Tried to start session of "
++                           "nonexistent conversation %s", service_name);
++                return;
++        }
 +
-+#include <gio/gio.h>
-+#include <gtk/gtk.h>
++        stop_all_other_conversations (impl, conversation);
 +
-+GdmGreeterExtension *
-+gdm_greeter_plugin_get_extension (void)
-+{
-+        static GObject *extension;
+         command = get_session_command (impl);
+         program = g_strdup_printf (GDMCONFDIR "/Xsession \"%s\"", command);
+         g_free (command);
+ 
+-        conversation = find_conversation_by_name (impl, service_name);
+-
+         setup_session_environment (impl);
+         send_environment (impl, conversation);
+ 
+@@ -2283,23 +2325,7 @@ gdm_session_direct_start_session (GdmSession *session,
+ static void
+ stop_all_conversations (GdmSessionDirect *session)
+ {
+-        GHashTableIter iter;
+-        gpointer key, value;
+-
+-        if (session->priv->conversations == NULL) {
+-                return;
+-        }
+-
+-        g_hash_table_iter_init (&iter, session->priv->conversations);
+-        while (g_hash_table_iter_next (&iter, &key, &value)) {
+-                GdmSessionConversation *conversation;
+-
+-                conversation = (GdmSessionConversation *) value;
+-
+-                stop_conversation (conversation);
+-        }
+-
+-        g_hash_table_remove_all (session->priv->conversations);
++        stop_all_other_conversations (session, NULL);
+ }
+ 
+ static void
+diff --git a/daemon/gdm-simple-slave.c b/daemon/gdm-simple-slave.c
+index 337718b..63ea82c 100644
+--- a/daemon/gdm-simple-slave.c
++++ b/daemon/gdm-simple-slave.c
+@@ -575,7 +575,7 @@ on_session_conversation_stopped (GdmSession     *session,
+         gboolean res;
+         g_debug ("GdmSimpleSlave: conversation stopped");
+ 
+-        if (slave->priv->greeter_server != NULL) {
++        if (slave->priv->greeter != NULL) {
+                 res = gdm_greeter_server_conversation_stopped (slave->priv->greeter_server,
+                                                                service_name);
+                 if (! res) {
+-- 
+1.6.5.rc2
+
+
+From 2ebacfe2a39bf72b42b40fe57ab30bff90e1f201 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Tue, 21 Apr 2009 15:30:28 -0400
+Subject: [PATCH 38/40] When one PAM conv. wins, actually stop the others
+
+We weren't properly keeping the winning conversation
+around in the previous commit
+---
+ daemon/gdm-session-direct.c |   13 ++++++++++---
+ 1 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/daemon/gdm-session-direct.c b/daemon/gdm-session-direct.c
+index d5209f4..d2ffc87 100644
+--- a/daemon/gdm-session-direct.c
++++ b/daemon/gdm-session-direct.c
+@@ -2280,13 +2280,20 @@ stop_all_other_conversations (GdmSessionDirect        *session,
+                 conversation = (GdmSessionConversation *) value;
+ 
+                 if (conversation == conversation_to_keep) {
+-                        continue;
++                        g_hash_table_iter_steal (&iter);
++                        g_free (key);
++                } else {
++                        stop_conversation (conversation);
+                 }
+-
+-                stop_conversation (conversation);
+         }
+ 
+         g_hash_table_remove_all (session->priv->conversations);
 +
-+        if (extension != NULL) {
-+                g_object_ref (extension);
-+        } else {
-+                extension = g_object_new (GDM_TYPE_SMARTCARD_EXTENSION, NULL);
-+                g_object_add_weak_pointer (extension, (gpointer *) &extension);
++        if (conversation_to_keep != NULL) {
++                g_hash_table_insert (session->priv->conversations,
++                                     g_strdup (conversation_to_keep->service_name),
++                                     conversation_to_keep);
 +        }
+ }
+ 
+ static void
+-- 
+1.6.5.rc2
+
+
+From a121a7ca2712f7669d31f6f62809ebe01602a687 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Fri, 24 Jul 2009 14:41:48 -0400
+Subject: [PATCH 39/40] KILL pam stack instead of TERM pam stack
+
+Some PAM modules are really slow to shut down.
+We need to handle them being slow to shut down better,
+(by not blocking login on them shutting down etc), but
+in the mean time force them to die immediately.
+
+This is a temporary hack.
+---
+ daemon/gdm-session-worker-job.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/daemon/gdm-session-worker-job.c b/daemon/gdm-session-worker-job.c
+index 0327d77..d99b8a5 100644
+--- a/daemon/gdm-session-worker-job.c
++++ b/daemon/gdm-session-worker-job.c
+@@ -320,7 +320,7 @@ gdm_session_worker_job_stop (GdmSessionWorkerJob *session_worker_job)
+ 
+         g_debug ("GdmSessionWorkerJob: Stopping job pid:%d", session_worker_job->priv->pid);
+ 
+-        res = gdm_signal_pid (session_worker_job->priv->pid, SIGTERM);
++        res = gdm_signal_pid (session_worker_job->priv->pid, SIGKILL);
+ 
+         if (res < 0) {
+                 g_warning ("Unable to kill session worker process");
+-- 
+1.6.5.rc2
+
+
+From 7304eb766ac3bd744d964e08c84a34d574f35bf8 Mon Sep 17 00:00:00 2001
+From: Ray Strode <rstrode at redhat.com>
+Date: Wed, 21 Oct 2009 16:08:52 -0400
+Subject: [PATCH 40/40] Don't show tasklist for autologin
+
+---
+ gui/simple-greeter/gdm-greeter-login-window.c |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
+index fda4ba0..ce8fa38 100644
+--- a/gui/simple-greeter/gdm-greeter-login-window.c
++++ b/gui/simple-greeter/gdm-greeter-login-window.c
+@@ -1195,6 +1195,11 @@ begin_auto_login (GdmGreeterLoginWindow *login_window)
+         set_message (login_window, _("Select language and click Log In"));
+ 
+         switch_mode (login_window, MODE_AUTHENTICATION);
 +
-+        return GDM_GREETER_EXTENSION (extension);
-+}
++        show_widget (login_window, "conversation-list", FALSE);
++        gdm_task_list_foreach_task (GDM_TASK_LIST (login_window->priv->conversation_list),
++                                    (GdmTaskListForeachFunc) reset_task,
++                                    login_window);
+ }
+ 
+ static gboolean
+-- 
+1.6.5.rc2
+


Index: gdm.spec
===================================================================
RCS file: /cvs/pkgs/rpms/gdm/F-12/gdm.spec,v
retrieving revision 1.498
retrieving revision 1.499
diff -u -p -r1.498 -r1.499
--- gdm.spec	21 Oct 2009 15:02:08 -0000	1.498
+++ gdm.spec	23 Oct 2009 02:27:30 -0000	1.499
@@ -16,7 +16,7 @@
 Summary: The GNOME Display Manager
 Name: gdm
 Version: 2.28.1
-Release: 3%{?dist}
+Release: 4%{?dist}
 Epoch: 1
 License: GPLv2+
 Group: User Interface/X
@@ -100,10 +100,12 @@ Patch3: gdm-2.23.92-save-root-window.pat
 # https://bugzilla.gnome.org/show_bug.cgi?id=572765
 Patch13: gdm-system-keyboard.patch
 
-Patch19: gdm-multistack.patch
 Patch20: gdm-2.28.1-move-shutdown-functions.patch
 Patch21: fix-clock.patch
+Patch22: fix-timer.patch
+Patch23: fix-na-tray.patch
 
+Patch97: gdm-multistack.patch
 # Fedora-specific
 Patch98: gdm-bubble-location.patch
 Patch99: gdm-2.23.1-fedora-logo.patch
@@ -147,10 +149,12 @@ The GDM fingerprint plugin provides func
 %patch3 -p1 -b .save-root-window
 %patch13 -p1 -b .system-keyboard
 
-%patch19 -p1 -b .multistack
 %patch20 -p1 -b .move-shutdown-functions
 %patch21 -p1 -b .fix-clock
+%patch22 -p1 -b .fix-timer
+%patch23 -p1 -b .fix-na-tray
 
+%patch97 -p1 -b .multistack
 %patch98 -p1 -b .bubble-location
 %patch99 -p1 -b .fedora-logo
 
@@ -401,6 +405,12 @@ fi
 %{_libdir}/gdm/simple-greeter/plugins/fingerprint.so
 
 %changelog
+* Thu Oct 22 2009 Ray Strode <rstrode at redhat.com> 2.28.1-4
+- Fix autologin window spasms
+- Fix autologin timer animation
+- Make autologin and multistack play better together
+- Add padding to notification tray
+
 * Wed Oct 21 2009 Ray Strode <rstrode at redhat.com> 2.28.1-3
 - Move date from panel to clock tooltip
 




More information about the fedora-extras-commits mailing list