[libwnck/gtk3: 3/4] Port to GTK3



commit 211a61d40b3cbac8ac38d3efe17e885b00e85f0e
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 6 15:03:52 2010 +0200

    Port to GTK3
    
    Includes some surgery in the Tasklist widget to make the glow effect use
    gtk_widget_draw() instead of fake expose events.

 configure.ac            |    2 +-
 libwnck/pager.c         |   63 +++++--------
 libwnck/tasklist.c      |  249 ++++++++++++++---------------------------------
 libwnck/test-tasklist.c |   23 ++---
 libwnck/xutils.c        |  122 +++++++-----------------
 libwnck/xutils.h        |    9 +--
 6 files changed, 141 insertions(+), 327 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 6ea731d..b2d13b5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -144,7 +144,7 @@ AC_SUBST(XRES_PACKAGE)
 AC_SUBST(XLIB_CFLAGS)
 AC_SUBST(XLIB_LIBS)
 
-PKG_CHECK_MODULES(LIBWNCK, gtk+-2.0 >= 2.19.7 glib-2.0 >= 2.16.0 gobject-2.0 >= 2.13.0 $STARTUP_NOTIFICATION_PACKAGE $XRES_PACKAGE)
+PKG_CHECK_MODULES(LIBWNCK, gtk+-3.0 >= 2.91.0 glib-2.0 >= 2.16.0 gobject-2.0 >= 2.13.0 $STARTUP_NOTIFICATION_PACKAGE $XRES_PACKAGE)
 AC_SUBST(LIBWNCK_LIBS)
 AC_SUBST(LIBWNCK_CFLAGS)
 
diff --git a/libwnck/pager.c b/libwnck/pager.c
index e3fcbc0..3f0cb86 100644
--- a/libwnck/pager.c
+++ b/libwnck/pager.c
@@ -117,8 +117,8 @@ static void     wnck_pager_size_request  (GtkWidget        *widget,
                                           GtkRequisition   *requisition);
 static void     wnck_pager_size_allocate (GtkWidget        *widget,
                                           GtkAllocation    *allocation);
-static gboolean wnck_pager_expose_event  (GtkWidget        *widget,
-                                          GdkEventExpose   *event);
+static gboolean wnck_pager_draw          (GtkWidget        *widget,
+                                          cairo_t          *cr);
 static gboolean wnck_pager_button_press  (GtkWidget        *widget,
                                           GdkEventButton   *event);
 static gboolean wnck_pager_drag_motion   (GtkWidget        *widget,
@@ -250,7 +250,7 @@ wnck_pager_class_init (WnckPagerClass *klass)
   widget_class->unrealize = wnck_pager_unrealize;
   widget_class->size_request = wnck_pager_size_request;
   widget_class->size_allocate = wnck_pager_size_allocate;
-  widget_class->expose_event = wnck_pager_expose_event;
+  widget_class->draw = wnck_pager_draw;
   widget_class->button_press_event = wnck_pager_button_press;
   widget_class->button_release_event = wnck_pager_button_release;
   widget_class->motion_notify_event = wnck_pager_motion;
@@ -350,13 +350,12 @@ wnck_pager_realize (GtkWidget *widget)
   attributes.height = allocation.height;
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
   attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK |
 	  		  GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
 			  GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK |
 			  GDK_POINTER_MOTION_HINT_MASK;
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
 
   window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
   gtk_widget_set_window (widget, window);
@@ -1061,7 +1060,6 @@ wnck_pager_draw_workspace (WnckPager    *pager,
   WnckWorkspace *space;
   GtkWidget *widget;
   GtkStateType state;
-  GdkWindow *window;
   GtkStyle *style;
   
   space = wnck_screen_get_workspace (pager->priv->screen, workspace);
@@ -1078,7 +1076,6 @@ wnck_pager_draw_workspace (WnckPager    *pager,
   else
     state = GTK_STATE_NORMAL;
 
-  window = gtk_widget_get_window (widget);
   style = gtk_widget_get_style (widget);
 
   /* FIXME in names mode, should probably draw things like a button.
@@ -1254,9 +1251,9 @@ wnck_pager_draw_workspace (WnckPager    *pager,
   if (workspace == pager->priv->prelight && pager->priv->prelight_dnd)
     {
       /* stolen directly from gtk source so it matches nicely */
-      gtk_paint_shadow (style, window,
+      gtk_paint_shadow (style, cr,
 		        GTK_STATE_NORMAL, GTK_SHADOW_OUT,
-		        NULL, widget, "dnd",
+		        widget, "dnd",
 			rect->x, rect->y, rect->width, rect->height);
 
       cairo_set_source_rgb (cr, 0.0, 0.0, 0.0); /* black */
@@ -1269,8 +1266,8 @@ wnck_pager_draw_workspace (WnckPager    *pager,
 }
 
 static gboolean
-wnck_pager_expose_event  (GtkWidget      *widget,
-                          GdkEventExpose *event)
+wnck_pager_draw (GtkWidget *widget,
+                 cairo_t   *cr)
 {
   WnckPager *pager;
   int i;
@@ -1278,11 +1275,8 @@ wnck_pager_expose_event  (GtkWidget      *widget,
   WnckWorkspace *active_space;
   GdkPixbuf *bg_pixbuf;
   gboolean first;
-  GdkWindow *window;
-  GtkAllocation allocation;
   GtkStyle *style;
   int focus_width;
-  cairo_t *cr;
   
   pager = WNCK_PAGER (widget);
 
@@ -1291,40 +1285,33 @@ wnck_pager_expose_event  (GtkWidget      *widget,
   bg_pixbuf = NULL;
   first = TRUE;
 
-  window = gtk_widget_get_window (widget);
-  gtk_widget_get_allocation (widget, &allocation);
-
   style = gtk_widget_get_style (widget);
   gtk_widget_style_get (widget,
 			"focus-line-width", &focus_width,
 			NULL);
 
-  cr = gdk_cairo_create (window);
-
   if (gtk_widget_has_focus (widget))
     gtk_paint_focus (style,
-		     window,
+		     cr,
 		     gtk_widget_get_state (widget),
-		     NULL,
 		     widget,
 		     "pager",
 		     0, 0,
-		     allocation.width,
-		     allocation.height);
+		     gtk_widget_get_allocated_width (widget),
+		     gtk_widget_get_allocated_height (widget));
 
   if (pager->priv->shadow_type != GTK_SHADOW_NONE)
     {
       gtk_paint_shadow (style,
-			window,
+			cr,
 			gtk_widget_get_state (widget),
 			pager->priv->shadow_type,
-			NULL,
 			widget,
 			"pager",
 			focus_width,
 			focus_width,
-			allocation.width - 2 * focus_width,
-			allocation.height - 2 * focus_width);
+                        gtk_widget_get_allocated_width (widget) - 2 * focus_width,
+                        gtk_widget_get_allocated_height (widget) - 2 * focus_width);
     }
   
   i = 0;
@@ -1659,7 +1646,7 @@ wnck_update_drag_icon (WnckWindow     *window,
   gint org_w, org_h, dnd_w, dnd_h;
   WnckWorkspace *workspace;
   GdkRectangle rect;
-  GdkPixmap *pixmap;
+  cairo_surface_t *surface;
   GtkWidget *widget;
   cairo_t *cr;
 
@@ -1690,19 +1677,18 @@ wnck_update_drag_icon (WnckWindow     *window,
   rect.width = MAX (rect.width, 3);
   rect.height = MAX (rect.height, 3);
 
-  pixmap = gdk_pixmap_new (gtk_widget_get_window (widget),
-                           rect.width, rect.height, -1);
-  cr = gdk_cairo_create (pixmap);
+  surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+                                               CAIRO_CONTENT_COLOR,
+                                               rect.width, rect.height);
+  cr = cairo_create (surface);
   draw_window (cr, widget, window,
 	       &rect, GTK_STATE_NORMAL, FALSE);  
   cairo_destroy (cr);
+  cairo_surface_set_device_offset (surface, 2, 2);
 
-  gtk_drag_set_icon_pixmap (context, 
-                            gdk_drawable_get_colormap (GDK_DRAWABLE (pixmap)),
-			    pixmap, NULL,
-			    -2, -2);
+  gtk_drag_set_icon_surface (context, surface);
 
-  g_object_unref (pixmap);
+  cairo_surface_destroy (surface);
 }
 
 static void
@@ -2589,10 +2575,7 @@ wnck_pager_get_background (WnckPager *pager,
   if (p != None)
     {
       _wnck_error_trap_push ();
-      pix = _wnck_gdk_pixbuf_get_from_pixmap (NULL,
-                                              p,
-                                              0, 0, 0, 0,
-                                              -1, -1);
+      pix = _wnck_gdk_pixbuf_get_from_pixmap (p);
       _wnck_error_trap_pop ();
     }
 
diff --git a/libwnck/tasklist.c b/libwnck/tasklist.c
index 4f0c6c4..5095898 100644
--- a/libwnck/tasklist.c
+++ b/libwnck/tasklist.c
@@ -154,8 +154,8 @@ struct _WnckTask
 
   guint32 dnd_timestamp;
 
-  GdkPixmap *screenshot;
-  GdkPixmap *screenshot_faded;
+  cairo_surface_t *screenshot;
+  cairo_surface_t *screenshot_faded;
 
   time_t  start_needs_attention;
   gdouble glow_start_time;
@@ -231,8 +231,6 @@ struct _WnckTasklistPrivate
   GdkRectangle monitor_geometry;
   GtkReliefStyle relief;
   
-  GdkPixmap *background;
-
   guint drag_start_time;
 };
 
@@ -299,8 +297,6 @@ static void     wnck_tasklist_size_allocate (GtkWidget        *widget,
                                              GtkAllocation    *allocation);
 static void     wnck_tasklist_realize       (GtkWidget        *widget);
 static void     wnck_tasklist_unrealize     (GtkWidget        *widget);
-static gint     wnck_tasklist_expose        (GtkWidget        *widget,
-                                             GdkEventExpose    *event);
 static void     wnck_tasklist_forall        (GtkContainer     *container,
                                              gboolean	       include_internals,
                                              GtkCallback       callback,
@@ -372,12 +368,12 @@ cleanup_screenshots (WnckTask *task)
 {
   if (task->screenshot != NULL)
     {
-      g_object_unref (task->screenshot);
+      cairo_surface_destroy (task->screenshot);
       task->screenshot = NULL;
     }
   if (task->screenshot_faded != NULL)
     {
-      g_object_unref (task->screenshot_faded);
+      cairo_surface_destroy (task->screenshot_faded);
       task->screenshot_faded = NULL;
     }
 }
@@ -507,13 +503,12 @@ wnck_task_button_glow (WnckTask *task)
 
   cairo_save (cr);
 
-  gdk_cairo_set_source_pixmap (cr, task->screenshot, 0., 0.);
-  cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+  cairo_set_source_surface (cr, task->screenshot, 0., 0.);
   cairo_paint (cr);
 
   cairo_restore (cr);
 
-  gdk_cairo_set_source_pixmap (cr, task->screenshot_faded, 0., 0.);
+  cairo_set_source_surface (cr, task->screenshot_faded, 0., 0.);
   cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
   cairo_paint_with_alpha (cr, glow_factor);
 
@@ -725,8 +720,6 @@ wnck_tasklist_init (WnckTasklist *tasklist)
   tasklist->priv->monitor_geometry.width = -1; /* invalid value */
   tasklist->priv->relief = GTK_RELIEF_NORMAL;
   
-  tasklist->priv->background = NULL;
-
   tasklist->priv->drag_start_time = 0;
 
   atk_obj = gtk_widget_get_accessible (widget);
@@ -750,7 +743,6 @@ wnck_tasklist_class_init (WnckTasklistClass *klass)
   widget_class->size_allocate = wnck_tasklist_size_allocate;
   widget_class->realize = wnck_tasklist_realize;
   widget_class->unrealize = wnck_tasklist_unrealize;
-  widget_class->expose_event = wnck_tasklist_expose;
   
   container_class->forall = wnck_tasklist_forall;
   container_class->remove = wnck_tasklist_remove;
@@ -908,12 +900,6 @@ wnck_tasklist_finalize (GObject *object)
   tasklist->priv->free_icon_loader_data = NULL;
   tasklist->priv->icon_loader_data = NULL;
 
-  if (tasklist->priv->background)
-    {
-      g_object_unref (tasklist->priv->background);
-      tasklist->priv->background = NULL;
-    }
-
   G_OBJECT_CLASS (wnck_tasklist_parent_class)->finalize (object);
 }
 
@@ -1321,7 +1307,8 @@ wnck_tasklist_size_request  (GtkWidget      *widget,
     {                                                           \
       WnckTask *task = WNCK_TASK (l->data);                     \
                                                                 \
-      gtk_widget_size_request (task->button, &child_req);       \
+      gtk_widget_get_preferred_size (task->button,              \
+                                     &child_req, NULL);         \
                                                                 \
       max_height = MAX (child_req.height,                       \
 			max_height);                            \
@@ -1743,45 +1730,6 @@ wnck_tasklist_unrealize (GtkWidget *widget)
 		   NULL);
 }
 
-static gint
-wnck_tasklist_expose (GtkWidget      *widget,
-                      GdkEventExpose *event)
-{
-  WnckTasklist *tasklist;
-  GdkGC *gc;
-  
-  g_return_val_if_fail (WNCK_IS_TASKLIST (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
-  
-  if (gtk_widget_is_drawable (widget))
-    {
-      GdkWindow *window;
-      GtkAllocation allocation;
-
-      window = gtk_widget_get_window (widget);
-      gtk_widget_get_allocation (widget, &allocation);
-
-      tasklist = WNCK_TASKLIST (widget);
-      /* get a screenshot of the background */
-      
-      if (tasklist->priv->background != NULL)
-        g_object_unref (tasklist->priv->background);
-      
-      tasklist->priv->background = gdk_pixmap_new (window,
-                                                   allocation.width,
-                                                   allocation.height,
-                                                   -1);
-      gc = gdk_gc_new (tasklist->priv->background);
-      gdk_draw_drawable (tasklist->priv->background, gc, window,
-                         allocation.x, allocation.y, 0, 0,
-                         allocation.width, allocation.height);
-      
-      g_object_unref (gc);
-    }
-  
-  return (* GTK_WIDGET_CLASS (wnck_tasklist_parent_class)->expose_event) (widget, event);
-}
-
 static void
 wnck_tasklist_forall (GtkContainer *container,
                       gboolean      include_internals,
@@ -2713,7 +2661,7 @@ wnck_task_position_menu (GtkMenu   *menu,
   gint pointer_x;
   gint pointer_y;
   
-  gtk_widget_size_request (GTK_WIDGET (menu), &requisition);
+  gtk_widget_get_preferred_size (GTK_WIDGET (menu), &requisition, NULL);
 
   window = gtk_widget_get_window (widget);
   gtk_widget_get_allocation (widget, &allocation);
@@ -3782,9 +3730,9 @@ wnck_task_button_press_event (GtkWidget	      *widget,
 }
 
 static gboolean
-wnck_task_expose (GtkWidget        *widget,
-                  GdkEventExpose   *event,
-                  gpointer          data);
+wnck_task_draw (GtkWidget *widget,
+                cairo_t   *cr,
+                gpointer   data);
 
 static void
 wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief)
@@ -3952,68 +3900,31 @@ wnck_task_create_widgets (WnckTask *task, GtkReliefStyle relief)
       g_assert_not_reached ();
     }
 
-  g_signal_connect_object (task->button, "expose_event",
-                           G_CALLBACK (wnck_task_expose),
+  g_signal_connect_object (task->button, "draw",
+                           G_CALLBACK (wnck_task_draw),
                            G_OBJECT (task),
                            G_CONNECT_AFTER);
 }
 
-static void
-fake_expose_widget (GtkWidget *widget,
-                    GdkPixmap *pixmap,
-                    gint       x,
-                    gint       y)
-{
-  GdkWindow *tmp_window;
-  GdkEventExpose event;
-  GtkAllocation allocation;
-
-  event.type = GDK_EXPOSE;
-  event.window = pixmap;
-  event.send_event = FALSE;
-  event.region = NULL;
-  event.count = 0;
-
-  tmp_window = gtk_widget_get_window (widget);
-  gtk_widget_get_allocation (widget, &allocation);
-
-  /* FIXME GSeal: we should use this:
-  gtk_widget_set_window (widget, pixmap);
-     but pixmap is not a GdkWindow...
-   */
-  widget->window = pixmap;
-  allocation.x += x;
-  allocation.y += y;
-  gtk_widget_set_allocation (widget, &allocation);
-
-  event.area = allocation;
-
-  gtk_widget_send_expose (widget, (GdkEvent *) &event);
-
-  gtk_widget_set_window (widget, tmp_window);
-  allocation.x -= x;
-  allocation.y -= y;
-  gtk_widget_set_allocation (widget, &allocation);
-}
-
-static GdkPixmap *
+static cairo_surface_t *
 take_screenshot (WnckTask *task)
 {
-  GtkAllocation allocation;
   WnckTasklist *tasklist;
   GtkWidget    *tasklist_widget;
-  GdkPixmap *pixmap;
+  cairo_surface_t *surface;
+  GtkAllocation allocation;
+  cairo_t *cr;
   gint width, height;
   gboolean overlay_rect;
 
-  gtk_widget_get_allocation (task->button, &allocation);
-  
-  width = allocation.width;
-  height = allocation.height;
-  
-  pixmap = gdk_pixmap_new (gtk_widget_get_window (task->button),
-                           width, height, -1);
+  width = gtk_widget_get_allocated_width (task->button);
+  height = gtk_widget_get_allocated_height (task->button);
   
+  surface = gdk_window_create_similar_surface (gtk_widget_get_window (task->button),
+                                               CAIRO_CONTENT_COLOR_ALPHA,
+                                               width, height);
+  cr = cairo_create (surface);
+                      
   tasklist = WNCK_TASKLIST (task->tasklist);
   tasklist_widget = GTK_WIDGET (task->tasklist);
 
@@ -4026,8 +3937,8 @@ take_screenshot (WnckTask *task)
       style = gtk_widget_get_style (task->button);
 
       /* Draw a rectangle with bg[SELECTED] */
-      gdk_draw_rectangle (pixmap, style->bg_gc[GTK_STATE_SELECTED],
-                          TRUE, 0, 0, width + 1, height + 1);
+      gdk_cairo_set_source_color (cr, &style->bg[GTK_STATE_SELECTED]);
+      cairo_paint (cr);
     }
   else
     {
@@ -4041,18 +3952,12 @@ take_screenshot (WnckTask *task)
       style = gtk_style_copy (gtk_widget_get_style (task->button));
       style->bg[state] = style->bg[GTK_STATE_SELECTED];
       /* Now attach it to the window */
-      attached_style = gtk_style_attach (style, pixmap);
+      attached_style = gtk_style_attach (style, gtk_widget_get_window (task->button));
       g_object_ref (attached_style);
       
-      /* copy the background */
-      gdk_draw_drawable (pixmap, attached_style->bg_gc[GTK_STATE_NORMAL],
-                         tasklist->priv->background,
-                         allocation.x, allocation.y,
-                         0, 0, width, height);
-      
       /* draw the button with our modified style instead of the real one. */
-      gtk_paint_box (attached_style, (GdkWindow*) pixmap, state,
-                     GTK_SHADOW_OUT, NULL, task->button, "button",
+      gtk_paint_box (attached_style, cr, state,
+                     GTK_SHADOW_OUT, task->button, "button",
                      0, 0, width, height);
 
       g_object_unref (style);
@@ -4061,54 +3966,47 @@ take_screenshot (WnckTask *task)
     }
   
   /* then the image and label */
-  fake_expose_widget (task->image, pixmap,
-                      -allocation.x, -allocation.y);
-  fake_expose_widget (task->label, pixmap,
-                      -allocation.x, -allocation.y);
+  cairo_save (cr);
+  gtk_widget_get_allocation (task->image, &allocation);
+  cairo_translate (cr, allocation.x, allocation.y);
+  gtk_widget_draw (task->image, cr);
+  cairo_restore (cr);
+
+  cairo_save (cr);
+  gtk_widget_get_allocation (task->label, &allocation);
+  cairo_translate (cr, allocation.x, allocation.y);
+  gtk_widget_draw (task->label, cr);
+  cairo_restore (cr);
   
-  return pixmap;
+  return surface;
 }
 
-static GdkPixmap *
-copy_pixmap (GtkWidget *widget)
+static cairo_surface_t *
+copy_surface (GtkWidget *widget)
 {
-  GdkWindow *window;
-  GtkAllocation allocation;
-  GdkPixmap *pixmap;
-  GtkStyle *style;
-
-  window = gtk_widget_get_window (widget);
-  gtk_widget_get_allocation (widget, &allocation);
-  style = gtk_widget_get_style (widget);
+  cairo_surface_t *surface;
+  cairo_t *cr;
 
-  pixmap = gdk_pixmap_new (window,
-                           allocation.width,
-                           allocation.height, -1);
+  surface = gdk_window_create_similar_surface (gtk_widget_get_window (widget),
+                                               CAIRO_CONTENT_COLOR_ALPHA,
+                                               gtk_widget_get_allocated_width (widget),
+                                               gtk_widget_get_allocated_height (widget));
 
-  gdk_draw_drawable (pixmap,
-                     style->bg_gc[GTK_STATE_NORMAL],
-                     window,
-                     allocation.x, allocation.y,
-                     0, 0,
-                     allocation.width, allocation.height);
+  cr = cairo_create (surface);
+  gtk_widget_draw (widget, cr);
+  cairo_destroy (cr);
 
-  return pixmap;
+  return surface;
 }
 
 static gboolean
-wnck_task_expose (GtkWidget        *widget,
-                  GdkEventExpose   *event,
-                  gpointer          data)
+wnck_task_draw (GtkWidget *widget,
+                cairo_t   *cr,
+                gpointer   data)
 {
-  GtkStyle *style;
-  GdkWindow *window;
-  GtkAllocation allocation;
-  GdkGC *lgc, *dgc;
   int x, y;
   WnckTask *task;
-
-  window = gtk_widget_get_window (widget);
-  gtk_widget_get_allocation (widget, &allocation);
+  GtkStyle *style;
 
   task = WNCK_TASK (data);
   
@@ -4118,33 +4016,32 @@ wnck_task_expose (GtkWidget        *widget,
     {
     case WNCK_TASK_CLASS_GROUP:
       style = gtk_widget_get_style (widget);
-      lgc = style->light_gc[GTK_STATE_NORMAL];
-      dgc = style->dark_gc[GTK_STATE_NORMAL];
 
-      x = allocation.x + allocation.width -
+      x = gtk_widget_get_allocated_width (widget) -
           (gtk_container_get_border_width (GTK_CONTAINER (widget)) + style->ythickness + 12);
-      y = allocation.y + allocation.height / 2 - 5;
+      y = gtk_widget_get_allocated_height (widget) / 2 - 5;
 
-      gtk_paint_tab (style, window,
+      gtk_paint_tab (style,
+                     cr,
 		     task->tasklist->priv->active_class_group == task ?
 		       GTK_STATE_ACTIVE : GTK_STATE_NORMAL,
-		     GTK_SHADOW_NONE, NULL, widget, NULL, x, y, 10, 10);
+		     GTK_SHADOW_NONE, widget, NULL, x, y, 10, 10);
 
       /* Fall through to get screenshot
        */
     case WNCK_TASK_WINDOW:
-      if ((event->area.x <= allocation.x) &&
-          (event->area.y <= allocation.y) &&
-          (event->area.width >= allocation.width) &&
-          (event->area.height >= allocation.height))
+      if (task->start_needs_attention)
         {
-          if (task->start_needs_attention)
-            {
-              task->screenshot = copy_pixmap (widget);
-              task->screenshot_faded = take_screenshot (task);
+          time_t attention = task->start_needs_attention;
+          
+          task->start_needs_attention = 0;
 
-              wnck_task_button_glow (task);
-            }
+          task->screenshot = copy_surface (widget);
+          task->screenshot_faded = take_screenshot (task);
+
+          task->start_needs_attention = attention;
+
+          wnck_task_button_glow (task);
         }
 
     case WNCK_TASK_STARTUP_SEQUENCE:
diff --git a/libwnck/test-tasklist.c b/libwnck/test-tasklist.c
index dd7e917..e205563 100644
--- a/libwnck/test-tasklist.c
+++ b/libwnck/test-tasklist.c
@@ -21,18 +21,13 @@ static GOptionEntry entries[] = {
 };
 
 static gboolean
-window_expose_event (GtkWidget      *widget,
-		     GdkEventExpose *event,
-		     gpointer        user_data)
+window_draw (GtkWidget      *widget,
+	     cairo_t        *cr,
+	     gpointer        user_data)
 {
-  cairo_t *cr;
-
-  cr = gdk_cairo_create (gtk_widget_get_window (widget));
   cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
-  gdk_cairo_region (cr, event->region);
   cairo_set_source_rgba (cr, 1., 1., 1., .5);
   cairo_fill (cr);
-  cairo_destroy (cr);
 
   return FALSE;
 }
@@ -102,13 +97,13 @@ main (int argc, char **argv)
 
   if (transparent)
     {
-      GdkColormap *map;
+      GdkVisual *visual;
 
-      map = gdk_screen_get_rgba_colormap (gtk_widget_get_screen (win));
+      visual = gdk_screen_get_rgba_visual (gtk_widget_get_screen (win));
 
-      if (map != NULL)
+      if (visual != NULL)
         {
-          gtk_widget_set_colormap (win, map);
+          gtk_widget_set_visual (win, visual);
 
           g_signal_connect (win, "composited-changed",
                             G_CALLBACK (window_composited_changed),
@@ -117,8 +112,8 @@ main (int argc, char **argv)
           /* draw even if we are not app-painted.
            * this just makes my life a lot easier :)
            */
-          g_signal_connect (win, "expose-event",
-                            G_CALLBACK (window_expose_event),
+          g_signal_connect (win, "draw",
+                            G_CALLBACK (window_draw),
                             NULL);
 
           window_composited_changed (win, NULL);
diff --git a/libwnck/xutils.c b/libwnck/xutils.c
index 92b9201..39c87e2 100644
--- a/libwnck/xutils.c
+++ b/libwnck/xutils.c
@@ -25,6 +25,7 @@
 #include "xutils.h"
 #include <string.h>
 #include <stdio.h>
+#include <cairo-xlib.h>
 #include "screen.h"
 #include "window.h"
 #include "private.h"
@@ -1644,97 +1645,48 @@ apply_mask (GdkPixbuf *pixbuf,
   return with_alpha;
 }
 
-static GdkColormap*
-get_cmap (GdkPixmap *pixmap)
+GdkPixbuf*
+_wnck_gdk_pixbuf_get_from_pixmap (Pixmap       xpixmap)
 {
-  GdkColormap *cmap;
+  cairo_surface_t *surface;
+  Display *display;
+  Window root_return;
+  int x_ret, y_ret;
+  unsigned int w_ret, h_ret, bw_ret, depth_ret;
+  XWindowAttributes attrs;
+  GdkPixbuf *retval;
 
-  cmap = gdk_drawable_get_colormap (pixmap);
-  if (cmap)
-    g_object_ref (G_OBJECT (cmap));
+  display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
 
-  if (cmap == NULL)
-    {
-      if (gdk_drawable_get_depth (pixmap) == 1)
-        {
-          /* try null cmap */
-          cmap = NULL;
-        }
-      else
-        {
-          /* Try system cmap */
-          GdkScreen *screen = gdk_drawable_get_screen (GDK_DRAWABLE (pixmap));
-          cmap = gdk_screen_get_system_colormap (screen);
-          g_object_ref (G_OBJECT (cmap));
-        }
-    }
+  if (!XGetGeometry (display, xpixmap, &root_return,
+                     &x_ret, &y_ret, &w_ret, &h_ret, &bw_ret, &depth_ret))
+    return NULL;
 
-  /* Be sure we aren't going to blow up due to visual mismatch */
-  if (cmap &&
-#if GTK_CHECK_VERSION(2,21,0)
-      (gdk_visual_get_depth (gdk_colormap_get_visual (cmap)) !=
-       gdk_drawable_get_depth (pixmap))
-#else
-      (gdk_colormap_get_visual (cmap)->depth !=
-       gdk_drawable_get_depth (pixmap))
-#endif
-     )
+  if (depth_ret == 1)
     {
-      g_object_unref (G_OBJECT (cmap));
-      cmap = NULL;
+      surface = cairo_xlib_surface_create_for_bitmap (display,
+                                                      xpixmap,
+                                                      GDK_SCREEN_XSCREEN (gdk_screen_get_default ()),
+                                                      w_ret,
+                                                      h_ret);
     }
-  
-  return cmap;
-}
-
-GdkPixbuf*
-_wnck_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
-                                  Pixmap       xpixmap,
-                                  int          src_x,
-                                  int          src_y,
-                                  int          dest_x,
-                                  int          dest_y,
-                                  int          width,
-                                  int          height)
-{
-  GdkDrawable *drawable;
-  GdkPixbuf *retval;
-  GdkColormap *cmap;
-  
-  retval = NULL;
-  cmap = NULL;
-  
-  drawable = gdk_xid_table_lookup (xpixmap);
-
-  if (drawable)
-    g_object_ref (G_OBJECT (drawable));
   else
-    drawable = gdk_pixmap_foreign_new (xpixmap);
-
-  if (drawable)
     {
-      cmap = get_cmap (drawable);
+      if (!XGetWindowAttributes (display, root_return, &attrs))
+        return NULL;
 
-      /* GDK is supposed to do this but doesn't in GTK 2.0.2,
-       * fixed in 2.0.3
-       */
-      if (width < 0)
-        gdk_drawable_get_size (drawable, &width, NULL);
-      if (height < 0)
-        gdk_drawable_get_size (drawable, NULL, &height);
-
-      retval = gdk_pixbuf_get_from_drawable (dest,
-                                             drawable,
-                                             cmap,
-                                             src_x, src_y,
-                                             dest_x, dest_y,
-                                             width, height);
+      surface = cairo_xlib_surface_create (display,
+                                           xpixmap,
+                                           attrs.visual,
+                                           w_ret, h_ret);
     }
 
-  if (cmap)
-    g_object_unref (G_OBJECT (cmap));
-  if (drawable)
-    g_object_unref (G_OBJECT (drawable));
+  retval = gdk_pixbuf_get_from_surface (surface,
+                                        0,
+                                        0,
+                                        w_ret,
+                                        h_ret);
+  cairo_surface_destroy (surface);
 
   return retval;
 }
@@ -1760,18 +1712,12 @@ try_pixmap_and_mask (Pixmap      src_pixmap,
 
   get_pixmap_geometry (src_pixmap, &w, &h, NULL);
       
-  unscaled = _wnck_gdk_pixbuf_get_from_pixmap (NULL,
-                                               src_pixmap,
-                                               0, 0, 0, 0,
-                                               w, h);
+  unscaled = _wnck_gdk_pixbuf_get_from_pixmap (src_pixmap);
 
   if (unscaled && src_mask != None)
     {
       get_pixmap_geometry (src_mask, &w, &h, NULL);
-      mask = _wnck_gdk_pixbuf_get_from_pixmap (NULL,
-                                               src_mask,
-                                               0, 0, 0, 0,
-                                               w, h);
+      mask = _wnck_gdk_pixbuf_get_from_pixmap (src_mask);
     }
   
   _wnck_error_trap_pop ();
diff --git a/libwnck/xutils.h b/libwnck/xutils.h
index b25b6b8..2b35d09 100644
--- a/libwnck/xutils.h
+++ b/libwnck/xutils.h
@@ -194,14 +194,7 @@ void _wnck_set_desktop_layout (Screen *xscreen,
                                int     rows,
                                int     columns);
 
-GdkPixbuf* _wnck_gdk_pixbuf_get_from_pixmap (GdkPixbuf   *dest,
-                                             Pixmap       xpixmap,
-                                             int          src_x,
-                                             int          src_y,
-                                             int          dest_x,
-                                             int          dest_y,
-                                             int          width,
-                                             int          height);
+GdkPixbuf* _wnck_gdk_pixbuf_get_from_pixmap (Pixmap       xpixmap);
 
 #define WNCK_NO_MANAGER_TOKEN 0
 



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