summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-22 00:11:15 +0000
committerevanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-11-22 00:11:15 +0000
commitef96b09a2b287d8911faa5ec9393d119eb09f269 (patch)
treed802c7a20dae3c58d1b272e3ac688d3738770b1f
parent8c2fcd19acaa0b3aeeae0aacd0f698d9d0e4b0a4 (diff)
downloadchromium_src-ef96b09a2b287d8911faa5ec9393d119eb09f269.zip
chromium_src-ef96b09a2b287d8911faa5ec9393d119eb09f269.tar.gz
chromium_src-ef96b09a2b287d8911faa5ec9393d119eb09f269.tar.bz2
Fix infinite paint loop on Linux.
In response to an invalidation, we call into WebKit to do layout. On Windows, WM_PAINT is a virtual message so any extra Invalidates that come up while it's doing layout are implicitly swallowed as soon as we actually do drawing via BeginPaint. Though GTK does know how to collapse multiple paint requests, it won't erase paint requests from the future when we start drawing. So the solution is to track whether we're currently handling a redraw, and during that if we get told by WebKit that a region has become invalid, we still add that region to the local dirty rect but *don't* enqueue yet another "do a paint" message. Review URL: http://codereview.chromium.org/11371 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5874 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--webkit/tools/test_shell/webwidget_host_gtk.cc22
1 files changed, 20 insertions, 2 deletions
diff --git a/webkit/tools/test_shell/webwidget_host_gtk.cc b/webkit/tools/test_shell/webwidget_host_gtk.cc
index b62f912..23d8d8a 100644
--- a/webkit/tools/test_shell/webwidget_host_gtk.cc
+++ b/webkit/tools/test_shell/webwidget_host_gtk.cc
@@ -16,6 +16,19 @@
namespace {
+// In response to an invalidation, we call into WebKit to do layout. On
+// Windows, WM_PAINT is a virtual message so any extra invalidates that come up
+// while it's doing layout are implicitly swallowed as soon as we actually do
+// drawing via BeginPaint.
+//
+// Though GTK does know how to collapse multiple paint requests, it won't erase
+// paint requests from the future when we start drawing. To avoid an infinite
+// cycle of repaints, we track whether we're currently handling a redraw, and
+// during that if we get told by WebKit that a region has become invalid, we
+// still add that region to the local dirty rect but *don't* enqueue yet
+// another "do a paint" message.
+bool handling_expose = false;
+
// -----------------------------------------------------------------------------
// Callback functions to proxy to host...
@@ -27,9 +40,12 @@ gboolean ConfigureEvent(GtkWidget* widget, GdkEventConfigure* config,
gboolean ExposeEvent(GtkWidget* widget, GdkEventExpose* expose,
WebWidgetHost* host) {
+ // See comments above about what handling_expose is for.
+ handling_expose = true;
gfx::Rect rect(expose->area);
host->UpdatePaintRect(rect);
host->Paint();
+ handling_expose = false;
return FALSE;
}
@@ -155,8 +171,10 @@ void WebWidgetHost::DidInvalidateRect(const gfx::Rect& damaged_rect) {
UpdatePaintRect(damaged_rect);
- gtk_widget_queue_draw_area(GTK_WIDGET(view_), damaged_rect.x(),
- damaged_rect.y(), damaged_rect.width(), damaged_rect.height());
+ if (!handling_expose) {
+ gtk_widget_queue_draw_area(GTK_WIDGET(view_), damaged_rect.x(),
+ damaged_rect.y(), damaged_rect.width(), damaged_rect.height());
+ }
}
void WebWidgetHost::DidScrollRect(int dx, int dy, const gfx::Rect& clip_rect) {