diff options
author | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-22 00:11:15 +0000 |
---|---|---|
committer | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-22 00:11:15 +0000 |
commit | ef96b09a2b287d8911faa5ec9393d119eb09f269 (patch) | |
tree | d802c7a20dae3c58d1b272e3ac688d3738770b1f | |
parent | 8c2fcd19acaa0b3aeeae0aacd0f698d9d0e4b0a4 (diff) | |
download | chromium_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.cc | 22 |
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) { |