diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 3b63028a2e4bc0ce930eb0a0cd9457ec57c2ec14..62ed5e0c859bc794900cd1e38a5ee60a9494289e 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -3857,7 +3857,7 @@ void QQuickItem::polish() Q_D(QQuickItem); if (!d->polishScheduled) { d->polishScheduled = true; - if (d->window) { + if (d->window && (isVisible() || (d->extra.isAllocated() && d->extra->effectRefCount>0))) { QQuickWindowPrivate *p = QQuickWindowPrivate::get(d->window); bool maybeupdate = p->itemsToPolish.isEmpty(); p->itemsToPolish.insert(this); @@ -5241,6 +5241,8 @@ bool QQuickItemPrivate::setEffectiveVisibleRecur(bool newEffectiveVisible) QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window); if (windowPriv->mouseGrabberItem == q) q->ungrabMouse(); + if (polishScheduled) + windowPriv->itemsToPolish.insert(q); } bool childVisibilityChanged = false; diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index bc8558e1d8580048bc7b221f28dbae02dd991128..7f62267859d90e28b9f898a7c1621d1824c97489 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -258,23 +258,16 @@ void QQuickWindowPrivate::polishItems() { int maxPolishCycles = 100000; - int removedItems; - do { - removedItems = 0; + while (!itemsToPolish.isEmpty() && --maxPolishCycles > 0) { QSet<QQuickItem *> itms = itemsToPolish; + itemsToPolish.clear(); for (QSet<QQuickItem *>::iterator it = itms.begin(); it != itms.end(); ++it) { QQuickItem *item = *it; - QQuickItemPrivate *itemPrivate = QQuickItemPrivate::get(item); - - if (item->isVisible() || (itemPrivate->extra.isAllocated() && itemPrivate->extra->effectRefCount>0)) { - itemPrivate->polishScheduled = false; - itemsToPolish.remove(item); - item->updatePolish(); - ++removedItems; - } + QQuickItemPrivate::get(item)->polishScheduled = false; + item->updatePolish(); } - } while (removedItems > 0 && --maxPolishCycles > 0); + } if (maxPolishCycles == 0) qWarning("QQuickWindow: possible QQuickItem::polish() loop"); diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index f4f237418353caa84e9f98bdd069285a9164de64..efe9266d0a53d50672b22e380fbd2b9a27dfd612 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -40,11 +40,13 @@ ****************************************************************************/ #include <qtest.h> +#include <qsignalspy.h> #include <QtQuick/qquickitem.h> #include <QtQuick/qquickwindow.h> #include <QtQuick/qquickview.h> #include "private/qquickfocusscope_p.h" +#include "private/qquickwindow_p.h" #include "private/qquickitem_p.h" #include <qpa/qwindowsysteminterface.h> #include <QDebug> @@ -156,6 +158,8 @@ private slots: void touchEventAcceptIgnore(); void polishOutsideAnimation(); void polishOnCompleted(); + void polishLaterWhenVisible(); + void polishWhenOtherHidden(); void wheelEvent_data(); void wheelEvent(); @@ -1396,6 +1400,63 @@ void tst_qquickitem::polishOnCompleted() QTRY_VERIFY(item->wasPolished); } +void tst_qquickitem::polishLaterWhenVisible() +{ + QQuickWindow window; + QQuickWindowPrivate *wp = QQuickWindowPrivate::get(&window); + window.resize(200, 200); + window.show(); + QTest::qWaitForWindowExposed(&window); + + TestPolishItem *item = new TestPolishItem(window.contentItem()); + item->setSize(QSizeF(200, 100)); + item->setVisible(false); + item->polish(); + + QVERIFY(!wp->itemsToPolish.contains(item)); + window.grabWindow(); // trigger QQuickWindowPrivate::polishItems() + QVERIFY(!item->wasPolished); + + item->setVisible(true); + QVERIFY(wp->itemsToPolish.contains(item)); + window.grabWindow(); // trigger QQuickWindowPrivate::polishItems() + QVERIFY(item->wasPolished); + QVERIFY(!wp->itemsToPolish.contains(item)); +} + +void tst_qquickitem::polishWhenOtherHidden() +{ + QQuickWindow window; + QQuickWindowPrivate *wp = QQuickWindowPrivate::get(&window); + window.resize(200, 200); + window.show(); + QTest::qWaitForWindowExposed(&window); + + // a hidden item pending for polish... + TestPolishItem *hiddenItem = new TestPolishItem(window.contentItem()); + hiddenItem->setSize(QSizeF(200, 100)); + hiddenItem->setVisible(false); + hiddenItem->polish(); + + QVERIFY(!wp->itemsToPolish.contains(hiddenItem)); + window.grabWindow(); // trigger QQuickWindowPrivate::polishItems() + QVERIFY(!hiddenItem->wasPolished); + + // ...should not block a visible item from being polished + TestPolishItem *visibleItem = new TestPolishItem(window.contentItem()); + visibleItem->setSize(QSizeF(200, 100)); + visibleItem->setVisible(true); + visibleItem->polish(); + + QVERIFY(wp->itemsToPolish.contains(visibleItem)); + QVERIFY(!wp->itemsToPolish.contains(hiddenItem)); + window.grabWindow(); // trigger QQuickWindowPrivate::polishItems() + QVERIFY(visibleItem->wasPolished); + QVERIFY(!hiddenItem->wasPolished); + QVERIFY(!wp->itemsToPolish.contains(visibleItem)); + QVERIFY(!wp->itemsToPolish.contains(hiddenItem)); +} + void tst_qquickitem::wheelEvent_data() { QTest::addColumn<bool>("visible");