diff --git a/gdk/quartz/gdkdrawable-quartz.c b/gdk/quartz/gdkdrawable-quartz.c
index 7e1172f..760c4dc 100644
--- a/gdk/quartz/gdkdrawable-quartz.c
+++ b/gdk/quartz/gdkdrawable-quartz.c
@@ -19,6 +19,7 @@
  */
 
 #include <config.h>
+#include <sys/time.h>
 #include <cairo-quartz.h>
 #include "gdkprivate-quartz.h"
 
@@ -770,6 +771,13 @@ gdk_quartz_drawable_release_context (GdkDrawable  *drawable,
 	{
 	  [window_impl->view unlockFocus];
 
+          /* Support drawing from outside of expose. */
+          if (window_impl->begin_paint_count == 0)
+            {
+              if (_gdk_quartz_drawable_can_flush ())
+                CGContextFlush (cg_context);
+            }
+
 	  if (window_impl->pool)
 	    {
 	      [window_impl->pool release];
@@ -794,3 +802,26 @@ _gdk_quartz_drawable_finish (GdkDrawable *drawable)
       impl->cairo_surface = NULL;
     }
 }  
+
+/* When drawing outside of expose, we must flush manually. If we flush
+ * too often, Quartz starts blocking all drawing operations until the
+ * next vertical sync happens, so we have to throttle the flushing.
+ * See http://developer.apple.com/documentation/Performance/
+ * Conceptual/Drawing/index.html.
+ */
+gboolean
+_gdk_quartz_drawable_can_flush (void)
+{
+  static struct timeval prev_tv;
+  struct timeval tv;
+
+  gettimeofday (&tv, NULL);
+  if (tv.tv_sec - prev_tv.tv_sec > 0 ||
+      tv.tv_usec - prev_tv.tv_usec > 30000)
+    {
+      prev_tv = tv;
+      return TRUE;
+    }
+
+  return FALSE;
+}
diff --git a/gdk/quartz/gdkprivate-quartz.h b/gdk/quartz/gdkprivate-quartz.h
index c3b7b0b..c3f1a1d 100644
--- a/gdk/quartz/gdkprivate-quartz.h
+++ b/gdk/quartz/gdkprivate-quartz.h
@@ -176,6 +176,7 @@ GdkEventType _gdk_quartz_keys_event_type  (NSEvent   *event);
 gboolean     _gdk_quartz_keys_is_modifier (guint      keycode);
 
 /* Drawable */
-void        _gdk_quartz_drawable_finish (GdkDrawable *drawable);
+void        _gdk_quartz_drawable_finish    (GdkDrawable *drawable);
+gboolean    _gdk_quartz_drawable_can_flush (void);
 
 #endif /* __GDK_PRIVATE_QUARTZ_H__ */
diff --git a/gdk/quartz/gdkwindow-quartz.c b/gdk/quartz/gdkwindow-quartz.c
index 63f0197..6214fad 100644
--- a/gdk/quartz/gdkwindow-quartz.c
+++ b/gdk/quartz/gdkwindow-quartz.c
@@ -282,7 +282,8 @@ gdk_window_quartz_process_updates_internal (GdkWindow *window)
 							rects[i].width, rects[i].height)];
 	}
 
-      [impl->view displayIfNeeded];
+      if (_gdk_quartz_drawable_can_flush ())
+        [impl->view displayIfNeeded];
 
       g_free (rects);
     }
