diff options
author | Alexandru Croitor <alexandru.croitor@theqtcompany.com> | 2016-04-25 15:43:57 +0200 |
---|---|---|
committer | Alexandru Croitor <alexandru.croitor@theqtcompany.com> | 2016-05-30 12:35:37 +0000 |
commit | 00061b968d23d34cdbd43e0930463be06a2775b3 (patch) | |
tree | 8e4fb50d6611d10d18100e1d7210ae1f96829b84 /src/widgets/kernel | |
parent | 886086f5d39a317443018689f817e8eb8ecb0be8 (diff) |
Fix opaque texture-based widgets not being always shown.
Whenever a regular QWidget contains a child render-to-texture widget
(like a QOpenGLWidget) that is opaque (attribute
Qt::WA_OpaquePaintEvent is set) and completely covers the parent
geometry, the child widget would not be shown.
This happens because QWidgetBackingStore::doSync contains a check to
see if an opaque child completely covers its parent, in which case it
does not draw the parent, and only draws the child.
This is an issue if the widget is actually a texture-based one, because
for it to be seen on screen, the parent widget has to be redrawn with a
proper blending mask, so that the rtt widget gets properly composed
into the place where the mask is.
The fix consists in keeping the parent widget being marked dirty, in case
it has an opaque texture-based child that completely covers it. This will
force a redraw of the parent widget with a proper blending mask.
Change-Id: If1feec04b86bff2c49158b8d72f175cec252dea1
Task-number: QTBUG-52123
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/widgets/kernel')
-rw-r--r-- | src/widgets/kernel/qwidgetbackingstore.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 049ed248de..5d13fb926b 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1211,10 +1211,20 @@ void QWidgetBackingStore::doSync() // We know for sure that the widget isn't overlapped if 'isMoved' is true. if (!wd->isMoved) wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove); + + // Make a copy of the widget's dirty region, to restore it in case there is an opaque + // render-to-texture child that completely covers the widget, because otherwise the + // render-to-texture child won't be visible, due to its parent widget not being redrawn + // with a proper blending mask. + const QRegion dirtyBeforeSubtractedOpaqueChildren = wd->dirty; + // Scrolled and moved widgets must draw all children. if (!wd->isScrolled && !wd->isMoved) wd->subtractOpaqueChildren(wd->dirty, w->rect()); + if (wd->dirty.isEmpty() && wd->textureChildSeen) + wd->dirty = dirtyBeforeSubtractedOpaqueChildren; + if (wd->dirty.isEmpty()) { resetWidget(w); continue; |