From bc82db4d08860735bbae584a54d1b591c760e38b Mon Sep 17 00:00:00 2001 From: Jason Barron Date: Thu, 14 Jan 2010 10:44:24 +0100 Subject: Improve the behavior of expose events on Symbian. Previously when an expose was received from WSERV, we simply called BitBlt (for raster) or called flush on the window surface (for anything else). This behavior differs from other platforms which call syncBackingStore(). This difference means that we flush the backing store without actually updating the content first. This works for most cases because if there actually was new content, it would be updated when the widget's UpdateRequest event was handled. The problem arises when the backing store does not have the correct content. This can happen if the backing store was deleted, but only partially restored (see Task below). Another problem is with the OpenVG graphics system which assumes that beginPaint() is called before endPaint() is order to initialize the context and the surface size. The fix is to call syncBackingStore() like the other platforms, but introduce a bit field to prevent infinite recursion in the painting pipeline. Task-number: QTBUG-4921 Reviewed-by: axis Reviewed-by: Gareth Stockwell --- src/gui/kernel/qapplication_s60.cpp | 11 +++++++++-- src/gui/kernel/qwidget_p.h | 1 + src/gui/kernel/qwidget_s60.cpp | 1 + src/gui/painting/qwindowsurface_s60.cpp | 8 +++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 3ee0a71..8c77728 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -807,6 +807,15 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const void QSymbianControl::Draw(const TRect& controlRect) const { + // Set flag to avoid calling DrawNow in window surface + QWExtra *extra = qwidget->d_func()->extraData(); + if (extra && !extra->inExpose) { + extra->inExpose = true; + QRect exposeRect = qt_TRect2QRect(controlRect); + qwidget->d_func()->syncBackingStore(exposeRect); + extra->inExpose = false; + } + QWindowSurface *surface = qwidget->windowSurface(); QPaintEngine *engine = surface ? surface->paintDevice()->paintEngine() : NULL; @@ -855,8 +864,6 @@ void QSymbianControl::Draw(const TRect& controlRect) const default: Q_ASSERT(false); } - } else { - surface->flush(qwidget, QRegion(qt_TRect2QRect(backingStoreRect)), QPoint()); } if (sendNativePaintEvents) { diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index ec8d20f..b1eb3c3 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -229,6 +229,7 @@ struct QWExtra { #endif #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called + uint inExpose : 1; // Prevents drawing recursion /** * Defines the behaviour of QSymbianControl::Draw. diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index c65a162..4c0e21e 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -883,6 +883,7 @@ void QWidgetPrivate::createSysExtra() extra->activated = 0; extra->nativePaintMode = QWExtra::Default; extra->receiveNativePaintEvents = 0; + extra->inExpose = 0; } void QWidgetPrivate::deleteSysExtra() diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index b8eaead..b41dc2c 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -145,10 +145,12 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget) void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) { - const QVector subRects = region.rects(); - for (int i = 0; i < subRects.count(); ++i) { - TRect tr = qt_QRect2TRect(subRects[i]); + QWExtra *extra = widget->d_func()->extraData(); + if (extra && !extra->inExpose) { + extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again + TRect tr = qt_QRect2TRect(region.boundingRect()); widget->winId()->DrawNow(tr); + extra->inExpose = false; } } -- cgit v0.12