diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-10-28 11:39:33 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2009-10-28 12:56:27 (GMT) |
commit | 992f5cef19ce9e313dd06279c47d7535c6dbc857 (patch) | |
tree | 103307bcde9d893ce7d5cefb866c33dd5e1ec359 /src | |
parent | f62e0f8323304b2afbf2e3b918d611ea1d0f6856 (diff) | |
download | Qt-992f5cef19ce9e313dd06279c47d7535c6dbc857.zip Qt-992f5cef19ce9e313dd06279c47d7535c6dbc857.tar.gz Qt-992f5cef19ce9e313dd06279c47d7535c6dbc857.tar.bz2 |
Wrong caching of opaque children in QWidget.
The opaque children cache was clipped to all the ancestors up to the
top-level, which means whenever a widget changes geometry all the
children must be invalidated. However, the bug was that we didn't
invalidate the children, and that is of course slow so we don't want
to do it either. A better solution is to only clip the children cache to the
widget itself (widget->rect() instead of widget->clipRect()), and we can
perfectly do this because the region we subtract the opaque children from is
already inside the clipRect().
Auto-test included.
Task-number: QTBUG-4245 (related to)
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 22 | ||||
-rw-r--r-- | src/gui/kernel/qwidget_p.h | 1 |
2 files changed, 9 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(); |