Index: launcher.c
===================================================================
--- launcher.c	(révision 10793)
+++ launcher.c	(copie de travail)
@@ -203,7 +203,10 @@ launcher_launch (Launcher  *launcher,
 	g_return_if_fail (launcher->key_file != NULL);
 
 	if (panel_global_config_get_enable_animations ())
-		xstuff_zoom_animate (widget, NULL);
+		xstuff_zoom_animate (widget,
+				     button_widget_get_pixbuf (BUTTON_WIDGET (widget)),
+				     button_widget_get_orientation (BUTTON_WIDGET (widget)),
+				     NULL);
 	
 	type = panel_util_key_file_get_string (launcher->key_file, "Type");
 	if (type && !strcmp (type, "Link"))
@@ -266,7 +269,10 @@ drag_data_received_cb (GtkWidget        
 	GList   *file_list;
 
 	if (panel_global_config_get_enable_animations ())
-		xstuff_zoom_animate (widget, NULL);
+		xstuff_zoom_animate (widget,
+				     button_widget_get_pixbuf (BUTTON_WIDGET (widget)),
+				     button_widget_get_orientation (BUTTON_WIDGET (widget)),
+				     NULL);
 	
 	file_list = NULL;
 	uris = g_uri_list_extract_uris ((const char *) selection_data->data);
Index: xstuff.c
===================================================================
--- xstuff.c	(révision 10787)
+++ xstuff.c	(copie de travail)
@@ -18,10 +18,12 @@
 
 #include <gdk/gdk.h>
 #include <gdk/gdkx.h>
+#include <gtk/gtk.h>
 
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 
+#include "panel-enums.h"
 #include "xstuff.h"
 
 static int (* xstuff_old_xio_error_handler) (Display *) = NULL;
@@ -287,6 +289,173 @@ xstuff_delete_property (GdkWindow *windo
 /* the delay per draw */
 #define MINIATURIZE_ANIMATION_DELAY_Z    10
 
+/* zoom factor, steps and delay if composited (factor must be odd) */
+#define ZOOM_FACTOR 5
+#define ZOOM_STEPS  14
+#define ZOOM_DELAY 10
+
+typedef struct {
+	int size;
+	int size_start;
+	int size_end;
+	PanelOrientation orientation;
+	double opacity;
+	GdkPixbuf *pixbuf;
+	guint timeout_id;
+} CompositedZoomData;
+
+static gboolean
+zoom_timeout (GtkWidget *window)
+{
+	gtk_widget_queue_draw (window);
+	return TRUE;
+}
+
+static gboolean
+zoom_expose (GtkWidget      *widget,
+	     GdkEventExpose *event,
+	     gpointer        user_data)
+{
+	CompositedZoomData *zoom;
+
+	zoom = user_data;
+
+	if (zoom->size >= zoom->size_end) {
+		if (zoom->timeout_id)
+			g_source_remove (zoom->timeout_id);
+		zoom->timeout_id = 0;
+
+		g_object_unref (zoom->pixbuf);
+		zoom->pixbuf = 0;
+
+		g_slice_free (CompositedZoomData, zoom);
+
+		gtk_widget_destroy (widget);
+	} else {
+		GdkPixbuf *scaled;
+		int width, height;
+		int x = 0, y = 0;
+		cairo_t *cr;
+
+		gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+
+		zoom->size += MAX ((zoom->size_end - zoom->size_start) / ZOOM_STEPS, 1);
+		zoom->opacity -= 1.0 / ((double) ZOOM_STEPS + 1);
+
+		scaled = gdk_pixbuf_scale_simple (zoom->pixbuf,
+						  zoom->size, zoom->size,
+						  GDK_INTERP_BILINEAR);
+
+		switch (zoom->orientation) {
+		case PANEL_ORIENTATION_TOP:
+			x = (width - gdk_pixbuf_get_width (scaled)) / 2;
+			y = 0;
+			break;
+
+		case PANEL_ORIENTATION_RIGHT:
+			x = width - gdk_pixbuf_get_width (scaled);
+			y = (height - gdk_pixbuf_get_height (scaled)) / 2;
+			break;
+
+		case PANEL_ORIENTATION_BOTTOM:
+			x = (width - gdk_pixbuf_get_width (scaled)) / 2;
+			y = height - gdk_pixbuf_get_height (scaled);
+			break;
+
+		case PANEL_ORIENTATION_LEFT:
+			x = 0;
+			y = (height - gdk_pixbuf_get_height (scaled)) / 2;
+			break;
+		}
+
+
+		cr = gdk_cairo_create (widget->window);
+		cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
+		cairo_set_source_rgba (cr, 0, 0, 0, 0.0);
+		cairo_rectangle (cr, 0, 0, width, height);
+		cairo_fill (cr);
+
+		gdk_cairo_set_source_pixbuf (cr, scaled, x, y);
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_paint_with_alpha (cr, MAX (zoom->opacity, 0));
+
+		cairo_destroy (cr);
+		g_object_unref (scaled);
+	}
+
+	return FALSE;
+}
+
+static void 
+draw_zoom_animation_composited (GdkScreen *gscreen,
+				int x, int y, int w, int h,
+				GdkPixbuf *pixbuf,
+				PanelOrientation orientation)
+{
+	GtkWidget *win;
+	CompositedZoomData *zoom;
+	int wx = 0, wy = 0;
+
+	w += 2;
+	h += 2;
+
+	zoom = g_slice_new (CompositedZoomData);
+	zoom->size = w;
+	zoom->size_start = w;
+	zoom->size_end = w * ZOOM_FACTOR;
+	zoom->orientation = orientation;
+	zoom->opacity = 1.0;
+	zoom->pixbuf = g_object_ref (pixbuf);
+	zoom->timeout_id = 0;
+
+	win = gtk_window_new (GTK_WINDOW_POPUP);
+
+	gtk_window_set_keep_above (GTK_WINDOW (win), TRUE);
+	gtk_window_set_decorated (GTK_WINDOW (win), FALSE);
+	gtk_widget_set_app_paintable(win, TRUE);
+	gtk_widget_set_colormap (win, gdk_screen_get_rgba_colormap (gscreen));
+
+	gtk_window_set_gravity (GTK_WINDOW (win), GDK_GRAVITY_STATIC);
+	gtk_window_set_default_size (GTK_WINDOW (win),
+				     w * ZOOM_FACTOR, h * ZOOM_FACTOR);
+
+	switch (zoom->orientation) {
+	case PANEL_ORIENTATION_TOP:
+		wx = x - w * (ZOOM_FACTOR / 2);
+		wy = y;
+		break;
+
+	case PANEL_ORIENTATION_RIGHT:
+		wx = x - w * (ZOOM_FACTOR - 1);
+		wy = y - h * (ZOOM_FACTOR / 2);
+		break;
+
+	case PANEL_ORIENTATION_BOTTOM:
+		wx = x - w * (ZOOM_FACTOR / 2);
+		wy = y - h * (ZOOM_FACTOR - 1);
+		break;
+
+	case PANEL_ORIENTATION_LEFT:
+		wx = x;
+		wy = y - h * (ZOOM_FACTOR / 2);
+		break;
+	}
+
+	gtk_window_move (GTK_WINDOW (win), wx, wy);
+
+	g_signal_connect (G_OBJECT (win), "expose-event",
+			  G_CALLBACK (zoom_expose), zoom);
+
+	/* see doc for gtk_widget_set_app_paintable() */
+	gtk_widget_realize (win);
+	gdk_window_set_back_pixmap (win->window, NULL, FALSE);
+	gtk_widget_show (win);
+
+	zoom->timeout_id = g_timeout_add (ZOOM_DELAY,
+					  (GSourceFunc) zoom_timeout,
+					  win);
+}
+
 static void 
 draw_zoom_animation (GdkScreen *gscreen,
 		     int x, int y, int w, int h,
@@ -337,7 +506,7 @@ draw_zoom_animation (GdkScreen *gscreen,
 	ystep = (float)(fy-y)/steps;
 	wstep = (float)(fw-w)/steps;
 	hstep = (float)(fh-h)/steps;
-    
+
 	for (j=0; j<FRAMES; j++) {
 		cx[j] = (float)x;
 		cy[j] = (float)y;
@@ -367,12 +536,12 @@ draw_zoom_animation (GdkScreen *gscreen,
 				cy[j]=cy[j+1];
 				cw[j]=cw[j+1];
 				ch[j]=ch[j+1];
-				
+
 				cxi[j]=cxi[j+1];
 				cyi[j]=cyi[j+1];
 				cwi[j]=cwi[j+1];
 				chi[j]=chi[j+1];
-				
+
 			} else {
 				cx[j]+=xstep;
 				cy[j]+=ystep;
@@ -401,16 +570,20 @@ draw_zoom_animation (GdkScreen *gscreen,
 		XDrawRectangle(dpy, root_win, frame_gc, 
 				       cxi[j], cyi[j], cwi[j], chi[j]);
 	}
-    
+
 	XUngrabServer(dpy);
 	XFreeGC (dpy, frame_gc);
 	gdk_colormap_free_colors (gdk_screen_get_system_colormap (gscreen),
 				  &color, 1);
+
 }
 #undef FRAMES
 
 void
-xstuff_zoom_animate (GtkWidget *widget, GdkRectangle *opt_rect)
+xstuff_zoom_animate (GtkWidget *widget,
+		     GdkPixbuf *pixbuf,
+		     PanelOrientation orientation,
+		     GdkRectangle *opt_rect)
 {
 	GdkScreen *gscreen;
 	GdkRectangle rect, dest;
@@ -429,13 +602,22 @@ xstuff_zoom_animate (GtkWidget *widget, 
 	}
 
 	gscreen = gtk_widget_get_screen (widget);
-	monitor = gdk_screen_get_monitor_at_window (gscreen, widget->window);
-	gdk_screen_get_monitor_geometry (gscreen, monitor, &dest);
 
-	draw_zoom_animation (gscreen,
-			     rect.x, rect.y, rect.width, rect.height,
-			     dest.x, dest.y, dest.width, dest.height,
-			     MINIATURIZE_ANIMATION_STEPS_Z);
+	if (gdk_screen_is_composited (gscreen))
+		draw_zoom_animation_composited (gscreen,
+						rect.x, rect.y,
+						rect.width, rect.height,
+						pixbuf, orientation);
+	else {
+		monitor = gdk_screen_get_monitor_at_window (gscreen,
+							    widget->window);
+		gdk_screen_get_monitor_geometry (gscreen, monitor, &dest);
+
+		draw_zoom_animation (gscreen,
+				     rect.x, rect.y, rect.width, rect.height,
+				     dest.x, dest.y, dest.width, dest.height,
+				     MINIATURIZE_ANIMATION_STEPS_Z);
+	}
 }
 
 int
Index: xstuff.h
===================================================================
--- xstuff.h	(révision 10787)
+++ xstuff.h	(copie de travail)
@@ -21,8 +21,10 @@ void xstuff_set_wmspec_strut		(GdkWindow
 					 int top,
 					 int bottom);
 
-void xstuff_zoom_animate                (GtkWidget    *widget,
-					 GdkRectangle *opt_src_rect);
+void xstuff_zoom_animate                (GtkWidget        *widget,
+					 GdkPixbuf        *pixbuf,
+					 PanelOrientation  orientation,
+					 GdkRectangle     *opt_src_rect);
 
 int  xstuff_get_current_workspace       (GdkScreen *screen);
 
