[gdm] Sync notification area stuff with shell



commit 8a9a27ecb5f95f526b40825e87594bc40031fad8
Author: William Jon McCann <jmccann redhat com>
Date:   Wed Jan 12 16:37:26 2011 -0500

    Sync notification area stuff with shell
    
    And port to gtk3.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=639284

 gui/simple-greeter/libnotificationarea/Makefile.am |   14 --
 gui/simple-greeter/libnotificationarea/fixedtip.c  |   22 ++-
 .../libnotificationarea/na-tray-child.c            |  152 ++++++++------
 .../libnotificationarea/na-tray-manager.c          |   68 +++---
 gui/simple-greeter/libnotificationarea/na-tray.c   |  125 +++++++----
 gui/simple-greeter/libnotificationarea/obox.c      |  129 ------------
 gui/simple-greeter/libnotificationarea/obox.h      |   73 -------
 gui/simple-greeter/libnotificationarea/testtray.c  |  220 --------------------
 8 files changed, 210 insertions(+), 593 deletions(-)
---
diff --git a/gui/simple-greeter/libnotificationarea/Makefile.am b/gui/simple-greeter/libnotificationarea/Makefile.am
index 7df0750..83e5789 100644
--- a/gui/simple-greeter/libnotificationarea/Makefile.am
+++ b/gui/simple-greeter/libnotificationarea/Makefile.am
@@ -26,8 +26,6 @@ BUILT_SOURCES = 	\
 libnotificationarea_la_SOURCES =		\
 	fixedtip.h				\
 	fixedtip.c				\
-	obox.c					\
-	obox.h					\
 	na-tray.c				\
 	na-tray.h				\
 	na-tray-child.c				\
@@ -57,15 +55,3 @@ na-marshal.h: na-marshal.list $(GLIB_GENMARSHAL)
 na-marshal.c: na-marshal.list $(GLIB_GENMARSHAL)
 	echo "#include \"na-marshal.h\"" > $@ && \
 	$(GLIB_GENMARSHAL) $< --body --prefix=_na_marshal >> $@
-
-noinst_PROGRAMS = testtray
-
-testtray_SOURCES = 		\
-	testtray.c		\
-	$(NULL)
-
-testtray_LDADD = 		\
-	libnotificationarea.la	\
-	$(GREETER_LIBS)		\
-	$(XLIB_LIBS)		\
-	$(NULL)
diff --git a/gui/simple-greeter/libnotificationarea/fixedtip.c b/gui/simple-greeter/libnotificationarea/fixedtip.c
index ca36bca..b000d4c 100644
--- a/gui/simple-greeter/libnotificationarea/fixedtip.c
+++ b/gui/simple-greeter/libnotificationarea/fixedtip.c
@@ -52,16 +52,20 @@ button_press_handler (GtkWidget      *fixedtip,
 }
 
 static gboolean
-expose_handler (GtkWidget *fixedtip)
+draw_handler (GtkWidget *fixedtip,
+              cairo_t   *cr)
 {
   GtkRequisition req;
+  GtkStyleContext *context;
 
   gtk_widget_size_request (fixedtip, &req);
 
-  gtk_paint_flat_box (gtk_widget_get_style (fixedtip), gtk_widget_get_window (fixedtip),
-                      GTK_STATE_NORMAL, GTK_SHADOW_OUT, 
-                      NULL, fixedtip, "tooltip",
-                      0, 0, req.width, req.height);
+  context = gtk_widget_get_style_context (fixedtip);
+
+  gtk_render_background (context, cr, 0, 0,
+                         req.width, req.height);
+  gtk_render_frame (context, cr, 0, 0,
+                    req.width, req.height);
 
   return FALSE;
 }
@@ -105,8 +109,8 @@ na_fixed_tip_init (NaFixedTip *fixedtip)
   gtk_container_add (GTK_CONTAINER (fixedtip), label);
   fixedtip->priv->label = label;
 
-  g_signal_connect (fixedtip, "expose_event",
-                    G_CALLBACK (expose_handler), NULL);
+  g_signal_connect (fixedtip, "draw",
+                    G_CALLBACK (draw_handler), NULL);
 
   gtk_widget_add_events (GTK_WIDGET (fixedtip), GDK_BUTTON_PRESS_MASK);
   
@@ -134,8 +138,8 @@ na_fixed_tip_position (NaFixedTip *fixedtip)
   gtk_widget_size_request (GTK_WIDGET (fixedtip), &req);
 
   gdk_window_get_origin (gtk_widget_get_window (fixedtip->priv->parent), &root_x, &root_y);
-  gdk_drawable_get_size (GDK_DRAWABLE (gtk_widget_get_window (fixedtip->priv->parent)),
-                         &parent_width, &parent_height);
+  parent_width = gdk_window_get_width (gtk_widget_get_window (fixedtip->priv->parent));
+  parent_height = gdk_window_get_height (gtk_widget_get_window (fixedtip->priv->parent));
 
   screen_width = gdk_screen_get_width (screen);
   screen_height = gdk_screen_get_height (screen);
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-child.c b/gui/simple-greeter/libnotificationarea/na-tray-child.c
index a366bf7..36cd4a0 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-child.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray-child.c
@@ -24,7 +24,7 @@
 
 #include "na-tray-child.h"
 
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
@@ -42,26 +42,30 @@ na_tray_child_realize (GtkWidget *widget)
 {
   NaTrayChild *child = NA_TRAY_CHILD (widget);
   GdkVisual *visual = gtk_widget_get_visual (widget);
+  GdkWindow *window;
 
   GTK_WIDGET_CLASS (na_tray_child_parent_class)->realize (widget);
 
+  window = gtk_widget_get_window (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 (gtk_widget_get_window (widget), &transparent);
-      gdk_window_set_composited (gtk_widget_get_window (widget), TRUE);
+      cairo_pattern_t *transparent = cairo_pattern_create_rgba (0, 0, 0, 0);
+      gdk_window_set_background_pattern (window, transparent);
+      gdk_window_set_composited (window, TRUE);
+      cairo_pattern_destroy (transparent);
 
       child->parent_relative_bg = FALSE;
     }
-  else if (visual == gdk_drawable_get_visual (GDK_DRAWABLE (gdk_window_get_parent (gtk_widget_get_window (widget)))))
+  else if (visual == gdk_window_get_visual (gdk_window_get_parent (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 (gtk_widget_get_window (widget), NULL, TRUE);
+      gdk_window_set_background_pattern (window, NULL);
 
       child->parent_relative_bg = TRUE;
     }
@@ -71,7 +75,7 @@ na_tray_child_realize (GtkWidget *widget)
       child->parent_relative_bg = FALSE;
     }
 
-  gdk_window_set_composited (gtk_widget_get_window (widget), child->composited);
+  gdk_window_set_composited (window, child->composited);
 
   gtk_widget_set_app_paintable (GTK_WIDGET (child),
                                 child->parent_relative_bg || child->has_alpha);
@@ -128,13 +132,15 @@ na_tray_child_size_allocate (GtkWidget      *widget,
                              GtkAllocation  *allocation)
 {
   NaTrayChild *child = NA_TRAY_CHILD (widget);
-
   GtkAllocation widget_allocation;
+  gboolean moved, resized;
+
   gtk_widget_get_allocation (widget, &widget_allocation);
-  gboolean moved = allocation->x != widget_allocation.x ||
-                   allocation->y != widget_allocation.y;
-  gboolean resized = allocation->width != widget_allocation.width ||
-                     allocation->height != widget_allocation.height;
+
+  moved = (allocation->x != widget_allocation.x ||
+	   allocation->y != widget_allocation.y);
+  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.
@@ -168,30 +174,46 @@ na_tray_child_size_allocate (GtkWidget      *widget,
 
 /* 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.
+ * draw handler draws with real or fake transparency.
+ * Copy-pasted from GtkTrayIcon.
  */
 static gboolean
-na_tray_child_expose_event (GtkWidget      *widget,
-                            GdkEventExpose *event)
+na_tray_child_draw (GtkWidget *widget,
+                    cairo_t   *cr)
 {
   NaTrayChild *child = NA_TRAY_CHILD (widget);
 
   if (na_tray_child_has_alpha (child))
     {
       /* Clear to transparent */
-      cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (widget));
       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);
+      cairo_paint (cr);
     }
   else if (child->parent_relative_bg)
     {
-      /* Clear to parent-relative pixmap */
-      gdk_window_clear_area (gtk_widget_get_window (widget),
-                             event->area.x, event->area.y,
-                             event->area.width, event->area.height);
+      GdkWindow *window;
+      cairo_surface_t *target;
+      GdkRectangle clip_rect;
+
+      window = gtk_widget_get_window (widget);
+      target = cairo_get_group_target (cr);
+
+      gdk_cairo_get_clip_rectangle (cr, &clip_rect);
+
+      /* Clear to parent-relative pixmap
+       * We need to use direct X access here because GDK doesn't know about
+       * the parent relative pixmap. */
+      cairo_surface_flush (target);
+
+      XClearArea (GDK_WINDOW_XDISPLAY (window),
+                  GDK_WINDOW_XID (window),
+                  clip_rect.x, clip_rect.y,
+                  clip_rect.width, clip_rect.height,
+                  False);
+      cairo_surface_mark_dirty_rectangle (target,
+                                          clip_rect.x, clip_rect.y,
+                                          clip_rect.width, clip_rect.height);
     }
 
   return FALSE;
@@ -215,7 +237,7 @@ na_tray_child_class_init (NaTrayChildClass *klass)
   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;
+  widget_class->draw = na_tray_child_draw;
 }
 
 GtkWidget *
@@ -227,8 +249,7 @@ na_tray_child_new (GdkScreen *screen,
   NaTrayChild *child;
   GdkVisual *visual;
   gboolean visual_has_alpha;
-  GdkColormap *colormap;
-  gboolean new_colormap;
+  int red_prec, green_prec, blue_prec, depth;
   int result;
 
   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
@@ -243,7 +264,7 @@ na_tray_child_new (GdkScreen *screen,
   gdk_error_trap_push ();
   result = XGetWindowAttributes (xdisplay, icon_window,
                                  &window_attributes);
-  gdk_error_trap_pop ();
+  gdk_error_trap_pop_ignored ();
 
   if (!result) /* Window already gone */
     return NULL;
@@ -253,36 +274,24 @@ na_tray_child_new (GdkScreen *screen,
   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);
+  gtk_widget_set_visual (GTK_WIDGET (child), visual);
 
   /* 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;
+  gdk_visual_get_red_pixel_details (visual, NULL, NULL, &red_prec);
+  gdk_visual_get_green_pixel_details (visual, NULL, NULL, &green_prec);
+  gdk_visual_get_blue_pixel_details (visual, NULL, NULL, &blue_prec);
+  depth = gdk_visual_get_depth (visual);
+
+  visual_has_alpha = red_prec + blue_prec + green_prec < 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);
 }
 
@@ -381,7 +390,8 @@ na_tray_child_set_composited (NaTrayChild *child,
 
   child->composited = composited;
   if (gtk_widget_get_realized (GTK_WIDGET (child)))
-    gdk_window_set_composited (gtk_widget_get_window (GTK_WIDGET (child)), composited);
+    gdk_window_set_composited (gtk_widget_get_window (GTK_WIDGET (child)),
+                               composited);
 }
 
 /* If we are faking transparency with a window-relative background, force a
@@ -402,16 +412,18 @@ na_tray_child_force_redraw (NaTrayChild *child)
        */
       Display *xdisplay = GDK_DISPLAY_XDISPLAY (gtk_widget_get_display (widget));
       XEvent xev;
+      GdkWindow *plug_window;
+      GtkAllocation allocation;
 
-      GtkAllocation widget_allocation;
-      gtk_widget_get_allocation (widget, &widget_allocation);
+      plug_window = gtk_socket_get_plug_window (GTK_SOCKET (child));
+      gtk_widget_get_allocation (widget, &allocation);
 
       xev.xexpose.type = Expose;
-      xev.xexpose.window = GDK_WINDOW_XWINDOW (gtk_socket_get_plug_window (GTK_SOCKET (child)));
+      xev.xexpose.window = gdk_x11_window_get_xid (plug_window);
       xev.xexpose.x = 0;
       xev.xexpose.y = 0;
-      xev.xexpose.width = widget_allocation.width;
-      xev.xexpose.height = widget_allocation.height;
+      xev.xexpose.width = allocation.width;
+      xev.xexpose.height = allocation.height;
       xev.xexpose.count = 0;
 
       gdk_error_trap_push ();
@@ -423,19 +435,18 @@ na_tray_child_force_redraw (NaTrayChild *child)
        * since that is asynchronous.
        */
       XSync (xdisplay, False);
-      gdk_error_trap_pop ();
+      gdk_error_trap_pop_ignored ();
 #else
       /* Hiding and showing is the safe way to do it, but can result in more
        * flickering.
        */
-      gdk_window_hide (gtk_widget_get_window (widget));
-      gdk_window_show (gtk_widget_get_window (widget));
+      gdk_window_hide (widget->window);
+      gdk_window_show (widget->window);
 #endif
     }
 }
 
-
-/* from libwnck xutils.c */
+/* from libwnck/xutils.c, comes as LGPLv2+ */
 static char *
 latin1_to_utf8 (const char *latin1)
 {
@@ -454,7 +465,7 @@ latin1_to_utf8 (const char *latin1)
   return g_string_free (str, FALSE);
 }
 
-/* derived from libwnck xutils.c */
+/* derived from libwnck/xutils.c, comes as LGPLv2+ */
 static void
 _get_wmclass (Display *xdisplay,
               Window   xwindow,
@@ -462,18 +473,13 @@ _get_wmclass (Display *xdisplay,
               char   **res_name)
 {
   XClassHint ch;
-  char *retval;
-
-  gdk_error_trap_push ();
 
   ch.res_name = NULL;
   ch.res_class = NULL;
 
+  gdk_error_trap_push ();
   XGetClassHint (xdisplay, xwindow, &ch);
-
-  gdk_error_trap_pop ();
-
-  retval = NULL;
+  gdk_error_trap_pop_ignored ();
 
   if (res_class)
     *res_class = NULL;
@@ -498,10 +504,20 @@ _get_wmclass (Display *xdisplay,
     }
 }
 
+/**
+ * na_tray_child_get_wm_class;
+ * @child: a #NaTrayChild
+ * @res_name: return location for a string containing the application name of
+ * @child, or %NULL
+ * @res_class: return location for a string containing the application class of
+ * @child, or %NULL
+ *
+ * Fetches the resource associated with @child.
+ */
 void
-na_tray_child_get_wm_class (NaTrayChild *child,
-                            char **res_name,
-                            char **res_class)
+na_tray_child_get_wm_class (NaTrayChild  *child,
+                            char        **res_name,
+                            char        **res_class)
 {
   GdkDisplay *display;
 
diff --git a/gui/simple-greeter/libnotificationarea/na-tray-manager.c b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
index 9618253..90c071a 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray-manager.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray-manager.c
@@ -26,8 +26,7 @@
 
 #include "na-tray-manager.h"
 
-#include <gdkconfig.h>
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
 #if defined (GDK_WINDOWING_X11)
 #include <gdk/gdkx.h>
 #include <X11/Xatom.h>
@@ -299,8 +298,8 @@ na_tray_manager_handle_dock_request (NaTrayManager       *manager,
   if (!gtk_socket_get_plug_window (GTK_SOCKET (child)))
     {
       /* Embedding failed, we won't get a plug-removed signal */
+      /* This signal destroys the socket */
       g_signal_emit (manager, manager_signals[TRAY_ICON_REMOVED], 0, child);
-      gtk_widget_destroy (child);
       return;
     }
 
@@ -539,21 +538,24 @@ na_tray_manager_unmanage (NaTrayManager *manager)
   GdkDisplay *display;
   guint32     timestamp;
   GtkWidget  *invisible;
+  GdkWindow  *window;
 
   if (manager->invisible == NULL)
     return;
 
   invisible = manager->invisible;
+  window = gtk_widget_get_window (invisible);
+
   g_assert (GTK_IS_INVISIBLE (invisible));
   g_assert (gtk_widget_get_realized (invisible));
-  g_assert (GDK_IS_WINDOW (gtk_widget_get_window (invisible)));
+  g_assert (GDK_IS_WINDOW (window));
   
   display = gtk_widget_get_display (invisible);
   
   if (gdk_selection_owner_get_for_display (display, manager->selection_atom) ==
-      gtk_widget_get_window (invisible))
+      window)
     {
-      timestamp = gdk_x11_get_server_time (gtk_widget_get_window (invisible));
+      timestamp = gdk_x11_get_server_time (window);
       gdk_selection_owner_set_for_display (display,
                                            NULL,
                                            manager->selection_atom,
@@ -564,7 +566,7 @@ na_tray_manager_unmanage (NaTrayManager *manager)
   //FIXME: we should also use gdk_remove_client_message_filter when it's
   //available
   // See bug #351254
-  gdk_window_remove_filter (gtk_widget_get_window (invisible),
+  gdk_window_remove_filter (window,
                             na_tray_manager_window_filter, manager);  
 
   manager->invisible = NULL; /* prior to destroy for reentrancy paranoia */
@@ -577,11 +579,15 @@ static void
 na_tray_manager_set_orientation_property (NaTrayManager *manager)
 {
 #ifdef GDK_WINDOWING_X11
+  GdkWindow  *window;
   GdkDisplay *display;
   Atom        orientation_atom;
   gulong      data[1];
 
-  if (!manager->invisible || !gtk_widget_get_window (manager->invisible))
+  if (!manager->invisible)
+    return;
+  window = gtk_widget_get_window (manager->invisible);
+  if (!window)
     return;
 
   display = gtk_widget_get_display (manager->invisible);
@@ -593,7 +599,7 @@ na_tray_manager_set_orientation_property (NaTrayManager *manager)
 		SYSTEM_TRAY_ORIENTATION_VERT;
 
   XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
-		   GDK_WINDOW_XWINDOW (gtk_widget_get_window (manager->invisible)),
+		   gdk_x11_window_get_xid (window),
                    orientation_atom,
 		   XA_CARDINAL, 32,
 		   PropModeReplace,
@@ -605,12 +611,16 @@ static void
 na_tray_manager_set_visual_property (NaTrayManager *manager)
 {
 #ifdef GDK_WINDOWING_X11
+  GdkWindow  *window;
   GdkDisplay *display;
   Visual     *xvisual;
   Atom        visual_atom;
   gulong      data[1];
 
-  if (!manager->invisible || !gtk_widget_get_window (manager->invisible))
+  if (!manager->invisible)
+    return;
+  window = gtk_widget_get_window (manager->invisible);
+  if (!window)
     return;
 
   /* The visual property is a hint to the tray icons as to what visual they
@@ -627,25 +637,14 @@ na_tray_manager_set_visual_property (NaTrayManager *manager)
 
   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));
-    }
+    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));
-    }
+    xvisual = GDK_VISUAL_XVISUAL (gdk_screen_get_system_visual (manager->screen));
 
   data[0] = XVisualIDFromVisual (xvisual);
 
   XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
-                   GDK_WINDOW_XWINDOW (gtk_widget_get_window (manager->invisible)),
+                   gdk_x11_window_get_xid (window),
                    visual_atom,
                    XA_VISUALID, 32,
                    PropModeReplace,
@@ -671,11 +670,11 @@ na_tray_manager_set_padding_property (NaTrayManager *manager)
   data[0] = manager->padding;
 
   XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
-		   GDK_WINDOW_XWINDOW (gtk_widget_get_window (manager->invisible)),
+                  GDK_WINDOW_XID (gtk_widget_get_window (manager->invisible)),
                    orientation_atom,
-		   XA_CARDINAL, 32,
-		   PropModeReplace,
-		   (guchar *) &data, 1);
+                  XA_CARDINAL, 32,
+                  PropModeReplace,
+                  (guchar *) &data, 1);
 #endif
 }
 
@@ -688,6 +687,7 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
   GdkDisplay *display;
   Screen     *xscreen;
   GtkWidget  *invisible;
+  GdkWindow  *window;
   char       *selection_atom_name;
   guint32     timestamp;
   
@@ -724,12 +724,14 @@ 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 (gtk_widget_get_window(invisible));
+
+  window = gtk_widget_get_window (invisible);
+
+  timestamp = gdk_x11_get_server_time (window);
 
   /* Check if we could set the selection owner successfully */
   if (gdk_selection_owner_set_for_display (display,
-                                           gtk_widget_get_window(invisible),
+                                           window,
                                            manager->selection_atom,
                                            timestamp,
                                            TRUE))
@@ -747,7 +749,7 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
       xev.data.l[0] = timestamp;
       xev.data.l[1] = gdk_x11_atom_to_xatom_for_display (display,
                                                          manager->selection_atom);
-      xev.data.l[2] = GDK_WINDOW_XWINDOW (gtk_widget_get_window(invisible));
+      xev.data.l[2] = gdk_x11_window_get_xid (window);
       xev.data.l[3] = 0;	/* manager specific data */
       xev.data.l[4] = 0;	/* manager specific data */
 
@@ -770,7 +772,7 @@ na_tray_manager_manage_screen_x11 (NaTrayManager *manager,
                         manager);
 #endif
       /* This is for SYSTEM_TRAY_REQUEST_DOCK and SelectionClear */
-      gdk_window_add_filter (gtk_widget_get_window(invisible),
+      gdk_window_add_filter (window,
                              na_tray_manager_window_filter, manager);
       /* This is for SYSTEM_TRAY_BEGIN_MESSAGE and SYSTEM_TRAY_CANCEL_MESSAGE */
       gdk_display_add_client_message_filter (display, opcode_atom,
diff --git a/gui/simple-greeter/libnotificationarea/na-tray.c b/gui/simple-greeter/libnotificationarea/na-tray.c
index 1e0c9d2..bac9c45 100644
--- a/gui/simple-greeter/libnotificationarea/na-tray.c
+++ b/gui/simple-greeter/libnotificationarea/na-tray.c
@@ -146,7 +146,7 @@ find_role (const char *wmclass)
 }
 
 static int
-find_role_pos (const char *role)
+find_role_position (const char *role)
 {
   int i;
 
@@ -159,49 +159,42 @@ find_role_pos (const char *role)
   return i + 1;
 }
 
-static void
-tray_added (NaTrayManager *manager,
-            GtkWidget     *icon,
-            TraysScreen   *trays_screen)
+static int
+find_icon_position (NaTray    *tray,
+                    GtkWidget *icon)
 {
-  NaTray *tray;
   NaTrayPrivate *priv;
-  GList *l, *children;
-  int position;
-  char *class_a;
-  const char *role;
-  int role_position;
+  int            position;
+  char          *class_a;
+  const char    *role;
+  int            role_position;
+  GList         *l, *children;
 
-  tray = get_tray (trays_screen);
-  if (tray == NULL)
-    return;
+  /* We insert the icons with a known roles in a specific order (the one
+   * defined by ordered_roles), and all other icons at the beginning of the box
+   * (left in LTR). */
 
   priv = tray->priv;
-
-  g_assert (priv->trays_screen == trays_screen);
-
-  g_hash_table_insert (trays_screen->icon_table, icon, tray);
-
   position = 0;
 
   class_a = NULL;
   na_tray_child_get_wm_class (NA_TRAY_CHILD (icon), NULL, &class_a);
   if (!class_a)
-    goto insert;
+    return position;
 
   role = find_role (class_a);
   g_free (class_a);
   if (!role)
-    goto insert;
+    return position;
 
-  role_position = find_role_pos (role);
+  role_position = find_role_position (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;
+      int        rp;
 
       rp = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (child), "role-position"));
       if (rp == 0 || rp < role_position)
@@ -212,10 +205,33 @@ tray_added (NaTrayManager *manager,
     }
   g_list_free (children);
 
+  /* should never happen, but it doesn't hurt to be on the safe side */
   if (position < 0)
     position = 0;
 
-insert:
+  return position;
+}
+
+static void
+tray_added (NaTrayManager *manager,
+            GtkWidget     *icon,
+            TraysScreen   *trays_screen)
+{
+  NaTray *tray;
+  NaTrayPrivate *priv;
+  int position;
+
+  tray = get_tray (trays_screen);
+  if (tray == NULL)
+    return;
+
+  priv = tray->priv;
+
+  g_assert (priv->trays_screen == trays_screen);
+
+  g_hash_table_insert (trays_screen->icon_table, icon, tray);
+
+  position = find_icon_position (tray, icon);
   gtk_box_pack_start (GTK_BOX (priv->box), icon, FALSE, FALSE, 0);
   gtk_box_reorder_child (GTK_BOX (priv->box), icon, position);
 
@@ -507,35 +523,36 @@ update_size_and_orientation (NaTray *tray)
  * gdk_window_set_composited(). We need to paint these children ourselves.
  */
 static void
-na_tray_expose_icon (GtkWidget *widget,
-		     gpointer   data)
+na_tray_draw_icon (GtkWidget *widget,
+                   gpointer   data)
 {
   cairo_t *cr = data;
 
   if (na_tray_child_has_alpha (NA_TRAY_CHILD (widget)))
     {
-      GtkAllocation widget_allocation;
-      gtk_widget_get_allocation (widget, &widget_allocation);
+      GtkAllocation allocation;
+
+      gtk_widget_get_allocation (widget, &allocation);
+
+      cairo_save (cr);
+
+      gdk_cairo_set_source_window (cr,
+                                   gtk_widget_get_window (widget),
+                                   allocation.x,
+                                   allocation.y);
+      cairo_rectangle (cr, allocation.x, allocation.y, allocation.width, allocation.height);
+      cairo_clip (cr);
 
-      gdk_cairo_set_source_pixmap (cr, gtk_widget_get_window (widget),
-				   widget_allocation.x,
-				   widget_allocation.y);
       cairo_paint (cr);
+      cairo_restore (cr);
     }
 }
 
 static void
-na_tray_expose_box (GtkWidget      *box,
-		    GdkEventExpose *event)
+na_tray_draw_box (GtkWidget *box,
+                  cairo_t   *cr)
 {
-  cairo_t *cr = gdk_cairo_create (gtk_widget_get_window (box));
-
-  gdk_cairo_region (cr, event->region);
-  cairo_clip (cr);
-
-  gtk_container_foreach (GTK_CONTAINER (box), na_tray_expose_icon, cr);
-
-  cairo_destroy (cr);
+  gtk_container_foreach (GTK_CONTAINER (box), na_tray_draw_icon, cr);
 }
 
 static void
@@ -553,8 +570,8 @@ na_tray_init (NaTray *tray)
   gtk_widget_show (priv->frame);
 
   priv->box = g_object_new (na_box_get_type (), NULL);
-  g_signal_connect (priv->box, "expose-event",
-		    G_CALLBACK (na_tray_expose_box), tray);
+  g_signal_connect (priv->box, "draw",
+		    G_CALLBACK (na_tray_draw_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);
@@ -710,10 +727,23 @@ na_tray_set_property (GObject      *object,
 }
 
 static void
-na_tray_size_request (GtkWidget        *widget,
-                      GtkRequisition   *requisition)
+na_tray_get_preferred_width (GtkWidget *widget,
+                             gint      *minimum_size,
+                             gint      *natural_size)
+{
+  gtk_widget_get_preferred_width (gtk_bin_get_child (GTK_BIN (widget)),
+                                  minimum_size,
+                                  natural_size);
+}
+
+static void
+na_tray_get_preferred_height (GtkWidget *widget,
+                              gint      *minimum_size,
+                              gint      *natural_size)
 {
-  gtk_widget_size_request (gtk_bin_get_child (GTK_BIN (widget)), requisition);
+  gtk_widget_get_preferred_height (gtk_bin_get_child (GTK_BIN (widget)),
+                                   minimum_size,
+                                   natural_size);
 }
 
 static void
@@ -733,7 +763,8 @@ na_tray_class_init (NaTrayClass *klass)
   gobject_class->set_property = na_tray_set_property;
   gobject_class->dispose = na_tray_dispose;
 
-  widget_class->size_request = na_tray_size_request;
+  widget_class->get_preferred_width = na_tray_get_preferred_width;
+  widget_class->get_preferred_height = na_tray_get_preferred_height;
   widget_class->size_allocate = na_tray_size_allocate;
 
   g_object_class_install_property



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]