diff options
author | Błażej Szczygieł <spaz16@wp.pl> | 2017-11-10 23:52:17 +0100 |
---|---|---|
committer | Błażej Szczygieł <spaz16@wp.pl> | 2018-04-17 06:32:52 +0000 |
commit | 5b09346cf4322704a866f253b911d467c40df3ba (patch) | |
tree | 0b61b5548ac8dae08609bd349d241b2bc1f16f35 /src/widgets/kernel/qwidget.cpp | |
parent | 98ad498a46471d43a745cc61fd53e08e8a6b56dc (diff) |
Widgets: Use accelerated scroll when scrolled widget is overlapped
Get region of overlapped widgets and scroll only non-overlapped parts
of image. Next, schedule an update for overlapped widgets region.
This patch improves scrolling performance when scrolled widget has
overlapped widgets.
Common use cases:
- faster scrolling when using "StyleHint::SH_ScrollBar_Transient",
- faster scrolling of zoomed image with semi-transparent thumbnail.
Accelerated scrolling with overlapped widgets is not available when
scale factor is non-integer.
Task-number: QTBUG-64504
Change-Id: I8337d3bc756e50f7d31cdc7979ccf86dc5c3695f
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/widgets/kernel/qwidget.cpp')
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 8e3263ad92..6b3fad6b5f 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1904,19 +1904,21 @@ void QWidgetPrivate::deleteTLSysExtra() } /* - Returns \c true if there are widgets above this which overlap with + Returns \c region of widgets above this which overlap with \a rect, which is in parent's coordinate system (same as crect). */ -bool QWidgetPrivate::isOverlapped(const QRect &rect) const +QRegion QWidgetPrivate::overlappedRegion(const QRect &rect, bool breakAfterFirst) const { Q_Q(const QWidget); const QWidget *w = q; QRect r = rect; + QPoint p; + QRegion region; while (w) { if (w->isWindow()) - return false; + break; QWidgetPrivate *pd = w->parentWidget()->d_func(); bool above = false; for (int i = 0; i < pd->children.size(); ++i) { @@ -1928,19 +1930,23 @@ bool QWidgetPrivate::isOverlapped(const QRect &rect) const continue; } - if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) { + const QRect siblingRect = sibling->d_func()->effectiveRectFor(sibling->data->crect); + if (qRectIntersects(siblingRect, r)) { const QWExtra *siblingExtra = sibling->d_func()->extra; if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect && !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) { continue; } - return true; + region += siblingRect.translated(-p); + if (breakAfterFirst) + break; } } w = w->parentWidget(); r.translate(pd->data.crect.topLeft()); + p += pd->data.crect.topLeft(); } - return false; + return region; } void QWidgetPrivate::syncBackingStore() |