Fix issue where revealed widget children do not receive paint event.

When a child of a widget is spontaneously revealed due to a call to
the parent 'resize' method, the child will not receive a paint event
if it has the WA_StaticContents and WA_OpaquePaintEvent flags set.

This is caused by the backing store being pre-emptively resized by the
call to setGeometry_sys, which causes QWidgetBackingStore::sync to skip
the block which handles the static contents.

There doesn't appear to be any reason to preemptively resize the backing
store, since it is always resized as-needed during the the 'sync' method.
This change-set removes the code which preemptively resizes the backing
store.

Task-number: QTBUG-35282
Change-Id: Ie9942854ca5322dfe0f98ed8100810161576be80
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
Reviewed-by: Laszlo Agocs <laszlo.agocs@digia.com>
This commit is contained in:
Chris Colbert 2013-12-01 16:47:30 -05:00 committed by The Qt Project
parent 26cf0f0d5a
commit 6060dab13a
3 changed files with 25 additions and 13 deletions

View File

@ -549,12 +549,6 @@ void QWidgetPrivate::show_sys()
window->resize(geomRect.size()); window->resize(geomRect.size());
} }
if (QBackingStore *store = q->backingStore()) {
if (store->size() != geomRect.size()) {
store->resize(geomRect.size());
}
}
#ifndef QT_NO_CURSOR #ifndef QT_NO_CURSOR
qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show qt_qpa_set_cursor(q, false); // Needed in case cursor was set before show
#endif #endif
@ -762,11 +756,6 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove)
QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint()); QPoint posInNativeParent = q->mapTo(q->nativeParentWidget(),QPoint());
q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size())); q->windowHandle()->setGeometry(QRect(posInNativeParent,r.size()));
} }
const QWidgetBackingStore *bs = maybeBackingStore();
if (bs && bs->store) {
if (isResize)
bs->store->resize(r.size());
}
if (needsShow) if (needsShow)
show_sys(); show_sys();

View File

@ -940,7 +940,7 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
} }
// Nothing to repaint. // Nothing to repaint.
if (!isDirty()) { if (!isDirty() && store->size().isValid()) {
qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTextures); qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTextures);
return; return;
} }
@ -1035,7 +1035,7 @@ void QWidgetBackingStore::doSync()
const QRect tlwRect(topLevelRect()); const QRect tlwRect(topLevelRect());
const QRect surfaceGeometry(tlwRect.topLeft(), store->size()); const QRect surfaceGeometry(tlwRect.topLeft(), store->size());
if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) { if ((fullUpdatePending || inTopLevelResize || surfaceGeometry.size() != tlwRect.size()) && !updatesDisabled) {
if (hasStaticContents()) { if (hasStaticContents() && !store->size().isEmpty() ) {
// Repaint existing dirty area and newly visible area. // Repaint existing dirty area and newly visible area.
const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height()); const QRect clipRect(0, 0, surfaceGeometry.width(), surfaceGeometry.height());
const QRegion staticRegion(staticContents(0, clipRect)); const QRegion staticRegion(staticContents(0, clipRect));

View File

@ -441,6 +441,8 @@ private slots:
void mouseDoubleClickBubbling_QTBUG29680(); void mouseDoubleClickBubbling_QTBUG29680();
void largerThanScreen_QTBUG30142(); void largerThanScreen_QTBUG30142();
void resizeStaticContentsChildWidget_QTBUG35282();
private: private:
bool ensureScreenSize(int width, int height); bool ensureScreenSize(int width, int height);
QWidget *testWidget; QWidget *testWidget;
@ -10220,5 +10222,26 @@ void tst_QWidget::largerThanScreen_QTBUG30142()
QVERIFY(widget2.frameGeometry().x() >= 0); QVERIFY(widget2.frameGeometry().x() >= 0);
} }
void tst_QWidget::resizeStaticContentsChildWidget_QTBUG35282()
{
QWidget widget;
widget.resize(200,200);
UpdateWidget childWidget(&widget);
childWidget.setAttribute(Qt::WA_StaticContents);
childWidget.setAttribute(Qt::WA_OpaquePaintEvent);
childWidget.setGeometry(250, 250, 500, 500);
widget.show();
QVERIFY(QTest::qWaitForWindowExposed(&widget));
QVERIFY(childWidget.numPaintEvents == 0);
childWidget.reset();
widget.resize(1000,1000);
QVERIFY(QTest::qWaitForWindowExposed(&widget));
QGuiApplication::sync();
QVERIFY(childWidget.numPaintEvents >= 1);
}
QTEST_MAIN(tst_QWidget) QTEST_MAIN(tst_QWidget)
#include "tst_qwidget.moc" #include "tst_qwidget.moc"