summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGareth Stockwell <ext-gareth.stockwell@nokia.com>2010-02-09 09:41:29 (GMT)
committerJason McDonald <jason.mcdonald@nokia.com>2010-02-09 17:27:19 (GMT)
commit0bc45266e94067c7a76609f01f0ccae5023d8aa2 (patch)
tree4b69b4ada2709b01a3caca4bbea7f7e80cd9cce0
parentf909655642b08948a72d3b61384952e7878de7e2 (diff)
downloadQt-0bc45266e94067c7a76609f01f0ccae5023d8aa2.zip
Qt-0bc45266e94067c7a76609f01f0ccae5023d8aa2.tar.gz
Qt-0bc45266e94067c7a76609f01f0ccae5023d8aa2.tar.bz2
Fixed defect in handling of expose events for Symbian
Commit bc82db did not correctly handle native child widgets. Consider the case when we have a top-level widget A with a native child widget B. When QSymbianControl::Draw() is called on the control corresponding to B, the following occurs: 1. The inExpose flag is set in B's QWExtra structure. 2. The call to syncBackingStore() results in a call to QWidgetBackingStore::flush(), passing default parameters. 3. Because no target widget was passed to flush(), this function selects the top-level widget (A) as the target for the flush operation, passing A as the first argument of QS60WindowSurface::flush(). 4. QS60WindowSurface::flush() checks the inExpose flag from A's QWExtra structure, finds it to be false, and proceeds to call DrawNow() on A's control. Because QSymbianControl::Draw() uses the default graphics context, this context is shared between controls. This means that the DrawNow() call in step 4 causes a WSERV-10 panic (Activate() called on an already-active) graphics context. This patch moves the inExpose flag from B's QWExtra into A's QTLWExtra, with the result that the call to DrawNow() in step 4 is suppressed. Task-number: QTBUG-7960 Reviewed-by: axis (cherry picked from commit 46df42af1a25fd06247bb96d9e0bf24bf19defe8)
-rw-r--r--src/gui/kernel/qapplication_s60.cpp11
-rw-r--r--src/gui/kernel/qwidget_p.h3
-rw-r--r--src/gui/kernel/qwidget_s60.cpp2
-rw-r--r--src/gui/painting/qwindowsurface_s60.cpp11
4 files changed, 17 insertions, 10 deletions
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index 936277f..f553a51 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -809,12 +809,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;
+ QWidget *window = qwidget->window();
+ Q_ASSERT(window);
+ QTLWExtra *topExtra = window->d_func()->maybeTopData();
+ Q_ASSERT(topExtra);
+ if (!topExtra->inExpose) {
+ topExtra->inExpose = true;
QRect exposeRect = qt_TRect2QRect(controlRect);
qwidget->d_func()->syncBackingStore(exposeRect);
- extra->inExpose = false;
+ topExtra->inExpose = false;
}
QWindowSurface *surface = qwidget->windowSurface();
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 25b6508..962d694 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -173,6 +173,8 @@ struct QTLWExtra {
#ifndef QT_NO_QWS_MANAGER
QWSManager *qwsManager;
#endif
+#elif defined(Q_OS_SYMBIAN)
+ uint inExpose : 1; // Prevents drawing recursion
#endif
};
@@ -229,7 +231,6 @@ 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 dc54edf..2da392c 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -878,6 +878,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */)
void QWidgetPrivate::createTLSysExtra()
{
extra->topextra->backingStore = 0;
+ extra->topextra->inExpose = 0;
}
void QWidgetPrivate::deleteTLSysExtra()
@@ -891,7 +892,6 @@ 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 d997aea..8762175 100644
--- a/src/gui/painting/qwindowsurface_s60.cpp
+++ b/src/gui/painting/qwindowsurface_s60.cpp
@@ -145,12 +145,15 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget)
void QS60WindowSurface::flush(QWidget *widget, const QRegion &region, const QPoint &)
{
- QWExtra *extra = widget->d_func()->extraData();
- if (extra && !extra->inExpose) {
- extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
+ QWidget *window = widget->window();
+ Q_ASSERT(window);
+ QTLWExtra *topExtra = window->d_func()->maybeTopData();
+ Q_ASSERT(topExtra);
+ if (!topExtra->inExpose) {
+ topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again
TRect tr = qt_QRect2TRect(region.boundingRect());
widget->winId()->DrawNow(tr);
- extra->inExpose = false;
+ topExtra->inExpose = false;
}
}