Index: gnome-panel/launcher.c
===================================================================
--- gnome-panel/launcher.c	(revision 10673)
+++ gnome-panel/launcher.c	(working copy)
@@ -187,7 +187,10 @@
 	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"))
@@ -249,7 +252,10 @@
 	GList      *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);
 	
 	list = gnome_vfs_uri_list_parse ((const char*) selection_data->data);
 	for (li = list; li != NULL; li = li->next) {
Index: gnome-panel/xstuff.c
===================================================================
--- gnome-panel/xstuff.c	(revision 10673)
+++ gnome-panel/xstuff.c	(working copy)
@@ -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;
@@ -286,131 +288,275 @@
 #define MINIATURIZE_ANIMATION_STEPS_Z    6
 /* 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  12
+#define ZOOM_DELAY 12000
 
+static int zoom_size;
+static int zoom_size_start;
+static int zoom_size_end;
+static PanelOrientation zoom_orientation;
+static double zoom_opacity;
+static GdkPixbuf *zoom_pixbuf = NULL;
+
+static gboolean
+zoom_expose (GtkWidget *widget, GdkEventExpose *event, gpointer user_data)
+{
+	cairo_t *cr;
+	int width, height;
+
+	gtk_window_get_size (GTK_WINDOW (widget), &width, &height);
+
+	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);
+
+	if (zoom_size > zoom_size_end)
+	{
+		gtk_widget_destroy (widget);
+	}
+	else
+	{
+		GdkPixbuf *scaled;
+		int x = 0, y = 0;
+
+		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);
+
+		g_object_unref (zoom_pixbuf);
+		zoom_pixbuf = scaled;
+
+		switch (zoom_orientation)
+		{
+			case PANEL_ORIENTATION_TOP:
+				x = width/2 - gdk_pixbuf_get_width (zoom_pixbuf) / 2;
+				y = 0;
+				break;
+
+			case PANEL_ORIENTATION_RIGHT:
+				x = width - gdk_pixbuf_get_width (zoom_pixbuf);
+				y = height/2 - gdk_pixbuf_get_height (zoom_pixbuf) / 2;
+				break;
+
+			case PANEL_ORIENTATION_BOTTOM:
+				x = width/2 - gdk_pixbuf_get_width (zoom_pixbuf) / 2;
+				y = height - gdk_pixbuf_get_height (zoom_pixbuf);
+				break;
+
+			case PANEL_ORIENTATION_LEFT:
+				x = 0;
+				y = height/2 - gdk_pixbuf_get_height (zoom_pixbuf) / 2;
+				break;
+		}
+
+		gdk_cairo_set_source_pixbuf (cr, zoom_pixbuf, x, y);
+		cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+		cairo_paint_with_alpha (cr, MAX (zoom_opacity, 0));
+
+		gdk_flush ();
+		usleep (ZOOM_DELAY);
+		gtk_widget_queue_draw_area (widget,  0, 0, width, height);
+	}
+
+	return FALSE;
+}
+
 static void 
 draw_zoom_animation (GdkScreen *gscreen,
 		     int x, int y, int w, int h,
 		     int fx, int fy, int fw, int fh, 
-		     int steps)
+		     int steps,
+		     GdkPixbuf *pixbuf,
+		     PanelOrientation orientation)
 {
-#define FRAMES (MINIATURIZE_ANIMATION_FRAMES_Z)
-	float cx[FRAMES], cy[FRAMES], cw[FRAMES], ch[FRAMES];
-	int cxi[FRAMES], cyi[FRAMES], cwi[FRAMES], chi[FRAMES];
-	float xstep, ystep, wstep, hstep;
-	int i, j;
-	GC frame_gc;
-	XGCValues gcv;
-	GdkColor color = { 65535, 65535, 65535 };
-	Display *dpy;
-	Window root_win;
-	int screen;
-	int depth;
+	if (gdk_screen_is_composited (gscreen))
+	{
+		GtkWidget *win;
+		int wx = 0, wy = 0;
 
-	dpy = gdk_x11_display_get_xdisplay (gdk_screen_get_display (gscreen));
-	root_win = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (gscreen));
-	screen = gdk_screen_get_number (gscreen);
-	depth = gdk_drawable_get_depth (gdk_screen_get_root_window (gscreen));
+		w += 2;
+		h += 2;
 
-	/* frame GC */
-	gdk_colormap_alloc_color (
-		gdk_screen_get_system_colormap (gscreen), &color, FALSE, TRUE);
-	gcv.function = GXxor;
-	/* this will raise the probability of the XORed color being different
-	 * of the original color in PseudoColor when not all color cells are
-	 * initialized */
-	if (DefaultVisual(dpy, screen)->class==PseudoColor)
-		gcv.plane_mask = (1<<(depth-1))|1;
+		zoom_size = zoom_size_start = w;
+		zoom_size_end = w * ZOOM_FACTOR;
+		zoom_orientation = orientation;
+		zoom_pixbuf = pixbuf;
+		zoom_opacity = 1.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 (gdk_screen_get_default ()));
+
+		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), NULL);
+
+		/* See the GTK+ manual for gtk_widget_set_app_paintable() */
+		gtk_widget_realize (win);
+		gdk_window_set_back_pixmap (win->window, NULL, FALSE);
+		gtk_widget_show (win);
+	}
 	else
-		gcv.plane_mask = AllPlanes;
-	gcv.foreground = color.pixel;
-	if (gcv.foreground == 0)
-		gcv.foreground = 1;
-	gcv.line_width = 1;
-	gcv.subwindow_mode = IncludeInferiors;
-	gcv.graphics_exposures = False;
+	{
+#define FRAMES (MINIATURIZE_ANIMATION_FRAMES_Z)
+		float cx[FRAMES], cy[FRAMES], cw[FRAMES], ch[FRAMES];
+		int cxi[FRAMES], cyi[FRAMES], cwi[FRAMES], chi[FRAMES];
+		float xstep, ystep, wstep, hstep;
+		int i, j;
+		GC frame_gc;
+		XGCValues gcv;
+		GdkColor color = { 65535, 65535, 65535 };
+		Display *dpy;
+		Window root_win;
+		int screen;
+		int depth;
 
-	frame_gc = XCreateGC(dpy, root_win, GCForeground|GCGraphicsExposures
-			     |GCFunction|GCSubwindowMode|GCLineWidth
-			     |GCPlaneMask, &gcv);
+		dpy = gdk_x11_display_get_xdisplay (gdk_screen_get_display (gscreen));
+		root_win = gdk_x11_drawable_get_xid (gdk_screen_get_root_window (gscreen));
+		screen = gdk_screen_get_number (gscreen);
+		depth = gdk_drawable_get_depth (gdk_screen_get_root_window (gscreen));
 
-	xstep = (float)(fx-x)/steps;
-	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;
-		cw[j] = (float)w;
-		ch[j] = (float)h;
-		cxi[j] = (int)cx[j];
-		cyi[j] = (int)cy[j];
-		cwi[j] = (int)cw[j];
-		chi[j] = (int)ch[j];
-	}
-	XGrabServer(dpy);
-	for (i=0; i<steps; i++) {
+		/* frame GC */
+		gdk_colormap_alloc_color (
+			gdk_screen_get_system_colormap (gscreen), &color, FALSE, TRUE);
+		gcv.function = GXxor;
+		/* this will raise the probability of the XORed color being different
+		 * of the original color in PseudoColor when not all color cells are
+		 * initialized */
+		if (DefaultVisual(dpy, screen)->class==PseudoColor)
+			gcv.plane_mask = (1<<(depth-1))|1;
+		else
+			gcv.plane_mask = AllPlanes;
+		gcv.foreground = color.pixel;
+		if (gcv.foreground == 0)
+			gcv.foreground = 1;
+		gcv.line_width = 1;
+		gcv.subwindow_mode = IncludeInferiors;
+		gcv.graphics_exposures = False;
+
+		frame_gc = XCreateGC(dpy, root_win, GCForeground|GCGraphicsExposures
+					 |GCFunction|GCSubwindowMode|GCLineWidth
+					 |GCPlaneMask, &gcv);
+
+		xstep = (float)(fx-x)/steps;
+		ystep = (float)(fy-y)/steps;
+		wstep = (float)(fw-w)/steps;
+		hstep = (float)(fh-h)/steps;
+		
 		for (j=0; j<FRAMES; j++) {
-			XDrawRectangle(dpy, root_win, frame_gc, cxi[j], cyi[j], cwi[j], chi[j]);
+			cx[j] = (float)x;
+			cy[j] = (float)y;
+			cw[j] = (float)w;
+			ch[j] = (float)h;
+			cxi[j] = (int)cx[j];
+			cyi[j] = (int)cy[j];
+			cwi[j] = (int)cw[j];
+			chi[j] = (int)ch[j];
 		}
-		XFlush(dpy);
+		XGrabServer(dpy);
+		for (i=0; i<steps; i++) {
+			for (j=0; j<FRAMES; j++) {
+				XDrawRectangle(dpy, root_win, frame_gc, cxi[j], cyi[j], cwi[j], chi[j]);
+			}
+			XFlush(dpy);
 #if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
-		usleep(MINIATURIZE_ANIMATION_DELAY_Z);
+			usleep(MINIATURIZE_ANIMATION_DELAY_Z);
 #else
-		usleep(10);
+			usleep(10);
 #endif
-		for (j=0; j<FRAMES; j++) {
-			XDrawRectangle(dpy, root_win, frame_gc, 
-				       cxi[j], cyi[j], cwi[j], chi[j]);
-			if (j<FRAMES-1) {
-				cx[j]=cx[j+1];
-				cy[j]=cy[j+1];
-				cw[j]=cw[j+1];
-				ch[j]=ch[j+1];
+			for (j=0; j<FRAMES; j++) {
+				XDrawRectangle(dpy, root_win, frame_gc, 
+						   cxi[j], cyi[j], cwi[j], chi[j]);
+				if (j<FRAMES-1) {
+					cx[j]=cx[j+1];
+					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];
+					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;
-				cw[j]+=wstep;
-				ch[j]+=hstep;
+				} else {
+					cx[j]+=xstep;
+					cy[j]+=ystep;
+					cw[j]+=wstep;
+					ch[j]+=hstep;
 
-				cxi[j] = (int)cx[j];
-				cyi[j] = (int)cy[j];
-				cwi[j] = (int)cw[j];
-				chi[j] = (int)ch[j];
+					cxi[j] = (int)cx[j];
+					cyi[j] = (int)cy[j];
+					cwi[j] = (int)cw[j];
+					chi[j] = (int)ch[j];
+				}
 			}
 		}
-	}
 
-	for (j=0; j<FRAMES; j++) {
-		XDrawRectangle(dpy, root_win, frame_gc, 
-				       cxi[j], cyi[j], cwi[j], chi[j]);
-	}
-	XFlush(dpy);
+		for (j=0; j<FRAMES; j++) {
+			XDrawRectangle(dpy, root_win, frame_gc, 
+						   cxi[j], cyi[j], cwi[j], chi[j]);
+		}
+		XFlush(dpy);
 #if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
-	usleep(MINIATURIZE_ANIMATION_DELAY_Z);
+		usleep(MINIATURIZE_ANIMATION_DELAY_Z);
 #else
-	usleep(10);
+		usleep(10);
 #endif
-	for (j=0; j<FRAMES; j++) {
-		XDrawRectangle(dpy, root_win, frame_gc, 
-				       cxi[j], cyi[j], cwi[j], chi[j]);
+		for (j=0; j<FRAMES; j++) {
+			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
 	}
-    
-	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;
@@ -435,7 +581,8 @@
 	draw_zoom_animation (gscreen,
 			     rect.x, rect.y, rect.width, rect.height,
 			     dest.x, dest.y, dest.width, dest.height,
-			     MINIATURIZE_ANIMATION_STEPS_Z);
+			     MINIATURIZE_ANIMATION_STEPS_Z,
+			     pixbuf, orientation);
 }
 
 int
Index: gnome-panel/xstuff.h
===================================================================
--- gnome-panel/xstuff.h	(revision 10673)
+++ gnome-panel/xstuff.h	(working copy)
@@ -21,8 +21,10 @@
 					 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);
 
