diff options
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | tests/auto/qwidget/tst_qwidget.cpp | 42 |
3 files changed, 51 insertions, 14 deletions
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 5fa9a92..1951ab2 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1825,18 +1825,6 @@ void QWidgetPrivate::setDirtyOpaqueRegion() pd->setDirtyOpaqueRegion(); } -QRegion QWidgetPrivate::getOpaqueRegion() const -{ - Q_Q(const QWidget); - - QRegion r = isOpaque ? q->rect() : getOpaqueChildren(); - if (extra && extra->hasMask) - r &= extra->mask; - if (r.isEmpty()) - return r; - return r & clipRect(); -} - const QRegion &QWidgetPrivate::getOpaqueChildren() const { if (!dirtyOpaqueChildren) @@ -1851,9 +1839,17 @@ const QRegion &QWidgetPrivate::getOpaqueChildren() const continue; const QPoint offset = child->geometry().topLeft(); - that->opaqueChildren += child->d_func()->getOpaqueRegion().translated(offset); + QWidgetPrivate *childd = child->d_func(); + QRegion r = childd->isOpaque ? child->rect() : childd->getOpaqueChildren(); + if (childd->extra && childd->extra->hasMask) + r &= childd->extra->mask; + if (r.isEmpty()) + continue; + r.translate(offset); + that->opaqueChildren += r; } + that->opaqueChildren &= q_func()->rect(); that->dirtyOpaqueChildren = false; return that->opaqueChildren; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 159a3f2..5cea641 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -386,7 +386,6 @@ public: bool paintOnScreen() const; void invalidateGraphicsEffectsRecursively(); - QRegion getOpaqueRegion() const; const QRegion &getOpaqueChildren() const; void setDirtyOpaqueRegion(); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 050d1c5..9c421d1 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -332,6 +332,7 @@ private slots: void doubleRepaint(); #ifndef Q_WS_MAC void resizeInPaintEvent(); + void opaqueChildren(); #endif void setMaskInResizeEvent(); @@ -8272,6 +8273,47 @@ void tst_QWidget::resizeInPaintEvent() // Make sure the resize triggers another update. QTRY_COMPARE(widget.numPaintEvents, 1); } + +void tst_QWidget::opaqueChildren() +{ + QWidget widget; + widget.resize(200, 200); + + QWidget child(&widget); + child.setGeometry(-700, -700, 200, 200); + + QWidget grandChild(&child); + grandChild.resize(200, 200); + + QWidget greatGrandChild(&grandChild); + greatGrandChild.setGeometry(50, 50, 200, 200); + greatGrandChild.setPalette(Qt::red); + greatGrandChild.setAutoFillBackground(true); // Opaque child widget. + + widget.show(); +#ifdef Q_WS_X11 + qt_x11_wait_for_window_manager(&widget); +#endif + QTest::qWait(100); + + // Child, grandChild and greatGrandChild are outside the ancestor clip. + QRegion expectedOpaqueRegion(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Now they are all inside the ancestor clip. + child.setGeometry(50, 50, 150, 150); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Set mask on greatGrandChild. + const QRegion mask(10, 10, 50, 50); + greatGrandChild.setMask(mask); + expectedOpaqueRegion &= mask.translated(50, 50); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), expectedOpaqueRegion); + + // Make greatGrandChild "transparent". + greatGrandChild.setAutoFillBackground(false); + QCOMPARE(qt_widget_private(&grandChild)->getOpaqueChildren(), QRegion()); +} #endif |