Index: gdk/gdk.symbols
===================================================================
--- gdk/gdk.symbols	(revision 18575)
+++ gdk/gdk.symbols	(working copy)
@@ -649,6 +649,7 @@ gdk_window_constrain_size
 gdk_window_destroy
 gdk_window_end_paint
 gdk_window_foreign_new
+gdk_window_freeze_toplevel_updates_libgtk_only
 gdk_window_freeze_updates
 gdk_window_get_children
 gdk_window_get_internal_paint_info
@@ -673,6 +674,7 @@ gdk_window_process_updates
 gdk_window_remove_filter
 gdk_window_set_debug_updates
 gdk_window_set_user_data
+gdk_window_thaw_toplevel_updates_libgtk_only
 gdk_window_thaw_updates
 gdk_window_set_composited
 #endif
Index: gdk/gdkwindow.c
===================================================================
--- gdk/gdkwindow.c	(revision 18575)
+++ gdk/gdkwindow.c	(working copy)
@@ -2290,10 +2290,22 @@ gdk_window_update_idle (gpointer data)
   return FALSE;
 }
 
+static gboolean
+gdk_window_is_toplevel_frozen (GdkWindow *window)
+{
+  GdkWindowObject *toplevel;
+
+  toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
+
+  return toplevel->update_and_descendants_freeze_count > 0;
+}
+
 static void
 gdk_window_schedule_update (GdkWindow *window)
 {
-  if (window && GDK_WINDOW_OBJECT (window)->update_freeze_count)
+  if (window &&
+      (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
+       gdk_window_is_toplevel_frozen (window)))
     return;
 
   if (!update_idle)
@@ -2423,7 +2435,8 @@ gdk_window_process_all_updates (void)
     {
       GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
       
-      if (private->update_freeze_count)
+      if (private->update_freeze_count ||
+	  gdk_window_is_toplevel_frozen (tmp_list->data))
 	update_windows = g_slist_prepend (update_windows, private);
       else
 	gdk_window_process_updates_internal (tmp_list->data);
@@ -2471,7 +2484,9 @@ gdk_window_process_updates (GdkWindow *w
       return;
     }
   
-  if (private->update_area && !private->update_freeze_count)
+  if (private->update_area &&
+      !private->update_freeze_count &&
+      !gdk_window_is_toplevel_frozen (window))
     {      
       gdk_window_process_updates_internal (window);
       update_windows = g_slist_remove (update_windows, window);
@@ -2816,6 +2831,58 @@ gdk_window_thaw_updates (GdkWindow *wind
 }
 
 /**
+ * gdk_window_freeze_toplevel_updates_libgtk_only:
+ * @window: a #GdkWindow
+ *
+ * Temporarily freezes a window and all its descendants such that it won't
+ * receive expose events.  The window will begin receiving expose events
+ * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
+ * gdk_window_freeze_toplevel_updates_libgtk_only()
+ * has been called more than once,
+ * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
+ * an equal number of times to begin processing exposes.
+ *
+ * This function is not part of the GDK public API and is only
+ * for use by GTK+.
+ **/
+void
+gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
+
+  private->update_and_descendants_freeze_count++;
+}
+
+/**
+ * gdk_window_thaw_toplevel_updates_libgtk_only:
+ * @window: a #GdkWindow
+ * 
+ * Thaws a window frozen with
+ * gdk_window_freeze_toplevel_updates_libgtk_only().
+ *
+ * This function is not part of the GDK public API and is only
+ * for use by GTK+.
+ **/
+void
+gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
+{
+  GdkWindowObject *private = (GdkWindowObject *)window;
+
+  g_return_if_fail (window != NULL);
+  g_return_if_fail (GDK_IS_WINDOW (window));
+  g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
+  g_return_if_fail (private->update_and_descendants_freeze_count > 0);
+
+  private->update_and_descendants_freeze_count--;
+
+  gdk_window_schedule_update (window);
+}
+
+/**
  * gdk_window_set_debug_updates:
  * @setting: %TRUE to turn on update debugging
  *
Index: gdk/gdkwindow.h
===================================================================
--- gdk/gdkwindow.h	(revision 18575)
+++ gdk/gdkwindow.h	(working copy)
@@ -298,6 +298,8 @@ struct _GdkWindowObject
   guint shaped : 1;
   
   GdkEventMask event_mask;
+
+  guint update_and_descendants_freeze_count;
 };
 
 struct _GdkWindowObjectClass
@@ -605,6 +607,9 @@ GdkRegion *gdk_window_get_update_area   
 void       gdk_window_freeze_updates      (GdkWindow    *window);
 void       gdk_window_thaw_updates        (GdkWindow    *window);
 
+void       gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window);
+void       gdk_window_thaw_toplevel_updates_libgtk_only   (GdkWindow *window);
+
 void       gdk_window_process_all_updates (void);
 void       gdk_window_process_updates     (GdkWindow    *window,
 					   gboolean      update_children);
Index: gtk/gtkwindow.c
===================================================================
--- gtk/gtkwindow.c	(revision 18575)
+++ gtk/gtkwindow.c	(working copy)
@@ -4817,7 +4817,10 @@ gtk_window_configure_event (GtkWidget   
    */
 
   if (window->configure_request_count > 0)
-    window->configure_request_count -= 1;
+    {
+      window->configure_request_count -= 1;
+      gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
+    }
   
   /* As an optimization, we avoid a resize when possible.
    *
@@ -6051,28 +6054,47 @@ gtk_window_move_resize (GtkWindow *windo
 			     new_request.width, new_request.height);
 	}
       
-      /* Increment the number of have-not-yet-received-notify requests */
-      window->configure_request_count += 1;
+      if (window->type == GTK_WINDOW_POPUP)
+        {
+	  GtkAllocation allocation;
 
-      /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
-       * configure event in response to our resizing request.
-       * the configure event will cause a new resize with
-       * ->configure_notify_received=TRUE.
-       * until then, we want to
-       * - discard expose events
-       * - coalesce resizes for our children
-       * - defer any window resizes until the configure event arrived
-       * to achieve this, we queue a resize for the window, but remove its
-       * resizing handler, so resizing will not be handled from the next
-       * idle handler but when the configure event arrives.
-       *
-       * FIXME: we should also dequeue the pending redraws here, since
-       * we handle those ourselves upon ->configure_notify_received==TRUE.
-       */
-      if (container->resize_mode == GTK_RESIZE_QUEUE)
-	{
-	  gtk_widget_queue_resize (widget);
-	  _gtk_container_dequeue_resize_handler (container);
+	  /* Directly size allocate for override redirect (popup) windows. */
+	  allocation.width = new_request.width;
+	  allocation.height = new_request.height;
+
+	  gtk_widget_size_allocate (widget, &allocation);
+
+	  gdk_window_process_updates (widget->window, TRUE);
+
+	  if (container->resize_mode == GTK_RESIZE_QUEUE)
+	    gtk_widget_queue_draw (widget);
+	}
+      else
+        {
+	  /* Increment the number of have-not-yet-received-notify requests */
+	  window->configure_request_count += 1;
+	  gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
+
+	  /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
+	   * configure event in response to our resizing request.
+	   * the configure event will cause a new resize with
+	   * ->configure_notify_received=TRUE.
+	   * until then, we want to
+	   * - discard expose events
+	   * - coalesce resizes for our children
+	   * - defer any window resizes until the configure event arrived
+	   * to achieve this, we queue a resize for the window, but remove its
+	   * resizing handler, so resizing will not be handled from the next
+	   * idle handler but when the configure event arrives.
+	   *
+	   * FIXME: we should also dequeue the pending redraws here, since
+	   * we handle those ourselves upon ->configure_notify_received==TRUE.
+	   */
+	  if (container->resize_mode == GTK_RESIZE_QUEUE)
+	    {
+	      gtk_widget_queue_resize (widget);
+	      _gtk_container_dequeue_resize_handler (container);
+	    }
 	}
     }
   else
