From 3a72235d7cf2aa953cb32654545c480fd2d08866 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Mon, 10 May 2010 17:01:57 +0100 Subject: Added tst_QWidget::destroyBackingStoreWhenHidden Task-number: QTBUG-8697 Reviewed-by: Jason Barron --- tests/auto/qwidget/tst_qwidget.cpp | 247 +++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 76e20b997e..f4add5a8b7 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -385,6 +385,7 @@ private slots: void setGraphicsEffect(); void destroyBackingStore(); + void destroyBackingStoreWhenHidden(); void activateWindow(); @@ -9517,6 +9518,252 @@ void tst_QWidget::destroyBackingStore() #endif } +// Helper function +QWidgetBackingStore* backingStore(QWidget &widget) +{ + QWidgetBackingStore *backingStore = 0; +#ifdef QT_BUILD_INTERNAL + if (QTLWExtra *topExtra = qt_widget_private(&widget)->maybeTopData()) + backingStore = topExtra->backingStore; +#endif + return backingStore; +} + +// Wait for a condition to be true, timing out after 1 second +// This is used following calls to QWidget::show() and QWidget::hide(), which are +// expected to asynchronously trigger native window visibility events. +#define WAIT_AND_VERIFY(condition) \ + do { \ + QTime start = QTime::currentTime(); \ + while (!(condition) && (start.elapsed() < 1000)) { \ + qApp->processEvents(); \ + QTest::qWait(50); \ + } \ + if (!QTest::qVerify((condition), #condition, "", __FILE__, __LINE__)) \ + return; \ + } while (0) + +void tst_QWidget::destroyBackingStoreWhenHidden() +{ +#ifndef QT_BUILD_INTERNAL + QSKIP("Test step requires access to Q_AUTOTEST_EXPORT", SkipAll); +#endif + +#ifndef Q_OS_SYMBIAN + QSKIP("Only Symbian destroys backing store when native window becomes invisible", SkipAll); +#endif + + testWidget->hide(); + QTest::qWait(1000); + + // 1. Single top-level QWidget + { + QWidget w; + w.setAutoFillBackground(true); + w.setPalette(Qt::yellow); + w.setGeometry(0, 0, 100, 100); + w.show(); + QTest::qWaitForWindowShown(&w); + QVERIFY(0 != backingStore(w)); + + w.hide(); + WAIT_AND_VERIFY(0 == backingStore(w)); + + w.show(); + QTest::qWaitForWindowShown(&w); + QVERIFY(0 != backingStore(w)); + } + + // 2. Two top-level widgets + { + QWidget w1; + w1.setGeometry(0, 0, 100, 100); + w1.setAutoFillBackground(true); + w1.setPalette(Qt::red); + w1.show(); + QTest::qWaitForWindowShown(&w1); + QVERIFY(0 != backingStore(w1)); + + QWidget w2; + w2.setGeometry(w1.geometry()); + w1.setAutoFillBackground(true); + w1.setPalette(Qt::blue); + w2.show(); + QTest::qWaitForWindowShown(&w2); + QVERIFY(0 != backingStore(w2)); + + // Check that w1 deleted its backing store when obscured by w2 + QVERIFY(0 == backingStore(w1)); + + w2.move(w2.pos() + QPoint(10, 10)); + + // Check that w1 recreates its backing store when partially revealed + WAIT_AND_VERIFY(0 != backingStore(w1)); + } + + // 3. Native child widget + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::yellow); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::green); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + child.winId(); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QWidgetBackingStore *const parentBs = backingStore(parent); + QVERIFY(0 != parentBs); + QVERIFY(0 == backingStore(child)); + + // Set margins to zero so that child widget totally obscures parent + layout.setContentsMargins(0, 0, 0, 0); + + WAIT_AND_VERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Backing store should remain unchanged despite child window obscuring + // parent window + QEXPECT_FAIL("", "QTBUG-8697", Continue); + QVERIFY(parentBs == backingStore(parent)); + QVERIFY(0 == backingStore(child)); + } + + // 4. Alien child widget which is made full-screen + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::red); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::blue); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QVERIFY(0 != backingStore(parent)); + QVERIFY(0 == backingStore(child)); + + // Make child widget full screen + child.setWindowFlags((child.windowFlags() | Qt::Window) ^ Qt::SubWindow); + child.setWindowState(child.windowState() | Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that child window obscures parent window + QVERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Now that extent of child widget goes beyond parent's extent, + // a new backing store should be created for the child widget. + QVERIFY(0 != backingStore(child)); + + // Parent is obscured, therefore its backing store should be destroyed + QVERIFY(0 == backingStore(parent)); + + // Disable full screen + child.setWindowFlags(child.windowFlags() ^ (Qt::Window | Qt::SubWindow)); + child.setWindowState(child.windowState() ^ Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that parent is now visible again + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should once again share parent's backing store + QVERIFY(0 != backingStore(parent)); + QEXPECT_FAIL("", "QTBUG-10643", Continue); + QVERIFY(0 == backingStore(child)); + } + + // 5. Native child widget which is made full-screen + { + QWidget parent; + parent.setGeometry(0, 0, 100, 100); + parent.setAutoFillBackground(true); + parent.setPalette(Qt::red); + + QWidget child(&parent); + child.setAutoFillBackground(true); + child.setPalette(Qt::blue); + + QVBoxLayout layout(&parent); + layout.setContentsMargins(10, 10, 10, 10); + layout.addWidget(&child); + parent.setLayout(&layout); + + child.winId(); + + parent.show(); + QTest::qWaitForWindowShown(&parent); + + // Check that child window does not obscure parent window + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should share parent's backing store + QVERIFY(0 != backingStore(parent)); + QVERIFY(0 == backingStore(child)); + + // Make child widget full screen + child.setWindowFlags((child.windowFlags() | Qt::Window) ^ Qt::SubWindow); + child.setWindowState(child.windowState() | Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Ensure that 'window hidden' event is received by parent + qApp->processEvents(); + + // Check that child window obscures parent window + QVERIFY(parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Now that extent of child widget goes beyond parent's extent, + // a new backing store should be created for the child widget. + QVERIFY(0 != backingStore(child)); + + // Parent is obscured, therefore its backing store should be destroyed + QVERIFY(0 == backingStore(parent)); + + // Disable full screen + child.setWindowFlags(child.windowFlags() ^ (Qt::Window | Qt::SubWindow)); + child.setWindowState(child.windowState() ^ Qt::WindowFullScreen); + child.show(); + QTest::qWaitForWindowShown(&child); + + // Check that parent is now visible again + QVERIFY(!parent.visibleRegion().subtracted(child.visibleRegion()).isEmpty()); + + // Native child widget should once again share parent's backing store + QVERIFY(0 != backingStore(parent)); + QEXPECT_FAIL("", "QTBUG-10643", Continue); + QVERIFY(0 == backingStore(child)); + } +} + +#undef WAIT_AND_VERIFY + void tst_QWidget::rectOutsideCoordinatesLimit_task144779() { #ifdef Q_OS_WINCE_WM -- cgit v1.2.3 From d7057e7c1f1a4769c6e9b0e1c54446d5104c1484 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Tue, 11 May 2010 16:50:00 +0100 Subject: Added reference counting to QWidgetBackingStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Symbian, the top-level widget's backing store must be destroyed when it is no longer required, in order to conserve memory. The criteria for destroying the backing store is when neither the TLW nor any of its native descendents (which share the backing store) are visible. In order to implement this requirement, a count must be kept of the number of native widgets which are using the TLW's backing store. This patch provides the mechanism for maintaining this count, and for destroying the backing store when the count is decremented to zero. No calls to either the increment nor decrement functions are made, however, by this code included in this patch; this code will be added to only the Symbian backend by a subsequent patch. Task-number: QTBUG-8697 Reviewed-by: Bjørn Erik Nilsen Reviewed-by: Jason Barron --- src/gui/embedded/qwsmanager_qws.cpp | 2 +- src/gui/kernel/qapplication_s60.cpp | 5 ++-- src/gui/kernel/qapplication_x11.cpp | 2 +- src/gui/kernel/qwidget.cpp | 57 +++++++++++++++++++++++++++++++------ src/gui/kernel/qwidget_p.h | 44 ++++++++++++++++++++++++++-- src/gui/kernel/qwidget_s60.cpp | 4 +-- src/gui/painting/qbackingstore.cpp | 4 +-- tests/auto/qwidget/tst_qwidget.cpp | 13 +++------ 8 files changed, 102 insertions(+), 29 deletions(-) diff --git a/src/gui/embedded/qwsmanager_qws.cpp b/src/gui/embedded/qwsmanager_qws.cpp index d6ef14858b..ac6d36eb25 100644 --- a/src/gui/embedded/qwsmanager_qws.cpp +++ b/src/gui/embedded/qwsmanager_qws.cpp @@ -392,7 +392,7 @@ void QWSManagerPrivate::dirtyRegion(int decorationRegion, const QRegion &clip) { QTLWExtra *topextra = managed->d_func()->extra->topextra; - QWidgetBackingStore *bs = topextra->backingStore; + QWidgetBackingStore *bs = topextra->backingStore.data(); const bool pendingUpdateRequest = bs->isDirty(); if (decorationRegion == QDecoration::All) { diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index b1e0f63d0f..6997326bdd 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1706,14 +1706,13 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent if (!w->d_func()->maybeTopData()) break; if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) { - delete w->d_func()->topData()->backingStore; - w->d_func()->topData()->backingStore = 0; + w->d_func()->topData()->backingStore.destroy(); // In order to ensure that any resources used by the window surface // are immediately freed, we flush the WSERV command buffer. S60->wsSession().Flush(); } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) && !w->d_func()->maybeBackingStore()) { - w->d_func()->topData()->backingStore = new QWidgetBackingStore(w); + w->d_func()->topData()->backingStore.create(w); w->d_func()->invalidateBuffer(w->rect()); w->repaint(); } diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 25a7750d96..304cd173e9 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5245,7 +5245,7 @@ bool QETWidget::translateConfigEvent(const XEvent *event) if (isVisible() && data->crect.size() != oldSize) { Q_ASSERT(d->extra->topextra); - QWidgetBackingStore *bs = d->extra->topextra->backingStore; + QWidgetBackingStore *bs = d->extra->topextra->backingStore.data(); const bool hasStaticContents = bs && bs->hasStaticContents(); // If we have a backing store with static contents, we have to disable the top-level // resize optimization in order to get invalidated regions for resized widgets. diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index e180001291..a9ea9ac563 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -161,6 +161,51 @@ static inline bool hasBackingStoreSupport() extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp + +QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore() + : m_ptr(0) + , m_count(0) +{ + +} + +QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore() +{ + delete m_ptr; +} + +void QRefCountedWidgetBackingStore::create(QWidget *widget) +{ + destroy(); + m_ptr = new QWidgetBackingStore(widget); + m_count = 0; +} + +void QRefCountedWidgetBackingStore::destroy() +{ + delete m_ptr; + m_ptr = 0; + m_count = 0; +} + +void QRefCountedWidgetBackingStore::ref() +{ + Q_ASSERT(m_ptr); + ++m_count; +} + +void QRefCountedWidgetBackingStore::deref() +{ + if (m_count) { + Q_ASSERT(m_ptr); + if (0 == --m_count) { + delete m_ptr; + m_ptr = 0; + } + } +} + + QWidgetPrivate::QWidgetPrivate(int version) : QObjectPrivate(version) , extra(0) @@ -1324,11 +1369,9 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { - delete d->topData()->backingStore; - // QWidgetBackingStore will check this variable, hence it must be 0 - d->topData()->backingStore = 0; + d->topData()->backingStore.destroy(); if (hasBackingStoreSupport()) - d->topData()->backingStore = new QWidgetBackingStore(this); + d->topData()->backingStore.create(this); } d->setModal_sys(); @@ -1451,8 +1494,7 @@ QWidget::~QWidget() // the backing store will delete its window surface, which may or may // not have a reference to this widget that will be used later to // notify the window it no longer has a surface. - delete d->extra->topextra->backingStore; - d->extra->topextra->backingStore = 0; + d->extra->topextra->backingStore.destroy(); } #endif if (QWidgetBackingStore *bs = d->maybeBackingStore()) { @@ -1540,7 +1582,6 @@ void QWidgetPrivate::createTLExtra() QTLWExtra* x = extra->topextra = new QTLWExtra; x->icon = 0; x->iconPixmap = 0; - x->backingStore = 0; x->windowSurface = 0; x->sharedPainter = 0; x->incw = x->inch = 0; @@ -1619,7 +1660,7 @@ void QWidgetPrivate::deleteExtra() #endif if (extra->topextra) { deleteTLSysExtra(); - delete extra->topextra->backingStore; + extra->topextra->backingStore.destroy(); delete extra->topextra->icon; delete extra->topextra->iconPixmap; #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 555647c1df..9f7ad95aac 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -110,13 +110,53 @@ class QWidgetItemV2; class QStyle; +class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore +{ +public: + QRefCountedWidgetBackingStore(); + ~QRefCountedWidgetBackingStore(); + + void create(QWidget *tlw); + void destroy(); + + void ref(); + void deref(); + + inline QWidgetBackingStore* data() + { + return m_ptr; + } + + inline QWidgetBackingStore* operator->() + { + return m_ptr; + } + + inline QWidgetBackingStore& operator*() + { + return *m_ptr; + } + + inline operator bool() const + { + return (0 != m_ptr); + } + +private: + Q_DISABLE_COPY(QRefCountedWidgetBackingStore) + +private: + QWidgetBackingStore* m_ptr; + int m_count; +}; + struct QTLWExtra { // *************************** Cross-platform variables ***************************** // Regular pointers (keep them together to avoid gaps on 64 bits architectures). QIcon *icon; // widget icon QPixmap *iconPixmap; - QWidgetBackingStore *backingStore; + QRefCountedWidgetBackingStore backingStore; QWindowSurface *windowSurface; QPainter *sharedPainter; @@ -907,7 +947,7 @@ inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const { Q_Q(const QWidget); QTLWExtra *x = q->window()->d_func()->maybeTopData(); - return x ? x->backingStore : 0; + return x ? x->backingStore.data() : 0; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 438c2a303a..6b91dff2f7 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -908,14 +908,12 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { - extra->topextra->backingStore = 0; extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() { - delete extra->topextra->backingStore; - extra->topextra->backingStore = 0; + extra->topextra->backingStore.destroy(); } void QWidgetPrivate::createSysExtra() diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 8de9eaa5c8..3ddffef7c2 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -914,7 +914,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); } else { - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); QRegion childExpose(newRect & clipR); if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw)) @@ -957,7 +957,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (x->inTopLevelResize) return; - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); if (!wbs) return; diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index f4add5a8b7..9369f4a774 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -9500,9 +9500,7 @@ void tst_QWidget::destroyBackingStore() QTRY_VERIFY(w.numPaintEvents > 0); w.reset(); w.update(); - delete qt_widget_private(&w)->topData()->backingStore; - qt_widget_private(&w)->topData()->backingStore = 0; - qt_widget_private(&w)->topData()->backingStore = new QWidgetBackingStore(&w); + qt_widget_private(&w)->topData()->backingStore.create(&w); w.update(); QApplication::processEvents(); @@ -9524,7 +9522,7 @@ QWidgetBackingStore* backingStore(QWidget &widget) QWidgetBackingStore *backingStore = 0; #ifdef QT_BUILD_INTERNAL if (QTLWExtra *topExtra = qt_widget_private(&widget)->maybeTopData()) - backingStore = topExtra->backingStore; + backingStore = topExtra->backingStore.data(); #endif return backingStore; } @@ -10244,15 +10242,12 @@ class scrollWidgetWBS : public QWidget public: void deleteBackingStore() { - if (static_cast(d_ptr.data())->maybeBackingStore()) { - delete static_cast(d_ptr.data())->topData()->backingStore; - static_cast(d_ptr.data())->topData()->backingStore = 0; - } + static_cast(d_ptr.data())->topData()->backingStore.destroy(); } void enableBackingStore() { if (!static_cast(d_ptr.data())->maybeBackingStore()) { - static_cast(d_ptr.data())->topData()->backingStore = new QWidgetBackingStore(this); + static_cast(d_ptr.data())->topData()->backingStore.create(this); static_cast(d_ptr.data())->invalidateBuffer(this->rect()); repaint(); } -- cgit v1.2.3 From 6c57e76ea755b28d30405fd1239bf4275e8271b4 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 12 May 2010 16:18:18 +0100 Subject: Enable visibility change events on all Symbian native windows Previously, these events were enabled only on top-level widgets. This patch enables them also for native child widgets. Task-number: QTBUG-8697 Reviewed-by: Jason Barron --- src/gui/kernel/qwidget_s60.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 6b91dff2f7..86b858dabd 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -433,6 +433,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de // Request mouse move events. drawableWindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); + drawableWindow->EnableVisibilityChangeEvents(); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) { activateSymbianWindow(control.data()); -- cgit v1.2.3 From 603ccb3d715b1d6e9969b2df8ab27461f51728fb Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Thu, 13 May 2010 14:11:07 +0100 Subject: Window visibility changes update TLW backing store reference count * When a native window becomes completely invisible, the reference count of the top-level widget's backing store is decremented. * When a previously invisible native window becomes either partially or fully visible: - If the top-level widget has a backing store, its reference count is incremented. - Otherwise, the top-level widget creates a backing store with an initial reference count of 1. Task-number: QTBUG-8697 Reviewed-by: Jason Barron --- src/gui/kernel/qapplication_s60.cpp | 23 ++++++++++++++++------- tests/auto/qwidget/tst_qwidget.cpp | 2 +- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 6997326bdd..78027b2752 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1703,18 +1703,27 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent return 1; const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged(); QWidget *w = QWidgetPrivate::mapper->value(control); - if (!w->d_func()->maybeTopData()) + QWidget *const window = w->window(); + if (!window->d_func()->maybeTopData()) break; + QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore; if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) { - w->d_func()->topData()->backingStore.destroy(); + // Decrement backing store reference count + backingStore.deref(); // In order to ensure that any resources used by the window surface // are immediately freed, we flush the WSERV command buffer. S60->wsSession().Flush(); - } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) - && !w->d_func()->maybeBackingStore()) { - w->d_func()->topData()->backingStore.create(w); - w->d_func()->invalidateBuffer(w->rect()); - w->repaint(); + } else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) { + if (backingStore.data()) { + // Increment backing store reference count + backingStore.ref(); + } else { + // Create backing store with an initial reference count of 1 + backingStore.create(window); + backingStore.ref(); + w->d_func()->invalidateBuffer(w->rect()); + w->repaint(); + } } return 1; } diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 9369f4a774..7d4f8ffa1a 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -9635,7 +9635,6 @@ void tst_QWidget::destroyBackingStoreWhenHidden() // Backing store should remain unchanged despite child window obscuring // parent window - QEXPECT_FAIL("", "QTBUG-8697", Continue); QVERIFY(parentBs == backingStore(parent)); QVERIFY(0 == backingStore(child)); } @@ -9742,6 +9741,7 @@ void tst_QWidget::destroyBackingStoreWhenHidden() QVERIFY(0 != backingStore(child)); // Parent is obscured, therefore its backing store should be destroyed + QEXPECT_FAIL("", "QTBUG-10643", Continue); QVERIFY(0 == backingStore(parent)); // Disable full screen -- cgit v1.2.3 From 6acfea19d4c00150602c152943d89bf429462c39 Mon Sep 17 00:00:00 2001 From: Gareth Stockwell Date: Wed, 2 Jun 2010 15:19:59 +0100 Subject: Removed compiler warnings Emitted when building with MetroWerks x86 toolchain. Reviewed-by: trustme --- src/3rdparty/phonon/mmf/abstractaudioeffect.cpp | 2 ++ src/3rdparty/phonon/mmf/abstractaudioeffect.h | 4 ++++ src/3rdparty/phonon/mmf/audiooutput.cpp | 3 +++ src/3rdparty/phonon/mmf/bassboost.cpp | 1 + src/3rdparty/phonon/mmf/effectfactory.cpp | 5 +++-- src/3rdparty/phonon/mmf/loudness.cpp | 1 + 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index 6cfeb768ae..9b64ab3ff2 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -184,6 +184,8 @@ int AbstractAudioEffect::effectParameterChanged( const EffectParameter ¶m, const QVariant &value) { // Default implementation + Q_UNUSED(param) + Q_UNUSED(value) Q_ASSERT_X(false, Q_FUNC_INFO, "Effect has no parameters"); return 0; } diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index d71993b146..70adcf644f 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -118,6 +118,10 @@ private: // for each of the effects. Using this reduces repetition of boilerplate // in the implementations of the backend effect nodes. +#ifdef Q_CC_NOKIAX86 +# pragma warn_illtokenpasting off +#endif + #define PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(Effect) \ \ void Effect##::createEffect(AudioPlayer::NativePlayer *player) \ diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index c6be20b3de..358868379b 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -78,6 +78,9 @@ bool MMF::AudioOutput::setOutputDevice(int index) { Q_ASSERT_X(index == AudioOutputDeviceID, Q_FUNC_INFO, "We only support one output device, with id 0"); +#ifdef QT_NO_DEBUG + Q_UNUSED(index) +#endif return true; } diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index c7af93924b..67076f62d0 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -49,6 +49,7 @@ const char* BassBoost::description() bool BassBoost::getParameters(CMdaAudioOutputStream *stream, QList ¶meters) { + Q_UNUSED(parameters) QScopedPointer effect; TRAPD(err, effect.reset(CBassBoost::NewL(*stream))); return (KErrNone == err); diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp index c5e33d5c7a..4643978d2f 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.cpp +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -183,8 +183,9 @@ EffectFactory::EffectData EffectFactory::getData() /* defaultValue */ QVariant(bool(true))); data.m_parameters.append(param); - if (data.m_supported = BackendNode::getParameters - (stream.data(), data.m_parameters)) { + data.m_supported = BackendNode::getParameters(stream.data(), + data.m_parameters); + if (data.m_supported) { const QString description = QCoreApplication::translate ("Phonon::MMF::EffectFactory", BackendNode::description()); data.m_descriptions.insert("name", description); diff --git a/src/3rdparty/phonon/mmf/loudness.cpp b/src/3rdparty/phonon/mmf/loudness.cpp index 1079a35653..ca05ab0989 100644 --- a/src/3rdparty/phonon/mmf/loudness.cpp +++ b/src/3rdparty/phonon/mmf/loudness.cpp @@ -49,6 +49,7 @@ const char* Loudness::description() bool Loudness::getParameters(CMdaAudioOutputStream *stream, QList ¶meters) { + Q_UNUSED(parameters) QScopedPointer effect; TRAPD(err, effect.reset(CLoudness::NewL(*stream))); return (KErrNone == err); -- cgit v1.2.3