From 9ba448d61f35443f907d6b434ce58acd14a1c235 Mon Sep 17 00:00:00 2001 From: "sky@chromium.org" Date: Mon, 5 Oct 2009 16:36:05 +0000 Subject: More views on gtk paint tweaks. My previous attempt resulted in the ability to continually paint. I've tweaked it so that we only schedule a paint if the paint is happening from Gtk and not views. BUG=none TEST=none Review URL: http://codereview.chromium.org/251084 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27998 0039d316-1c4b-4281-b951-d872f2087c98 --- views/widget/root_view_gtk.cc | 23 +++++++++++++++-------- views/widget/widget_gtk.cc | 5 ++++- views/widget/widget_gtk.h | 7 +++++++ 3 files changed, 26 insertions(+), 9 deletions(-) (limited to 'views') diff --git a/views/widget/root_view_gtk.cc b/views/widget/root_view_gtk.cc index 75f444e..e284313 100644 --- a/views/widget/root_view_gtk.cc +++ b/views/widget/root_view_gtk.cc @@ -13,13 +13,17 @@ namespace views { void RootView::OnPaint(GdkEventExpose* event) { + WidgetGtk* widget = static_cast(GetWidget()); + if (!widget) { + NOTREACHED(); + return; + } gfx::Rect scheduled_dirty_rect = GetScheduledPaintRectConstrainedToSize(); gfx::Rect expose_rect = gfx::Rect(event->area); gfx::CanvasPaint canvas(event); bool invoked_process_paint = false; if (!canvas.is_empty()) { - canvas.set_composite_alpha( - static_cast(GetWidget())->is_transparent()); + canvas.set_composite_alpha(widget->is_transparent()); SchedulePaint(gfx::Rect(canvas.rectangle()), false); if (NeedsPainting(false)) { ProcessPaint(&canvas); @@ -28,12 +32,15 @@ void RootView::OnPaint(GdkEventExpose* event) { } if (invoked_process_paint && !scheduled_dirty_rect.IsEmpty() && - !expose_rect.Contains(scheduled_dirty_rect)) { - // The region Views needs to paint (scheduled_dirty_rect) isn't contained - // within the region GTK wants us to paint. ProccessPaint clears out the - // dirty region, so that at this point views thinks everything has painted - // correctly, but we haven't. Invoke schedule paint again to make sure we - // paint everything we need to. + !expose_rect.Contains(scheduled_dirty_rect) && widget && + !widget->in_paint_now()) { + // We're painting as the result of Gtk wanting us to paint (not from views) + // and there was a region scheduled by views to be painted that is not + // contained in the region gtk wants us to paint. As a result of the + // ProcessPaint call above views no longer thinks it needs to be painted. + // We have to invoke SchedulePaint here to be sure we end up painting the + // region views wants to paint, otherwise we'll drop the views paint region + // on the floor. // // NOTE: We don't expand the region to paint to include // scheduled_dirty_rect as that results in us drawing on top of any GTK diff --git a/views/widget/widget_gtk.cc b/views/widget/widget_gtk.cc index 8fcac89..734ea02 100644 --- a/views/widget/widget_gtk.cc +++ b/views/widget/widget_gtk.cc @@ -107,7 +107,8 @@ WidgetGtk::WidgetGtk(Type type) transparent_(false), ignore_drag_leave_(false), opacity_(255), - drag_data_(NULL) { + drag_data_(NULL), + in_paint_now_(false) { static bool installed_message_loop_observer = false; if (!installed_message_loop_observer) { installed_message_loop_observer = true; @@ -394,7 +395,9 @@ void WidgetGtk::PaintNow(const gfx::Rect& update_rect) { gtk_widget_queue_draw_area(widget_, update_rect.x(), update_rect.y(), update_rect.width(), update_rect.height()); // Force the paint to occur now. + in_paint_now_ = true; gdk_window_process_updates(widget_->window, true); + in_paint_now_ = false; } } diff --git a/views/widget/widget_gtk.h b/views/widget/widget_gtk.h index 080c1a0..8009f89 100644 --- a/views/widget/widget_gtk.h +++ b/views/widget/widget_gtk.h @@ -84,6 +84,10 @@ class WidgetGtk // Starts a drag on this widget. This blocks until the drag is done. void DoDrag(const OSExchangeData& data, int operation); + // Are we in PaintNow? See use in root_view_gtk for details on what this is + // used for. + bool in_paint_now() const { return in_paint_now_; } + // Overridden from Widget: virtual void Init(gfx::NativeView parent, const gfx::Rect& bounds); virtual void SetContentsView(View* view); @@ -377,6 +381,9 @@ class WidgetGtk // for the drag. const OSExchangeDataProviderGtk* drag_data_; + // See description above getter for details. + bool in_paint_now_; + DISALLOW_COPY_AND_ASSIGN(WidgetGtk); }; -- cgit v1.1