Index: src/nautilus-window-manage-views.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/nautilus-window-manage-views.c,v
retrieving revision 1.351
diff -u -r1.351 nautilus-window-manage-views.c
--- src/nautilus-window-manage-views.c	19 Apr 2005 12:01:16 -0000	1.351
+++ src/nautilus-window-manage-views.c	2 Jun 2005 20:18:02 -0000
@@ -34,6 +34,7 @@
 #include "nautilus-main.h"
 #include "nautilus-window-private.h"
 #include "nautilus-zoom-control.h"
+#include "file-manager/xstuff.h"
 #include <eel/eel-accessibility.h>
 #include <eel/eel-debug.h>
 #include <eel/eel-gdk-extensions.h>
@@ -842,6 +844,8 @@
 	NautilusWindow *window;
 	char *location;
 	char *home_uri;
+	char *geometry_string;
+	GdkRectangle rect;
 
 	window = callback_data;
 	
@@ -945,6 +949,12 @@
 		}
 	}
 	
+	geometry_string = nautilus_file_get_metadata 
+		(file, NAUTILUS_METADATA_KEY_WINDOW_GEOMETRY, NULL);
+	eel_gdk_parse_geometry (geometry_string, &rect.x, &rect.y, 
+				&rect.width,&rect.height);
+	xstuff_queued_zoom_animate (GTK_WIDGET (window), &rect);
+
 	nautilus_file_unref (file);
 }
 
Index: src/file-manager/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/Makefile.am,v
retrieving revision 1.80
diff -u -r1.80 Makefile.am
--- src/file-manager/Makefile.am	25 Nov 2004 14:59:54 -0000	1.80
+++ src/file-manager/Makefile.am	2 Jun 2005 20:18:02 -0000
@@ -38,6 +38,8 @@
 	fm-tree-model.h			\
 	fm-tree-view.c			\
 	fm-tree-view.h			\
+	xstuff.c			\
+	xstuff.h			\
 	$(NULL)
 
 
Index: src/file-manager/fm-directory-view.c
===================================================================
RCS file: /cvs/gnome/nautilus/src/file-manager/fm-directory-view.c,v
retrieving revision 1.681
diff -u -r1.681 fm-directory-view.c
--- src/file-manager/fm-directory-view.c	2 Jun 2005 14:35:14 -0000	1.681
+++ src/file-manager/fm-directory-view.c	2 Jun 2005 20:18:02 -0000
@@ -32,6 +32,7 @@
 #include "fm-directory-view.h"
 #include "fm-list-view.h"
 #include "fm-desktop-icon-view.h"
+#include "xstuff.h"
 
 #include "fm-actions.h"
 #include "fm-error-reporting.h"
@@ -84,6 +85,7 @@
 #include <libnautilus-private/nautilus-file-utilities.h>
 #include <libnautilus-private/nautilus-file-private.h> /* for nautilus_file_get_existing */
 #include <libnautilus-private/nautilus-global-preferences.h>
+#include <libnautilus-private/nautilus-icon-private.h>
 #include <libnautilus-private/nautilus-icon-factory.h>
 #include <libnautilus-private/nautilus-link.h>
 #include <libnautilus-private/nautilus-metadata.h>
@@ -7014,6 +7016,51 @@
 			     parameters);
 }
 
+static GdkRectangle *
+get_icon_rectangle (FMDirectoryView *view, NautilusFile *file)
+{
+	NautilusIconContainer *container;
+	NautilusIconCanvasItem *item;
+	ArtDRect rect;
+	GdkRectangle *rectangle;
+	GList *p;
+	NautilusIcon *icon;
+	char *icon_uri, *uri;
+	int container_x, container_y;
+
+	g_return_val_if_fail (FM_IS_DIRECTORY_VIEW (view), NULL);
+	g_return_val_if_fail (NAUTILUS_IS_FILE (file), NULL);
+
+	icon_uri = nautilus_file_get_uri (file);
+
+	g_return_val_if_fail (NAUTILUS_IS_ICON_CONTAINER (GTK_BIN(view)->child), NULL);
+	container = NAUTILUS_ICON_CONTAINER (GTK_BIN (view)->child);
+	
+	for (p = container->details->icons; p!=NULL; p = p->next) {
+		icon = p->data;
+		if (!icon->is_selected) {
+			continue;
+		}
+		uri = nautilus_icon_container_get_icon_uri (container, icon);
+		if (g_ascii_strcasecmp (uri, icon_uri) == 0) {
+			item = icon->item;
+			rect = nautilus_icon_canvas_item_get_icon_rectangle (item);
+			gdk_window_get_origin (GTK_WIDGET(container)->window, 
+					       &container_x, &container_y);
+			rectangle = g_new0 (GdkRectangle, 1);
+			rectangle->x = rect.x0 + container_x;
+			rectangle->y = rect.y0 + container_y;
+			rectangle->width = rect.x1 - rect.x0;
+			rectangle->height = rect.y1 - rect.y0;
+			return rectangle;
+		}
+		g_free (uri);
+	}
+
+	return NULL;
+}
+
+
 static void
 activate_callback (NautilusFile *file, gpointer callback_data)
 {
@@ -7024,6 +7071,7 @@
 	char *old_working_dir;
 	ActivationAction action;
 	GdkScreen *screen;
+	GdkRectangle *rectangle;
 
 	parameters = callback_data;
 
@@ -7038,6 +7086,12 @@
 		return;
 	}
 
+	rectangle = get_icon_rectangle (view, file);
+	if (rectangle) {
+		xstuff_queue_zoom (rectangle);
+		g_free (rectangle);
+	}
+
 	orig_uri = uri = nautilus_file_get_activation_uri (file);
 
 	action = get_activation_action (file);
@@ -7053,6 +7107,7 @@
 	
 	switch (action) {
 	case ACTIVATION_ACTION_LAUNCH_DESKTOP_FILE :
+		xstuff_queued_zoom_animate (GTK_WIDGET(view), NULL);
 		file_uri = nautilus_file_get_uri (file);
 		nautilus_launch_desktop_file (
 				screen, file_uri, NULL,
@@ -7060,11 +7115,13 @@
 		g_free (file_uri);		 
 		break;
 	case ACTIVATION_ACTION_LAUNCH_APPLICATION_FROM_COMMAND :
+		xstuff_queued_zoom_animate (GTK_WIDGET(view), NULL);
 		uri += strlen (NAUTILUS_COMMAND_SPECIFIER);
 		nautilus_launch_application_from_command (screen, NULL, uri, NULL, FALSE);
 		break;
 	case ACTIVATION_ACTION_LAUNCH :
 	case ACTIVATION_ACTION_LAUNCH_IN_TERMINAL :
+		xstuff_queued_zoom_animate (GTK_WIDGET(view), NULL);
 		old_working_dir = change_to_view_directory (view);
 
 		executable_path = gnome_vfs_get_local_path_from_uri (uri);
@@ -7085,6 +7142,7 @@
 		open_location (view, uri, parameters->mode, parameters->flags);
 		break;
 	case ACTIVATION_ACTION_OPEN_IN_APPLICATION :
+		xstuff_queued_zoom_animate (GTK_WIDGET(view), NULL);
 		nautilus_launch_show_file
 			(file, fm_directory_view_get_containing_window (view));
 		
--- /dev/null	Fri Mar 23 23:37:44 2001
+++ src/file-manager/xstuff.c	Thu Jun  2 16:17:18 2005
@@ -0,0 +1,543 @@
+/*
+ * GNOME panel x stuff
+ *
+ * Copyright (C) 2000, 2001 Eazel, Inc.
+ *               2002 Sun Microsystems Inc.
+ *
+ * Authors: George Lebl <jirka@5z.com>
+ *          Mark McLoughlin <mark@skynet.ie>
+ *
+ *  Contains code from the Window Maker window manager
+ *
+ *  Copyright (c) 1997-2002 Alfredo K. Kojima
+
+ */
+#include <config.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <gdk/gdk.h>
+#include <gdk/gdkx.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xatom.h>
+
+#include "xstuff.h"
+
+GList *pending_zooms = NULL;
+
+static Atom
+panel_atom_get (const char *atom_name)
+{
+	static GHashTable *atom_hash;
+	Display           *xdisplay;
+	Atom               retval;
+
+	g_return_val_if_fail (atom_name != NULL, None);
+
+	xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+
+	if (!atom_hash)
+		atom_hash = g_hash_table_new_full (
+				g_str_hash, g_str_equal, g_free, NULL);
+
+	retval = GPOINTER_TO_UINT (g_hash_table_lookup (atom_hash, atom_name));
+	if (!retval) {
+		retval = XInternAtom (xdisplay, atom_name, FALSE);
+
+		if (retval != None)
+			g_hash_table_insert (atom_hash, g_strdup (atom_name),
+					     GUINT_TO_POINTER (retval));
+	}
+
+	return retval;
+}
+
+/* Stolen from deskguide */
+static gpointer
+get_typed_property_data (Display *xdisplay,
+			 Window   xwindow,
+			 Atom     property,
+			 Atom     requested_type,
+			 gint    *size_p,
+			 guint    expected_format)
+{
+  static const guint prop_buffer_lengh = 1024 * 1024;
+  unsigned char *prop_data = NULL;
+  Atom type_returned = 0;
+  unsigned long nitems_return = 0, bytes_after_return = 0;
+  int format_returned = 0;
+  gpointer data = NULL;
+  gboolean abort = FALSE;
+
+  g_return_val_if_fail (size_p != NULL, NULL);
+  *size_p = 0;
+
+  gdk_error_trap_push ();
+
+  abort = XGetWindowProperty (xdisplay,
+			      xwindow,
+			      property,
+			      0, prop_buffer_lengh,
+			      False,
+			      requested_type,
+			      &type_returned, &format_returned,
+			      &nitems_return,
+			      &bytes_after_return,
+			      &prop_data) != Success;
+  if (gdk_error_trap_pop () ||
+      type_returned == None)
+    abort++;
+  if (!abort &&
+      requested_type != AnyPropertyType &&
+      requested_type != type_returned)
+    {
+      g_warning (G_GNUC_PRETTY_FUNCTION "(): Property has wrong type, probably on crack");
+      abort++;
+    }
+  if (!abort && bytes_after_return)
+    {
+      g_warning (G_GNUC_PRETTY_FUNCTION "(): Eeek, property has more than %u bytes, stored on harddisk?",
+		 prop_buffer_lengh);
+      abort++;
+    }
+  if (!abort && expected_format && expected_format != format_returned)
+    {
+      g_warning (G_GNUC_PRETTY_FUNCTION "(): Expected format (%u) unmatched (%d), programmer was drunk?",
+		 expected_format, format_returned);
+      abort++;
+    }
+  if (!abort && prop_data && nitems_return && format_returned)
+    {
+      switch (format_returned)
+	{
+	case 32:
+	  *size_p = nitems_return * 4;
+	  if (sizeof (gulong) == 8)
+	    {
+	      guint32 i, *mem = g_malloc0 (*size_p + 1);
+	      gulong *prop_longs = (gulong*) prop_data;
+
+	      for (i = 0; i < *size_p / 4; i++)
+		mem[i] = prop_longs[i];
+	      data = mem;
+	    }
+	  break;
+	case 16:
+	  *size_p = nitems_return * 2;
+	  break;
+	case 8:
+	  *size_p = nitems_return;
+	  break;
+	default:
+	  g_warning ("Unknown property data format with %d bits (extraterrestrial?)",
+		     format_returned);
+	  break;
+	}
+      if (!data && *size_p)
+	{
+	  guint8 *mem = g_malloc (*size_p + 1);
+
+	  memcpy (mem, prop_data, *size_p);
+	  mem[*size_p] = 0;
+	  data = mem;
+	}
+    }
+
+  if (prop_data)
+    XFree (prop_data);
+  
+  return data;
+}
+
+gboolean
+xstuff_is_compliant_wm (void)
+{
+	Display  *xdisplay;
+	Window    root_window;
+	gpointer  data;
+	int       size;
+
+	xdisplay = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
+	root_window = GDK_WINDOW_XWINDOW (
+				gdk_get_default_root_window ());
+
+        /* FIXME this is totally broken; should be using
+         * gdk_net_wm_supports() on particular hints when we rely
+         * on those particular hints
+         */
+	data = get_typed_property_data (
+			xdisplay, root_window,
+			panel_atom_get ("_NET_SUPPORTED"),
+			XA_ATOM, &size, 32);
+
+	if (!data)
+		return FALSE;
+
+	/* Actually checks for some of these */
+	g_free (data);
+	return TRUE;
+}
+
+gboolean
+xstuff_net_wm_supports (const char *hint)
+{
+	return gdk_net_wm_supports (gdk_atom_intern (hint, FALSE));
+}
+
+/* This is such a broken stupid function. */   
+void
+xstuff_set_pos_size (GdkWindow *window, int x, int y, int w, int h)
+{
+	XSizeHints size_hints;
+	int old_x, old_y, old_w, old_h;
+
+	old_x = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "xstuff-cached-x"));
+	old_y = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "xstuff-cached-y"));
+	old_w = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "xstuff-cached-w"));
+	old_h = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window), "xstuff-cached-h"));
+
+	if (x == old_x && y == old_y && w == old_w && h == old_h)
+		return;
+
+	/* Do not add USPosition / USSize here, fix the damn WM */
+	size_hints.flags = PPosition | PSize | PMaxSize | PMinSize;
+	size_hints.x = 0; /* window managers aren't supposed to and  */
+	size_hints.y = 0; /* don't use these fields */
+	size_hints.width = w;
+	size_hints.height = h;
+	size_hints.min_width = w;
+       	size_hints.min_height = h;
+	size_hints.max_width = w;
+	size_hints.max_height = h;
+  
+	gdk_error_trap_push ();
+
+	XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
+			   GDK_WINDOW_XWINDOW (window),
+			   &size_hints);
+
+	gdk_window_move_resize (window, x, y, w, h);
+
+	gdk_flush ();
+	gdk_error_trap_pop ();
+
+	g_object_set_data (G_OBJECT (window), "xstuff-cached-x", GINT_TO_POINTER (x));
+	g_object_set_data (G_OBJECT (window), "xstuff-cached-y", GINT_TO_POINTER (y));
+	g_object_set_data (G_OBJECT (window), "xstuff-cached-w", GINT_TO_POINTER (w));
+	g_object_set_data (G_OBJECT (window), "xstuff-cached-h", GINT_TO_POINTER (h));
+}
+
+void
+xstuff_set_wmspec_dock_hints (GdkWindow *window,
+			      gboolean autohide)
+{
+        Atom atoms [2] = { None, None };
+        
+	if (!autohide)
+		atoms [0] = panel_atom_get ("_NET_WM_WINDOW_TYPE_DOCK");
+	else {
+		atoms [0] = panel_atom_get ("_GNOME_WINDOW_TYPE_AUTOHIDE_PANEL");
+		atoms [1] = panel_atom_get ("_NET_WM_WINDOW_TYPE_DOCK");
+	}
+
+        XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+                         GDK_WINDOW_XWINDOW (window),
+			 panel_atom_get ("_NET_WM_WINDOW_TYPE"),
+                         XA_ATOM, 32, PropModeReplace,
+                         (unsigned char *) atoms, 
+			 autohide ? 2 : 1);
+}
+
+void
+xstuff_set_wmspec_strut (GdkWindow *window,
+			 int        left,
+			 int        right,
+			 int        top,
+			 int        bottom)
+{
+	long vals [4];
+        
+	vals [0] = left;
+	vals [1] = right;
+	vals [2] = top;
+	vals [3] = bottom;
+
+        XChangeProperty (GDK_WINDOW_XDISPLAY (window),
+                         GDK_WINDOW_XWINDOW (window),
+			 panel_atom_get ("_NET_WM_STRUT"),
+                         XA_CARDINAL, 32, PropModeReplace,
+                         (unsigned char *) vals, 4);
+}
+
+void
+xstuff_delete_property (GdkWindow *window, const char *name)
+{
+	Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
+	Window   xwindow  = GDK_WINDOW_XWINDOW (window);
+
+        XDeleteProperty (xdisplay, xwindow,
+			 panel_atom_get (name));
+}
+
+/* Zoom animation */
+#define MINIATURIZE_ANIMATION_FRAMES_Z   1
+#define MINIATURIZE_ANIMATION_STEPS_Z    6
+/* the delay per draw */
+#define MINIATURIZE_ANIMATION_DELAY_Z    10
+
+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)
+{
+#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;
+
+	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));
+
+	/* 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++) {
+		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++) {
+		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);
+#else
+		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];
+				
+				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;
+
+				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);
+#if (MINIATURIZE_ANIMATION_DELAY_Z > 0)
+	usleep(MINIATURIZE_ANIMATION_DELAY_Z);
+#else
+	usleep(10);
+#endif
+	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
+
+void
+xstuff_zoom_animate (GtkWidget *widget, GdkRectangle *opt_rect,
+										 GdkRectangle *opt_dest)
+{
+	GdkScreen *gscreen;
+	GdkRectangle rect, dest;
+	int monitor;
+
+	if (opt_rect)
+		rect = *opt_rect;
+	else {
+		gdk_window_get_origin (widget->window, &rect.x, &rect.y);
+		if (GTK_WIDGET_NO_WINDOW (widget)) {
+			rect.x += widget->allocation.x;
+			rect.y += widget->allocation.y;
+		}
+		rect.height = widget->allocation.height;
+		rect.width = widget->allocation.width;
+	}
+
+	gscreen = gtk_widget_get_screen (widget);
+	if (opt_dest==NULL) {
+		monitor = gdk_screen_get_monitor_at_window (gscreen, widget->window);
+		gdk_screen_get_monitor_geometry (gscreen, monitor, &dest);
+	}	else {
+		dest.x = opt_dest->x;
+		dest.y = opt_dest->y;
+		dest.width = opt_dest->width;
+		dest.height = opt_dest->height;
+	}
+
+	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
+xstuff_get_current_workspace (GdkScreen *screen)
+{
+	Window  root_window;
+	Atom    type = None;
+	gulong  nitems;
+	gulong  bytes_after;
+	gulong *num;
+	int     format;
+	int     result;
+	int     retval;
+
+	root_window = gdk_x11_drawable_get_xid (
+				gdk_screen_get_root_window (screen));
+
+	gdk_error_trap_push ();
+	result = XGetWindowProperty (gdk_display,
+				     root_window,
+				     panel_atom_get ("_NET_CURRENT_DESKTOP"),
+				     0, G_MAXLONG,
+				     False, XA_CARDINAL, &type, &format, &nitems,
+				     &bytes_after, (gpointer) &num);
+	if (gdk_error_trap_pop () || result != Success)
+		return -1;
+ 
+	if (type != XA_CARDINAL) {
+		XFree (num);
+		return -1;
+	}
+
+	retval = *num;
+ 
+	XFree (num);
+
+	return retval;
+}
+
+void
+xstuff_grab_key_on_all_screens (int      keycode,
+				guint    modifiers,
+				gboolean grab)
+{
+	GdkDisplay *display;
+	int         n_screens;
+	int         i;
+
+	display   = gdk_display_get_default ();
+	n_screens = gdk_display_get_n_screens (display);
+
+	for (i = 0; i < n_screens; i++) {
+		GdkWindow *root;
+
+		root = gdk_screen_get_root_window (
+				gdk_display_get_screen (display, i));
+
+		if (grab)
+			XGrabKey (gdk_x11_display_get_xdisplay (display),
+				  keycode, modifiers,
+				  gdk_x11_drawable_get_xid (root),
+				  True, GrabModeAsync, GrabModeAsync);
+		else
+			XUngrabKey (gdk_x11_display_get_xdisplay (display),
+				    keycode, modifiers,
+				    gdk_x11_drawable_get_xid (root));
+	}
+}
+
+void 
+xstuff_queue_zoom (GdkRectangle *start)
+{
+	GdkRectangle *new;
+
+	new = g_new0 (GdkRectangle, 1);
+	new->x = start->x;
+	new->y = start->y;
+	new->width = start->width;
+	new->height = start->height;
+
+	pending_zooms = g_list_append (pending_zooms, new);
+}
+
+void
+xstuff_queued_zoom_animate (GtkWidget *widget, 
+														GdkRectangle *dest)
+{
+	GdkRectangle *orig;
+
+	if (!pending_zooms)
+		return;
+
+	orig = g_list_last (pending_zooms)->data;
+	pending_zooms = g_list_remove (pending_zooms, orig);
+
+	xstuff_zoom_animate (widget, orig, dest);
+	g_free (orig);
+}
--- /dev/null	Fri Mar 23 23:37:44 2001
+++ src/file-manager/xstuff.h	Thu Jun  2 15:44:26 2005
@@ -0,0 +1,38 @@
+#ifndef __XSTUFF_H__
+#define __XSTUFF_H__
+
+#include <gdk/gdk.h>
+#include <gtk/gtkwidget.h>
+
+void xstuff_delete_property		(GdkWindow *window,
+					 const char *name);
+gboolean xstuff_is_compliant_wm		(void);
+gboolean xstuff_net_wm_supports         (const char *hint);
+
+void xstuff_unsetup_desktop_area	(void);
+void xstuff_set_pos_size		(GdkWindow *window,
+					 int x, int y,
+					 int w, int h);
+void xstuff_set_wmspec_dock_hints       (GdkWindow *window,
+					 gboolean autohide);
+void xstuff_set_wmspec_strut		(GdkWindow *window,
+					 int left,
+					 int right,
+					 int top,
+					 int bottom);
+
+void xstuff_zoom_animate                (GtkWidget    *widget,
+					 GdkRectangle *opt_src_rect, GdkRectangle *opt_dest);
+
+int  xstuff_get_current_workspace       (GdkScreen *screen);
+
+void xstuff_grab_key_on_all_screens     (int      keycode,
+					 guint    modifiers,
+					 gboolean grab);
+void xstuff_queued_zoom_animate (GtkWidget *widget, 
+																 GdkRectangle *dest);
+void 
+xstuff_queue_zoom (GdkRectangle *start);
+
+
+#endif /* __XSTUFF_H__ */
