Index: src/include/tabpopup.h
===================================================================
--- src/include/tabpopup.h	(revision 3503)
+++ src/include/tabpopup.h	(working copy)
@@ -41,6 +41,7 @@
   MetaTabEntryKey  key;  
   const char      *title;
   GdkPixbuf       *icon;
+  GdkPixbuf       *thumbnail;
   MetaRectangle    rect;
   MetaRectangle    inner_rect;
   guint            blank : 1;
Index: src/core/screen.c
===================================================================
--- src/core/screen.c	(revision 3503)
+++ src/core/screen.c	(working copy)
@@ -1250,7 +1250,7 @@
 
 #define MAX_PREVIEW_SIZE 150.0
 
-static GdkPixbuf *
+GdkPixbuf *
 get_window_pixbuf (MetaWindow *window,
                    int        *width,
                    int        *height)
@@ -1265,7 +1265,7 @@
     return NULL;
 
   pixbuf = meta_ui_get_pixbuf_from_pixmap (pmap);
-  if (pixbuf == NULL) 
+  if (pixbuf == NULL)
     return NULL;
 
   *width = gdk_pixbuf_get_width (pixbuf);
@@ -1287,6 +1287,7 @@
 
   scaled = gdk_pixbuf_scale_simple (pixbuf, *width, *height,
                                     GDK_INTERP_BILINEAR);
+
   g_object_unref (pixbuf);
   return scaled;
 }
@@ -1316,6 +1317,7 @@
   entries[len].key = NULL;
   entries[len].title = NULL;
   entries[len].icon = NULL;
+  entries[len].thumbnail = NULL;
   
   i = 0;
   tmp = tab_list;
@@ -1323,7 +1325,6 @@
     {
       MetaWindow *window;
       MetaRectangle r;
-      GdkPixbuf *win_pixbuf;
       int width, height;
 
       window = tmp->data;
@@ -1331,14 +1332,21 @@
       entries[i].key = (MetaTabEntryKey) window->xwindow;
       entries[i].title = window->title;
 
-      win_pixbuf = get_window_pixbuf (window, &width, &height);
-      if (win_pixbuf == NULL)
-        entries[i].icon = g_object_ref (window->icon);
+      if (window->thumbnail == NULL)
+      {
+	meta_window_update_thumbnail_now (window);
+      }
+
+      if (window->thumbnail == NULL)
+          entries[i].icon = g_object_ref (window->icon);
       else
         {
           int icon_width, icon_height, t_width, t_height;
 #define ICON_OFFSET 6
 
+          width = gdk_pixbuf_get_width (window->thumbnail);
+          height = gdk_pixbuf_get_height (window->thumbnail);
+
           icon_width = gdk_pixbuf_get_width (window->icon);
           icon_height = gdk_pixbuf_get_height (window->icon);
 
@@ -1348,9 +1356,8 @@
           entries[i].icon = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8,
                                             t_width, t_height);
           gdk_pixbuf_fill (entries[i].icon, 0x00000000);
-          gdk_pixbuf_copy_area (win_pixbuf, 0, 0, width, height,
+          gdk_pixbuf_copy_area (window->thumbnail, 0, 0, width, height,
                                 entries[i].icon, 0, 0);
-          g_object_unref (win_pixbuf);
           gdk_pixbuf_composite (window->icon, entries[i].icon, 
                                 t_width - icon_width, t_height - icon_height,
                                 icon_width, icon_height,
Index: src/core/screen.h
===================================================================
--- src/core/screen.h	(revision 3503)
+++ src/core/screen.h	(working copy)
@@ -148,6 +148,10 @@
                                                MetaCursor                  cursor);
 void          meta_screen_update_cursor       (MetaScreen                 *screen);
 
+GdkPixbuf*    get_window_pixbuf 	      (MetaWindow *window,
+						int        *width,
+                  				 int        *height);
+
 void          meta_screen_ensure_tab_popup    (MetaScreen                 *screen,
                                                MetaTabList                 list_type,
                                                MetaTabShowType             show_type);
Index: src/core/window.c
===================================================================
--- src/core/window.c	(revision 3503)
+++ src/core/window.c	(working copy)
@@ -35,6 +35,7 @@
 #include "keybindings.h"
 #include "ui.h"
 #include "place.h"
+#include "screen.h"
 #include "session.h"
 #include "effects.h"
 #include "prefs.h"
@@ -126,6 +127,7 @@
 static gboolean idle_calc_showing (gpointer data);
 static gboolean idle_move_resize (gpointer data);
 static gboolean idle_update_icon (gpointer data);
+static gboolean idle_update_thumbnail (gpointer data);
 
 #ifdef WITH_VERBOSE_MODE
 static const char*
@@ -438,6 +440,7 @@
   window->icon_name = NULL;
   window->icon = NULL;
   window->mini_icon = NULL;
+  window->thumbnail = NULL;
   meta_icon_cache_init (&window->icon_cache);
   window->wm_hints_pixmap = None;
   window->wm_hints_mask = None;
@@ -542,6 +545,7 @@
   window->using_net_wm_visible_icon_name = FALSE;
 
   window->need_reread_icon = TRUE;
+  window->need_reread_thumbnail = TRUE;
   
   window->layer = META_LAYER_LAST; /* invalid value */
   window->stack_position = -1;
@@ -589,6 +593,7 @@
   update_role (window);
   update_net_wm_type (window);
   meta_window_update_icon_now (window);
+  meta_window_update_thumbnail_now (window);
 
   if (window->initially_iconic)
     {
@@ -1164,6 +1169,9 @@
   if (window->mini_icon)
     g_object_unref (G_OBJECT (window->mini_icon));
 
+  if (window->thumbnail)
+    g_object_unref (G_OBJECT (window->thumbnail));
+
   meta_icon_cache_free (&window->icon_cache);
   
   g_free (window->sm_client_id);
@@ -1647,7 +1655,7 @@
 }
 
 static const gchar* meta_window_queue_names[NUMBER_OF_QUEUES] =
-  {"calc_showing", "move_resize", "update_icon"};
+  {"calc_showing", "move_resize", "update_icon", "update_thumbnail"};
 
 static void
 meta_window_unqueue (MetaWindow *window, guint queuebits)
@@ -1721,6 +1729,7 @@
               idle_calc_showing,
               idle_move_resize,
               idle_update_icon,
+              idle_update_thumbnail,
             };
 
           /* If we're about to drop the window, there's no point in putting
@@ -5828,7 +5837,66 @@
   
   return FALSE;
 }
+  
 
+void
+meta_window_update_thumbnail_now (MetaWindow *window)
+{
+  GdkPixbuf *thumbnail;
+  int width, height;
+
+  thumbnail = get_window_pixbuf(window, &width, &height);
+  
+  if (thumbnail)
+  {
+      if (window->thumbnail)
+        g_object_unref (G_OBJECT (window->thumbnail));
+      
+      window->thumbnail = thumbnail;
+
+  }
+}
+
+static gboolean
+idle_update_thumbnail (gpointer data)
+{
+  GSList *tmp;
+  GSList *copy;
+  guint queue_index = GPOINTER_TO_INT (data);
+
+  meta_topic (META_DEBUG_GEOMETRY, "Clearing the update_thumbnail queue\n");
+
+  /* Work with a copy, for reentrancy. The allowed reentrancy isn't
+   * complete; destroying a window while we're in here would result in
+   * badness. But it's OK to queue/unqueue update_icons.
+   */
+  copy = g_slist_copy (queue_pending[queue_index]);
+  g_slist_free (queue_pending[queue_index]);
+  queue_pending[queue_index] = NULL;
+  queue_idle[queue_index] = 0;
+
+  destroying_windows_disallowed += 1;
+  
+  tmp = copy;
+  while (tmp != NULL)
+    {
+      MetaWindow *window;
+
+      window = tmp->data;
+
+      meta_window_update_thumbnail_now (window); 
+      window->is_in_queues &= ~META_QUEUE_UPDATE_THUMBNAIL;
+      
+      tmp = tmp->next;
+    }
+
+  g_slist_free (copy);
+
+  destroying_windows_disallowed -= 1;
+  
+  return FALSE;
+}
+
 GList*
 meta_window_get_workspaces (MetaWindow *window)
 {
Index: src/core/window.h
===================================================================
--- src/core/window.h	(revision 3503)
+++ src/core/window.h	(working copy)
@@ -71,9 +71,10 @@
   META_QUEUE_CALC_SHOWING = 1 << 0,
   META_QUEUE_MOVE_RESIZE  = 1 << 1,
   META_QUEUE_UPDATE_ICON  = 1 << 2,
+  META_QUEUE_UPDATE_THUMBNAIL  = 1 << 4,
 } MetaQueueType;
 
-#define NUMBER_OF_QUEUES 3
+#define NUMBER_OF_QUEUES 4
 
 struct _MetaWindow
 {
@@ -92,6 +93,7 @@
   char *icon_name;
   GdkPixbuf *icon;
   GdkPixbuf *mini_icon;
+  GdkPixbuf *thumbnail;
   MetaIconCache icon_cache;
   Pixmap wm_hints_pixmap;
   Pixmap wm_hints_mask;
@@ -277,6 +279,9 @@
 
   /* icon props have changed */
   guint need_reread_icon : 1;
+
+  /* thumbnail props have changed */
+  guint need_reread_thumbnail : 1;
   
   /* if TRUE, window was maximized at start of current grab op */
   guint shaken_loose : 1;
@@ -608,4 +613,6 @@
 
 void meta_window_update_icon_now (MetaWindow *window);
 
+void meta_window_update_thumbnail (MetaWindow *window);
+
 #endif
Index: src/ui/ui.c
===================================================================
--- src/ui/ui.c	(revision 3503)
+++ src/ui/ui.c	(working copy)
@@ -983,7 +983,6 @@
   
   pixbuf = gdk_pixbuf_get_from_drawable (NULL, gpmap, cmap, 0, 0, 0, 0,
                                          width, height);
-
   g_object_unref (gpmap);
 
   return pixbuf;
