diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/kernel/qwidget_p.h | 1 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetrepaintmanager.cpp | 107 |
2 files changed, 28 insertions, 80 deletions
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index db458be7f1..41f343dfec 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -390,6 +390,7 @@ public: void invalidateBackingStore(const T &); QRegion overlappedRegion(const QRect &rect, bool breakAfterFirst = false) const; + bool isOverlapped(const QRect &rect) const { return !overlappedRegion(rect, true).isEmpty(); } void syncBackingStore(); void syncBackingStore(const QRegion ®ion); diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp index d9375c7281..734d3424fd 100644 --- a/src/widgets/kernel/qwidgetrepaintmanager.cpp +++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp @@ -414,25 +414,6 @@ static bool hasPlatformWindow(QWidget *widget) return widget && widget->windowHandle() && widget->windowHandle()->handle(); } -static QList<QRect> getSortedRectsToScroll(const QRegion ®ion, int dx, int dy) -{ - QList<QRect> rects; - std::copy(region.begin(), region.end(), std::back_inserter(rects)); - if (rects.count() > 1) { - std::sort(rects.begin(), rects.end(), [=](const QRect &r1, const QRect &r2) { - if (r1.y() == r2.y()) { - if (dx > 0) - return r1.x() > r2.x(); - return r1.x() < r2.x(); - } - if (dy > 0) - return r1.y() > r2.y(); - return r1.y() < r2.y(); - }); - } - return rects; -} - //parent's coordinates; move whole rect; update parent and widget //assume the screen blt has already been done, so we don't need to refresh that part void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) @@ -449,17 +430,21 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) QWidget *pw = q->parentWidget(); QPoint toplevelOffset = pw->mapTo(tlw, QPoint()); QWidgetPrivate *pd = pw->d_func(); - const QRect clipR(pd->clipRect()); + QRect clipR(pd->clipRect()); const QRect newRect(rect.translated(dx, dy)); + QRect destRect = rect.intersected(clipR); + if (destRect.isValid()) + destRect = destRect.translated(dx, dy).intersected(clipR); + const QRect sourceRect(destRect.translated(-dx, -dy)); const QRect parentRect(rect & clipR); const bool nativeWithTextureChild = textureChildSeen && hasPlatformWindow(q); - const bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild + bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild #if QT_CONFIG(graphicsview) // No accelerate move for proxy widgets. && !tlw->d_func()->extra->proxyWidget #endif - ; + && !isOverlapped(sourceRect) && !isOverlapped(destRect); if (!accelerateMove) { QRegion parentR(effectiveRectFor(parentRect)); @@ -472,50 +457,22 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) pd->invalidateBackingStore(parentR); invalidateBackingStore((newRect & clipR).translated(-data.crect.topLeft())); } else { - QRect destRect = rect.intersected(clipR); - if (destRect.isValid()) - destRect = destRect.translated(dx, dy).intersected(clipR); - const QRect sourceRect(destRect.translated(-dx, -dy)); QWidgetRepaintManager *repaintManager = x->repaintManager.get(); - QRegion childExpose = QRegion(newRect) & clipR; - QRegion overlappedExpose; + QRegion childExpose(newRect & clipR); - if (sourceRect.isValid()) { - overlappedExpose = (overlappedRegion(sourceRect) | overlappedRegion(destRect)) & clipR; - - const qreal factor = QHighDpiScaling::factor(q->windowHandle()); - if (overlappedExpose.isEmpty() || qFloor(factor) == factor) { - const QList<QRect> rectsToScroll = - getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy); - for (QRect r : rectsToScroll) { - if (repaintManager->bltRect(r, dx, dy, pw)) { - childExpose -= r.translated(dx, dy); - } - } - isMoved = true; - } - - childExpose -= overlappedExpose; - } + if (sourceRect.isValid() && repaintManager->bltRect(sourceRect, dx, dy, pw)) + childExpose -= destRect; if (!pw->updatesEnabled()) return; const bool childUpdatesEnabled = q->updatesEnabled(); - if (childUpdatesEnabled) { - // As per paintAndFlush, reset isMoved if we have overlapping - // or child regions that need to be painted. - if (!overlappedExpose.isEmpty()) { - overlappedExpose.translate(-data.crect.topLeft()); - invalidateBackingStore(overlappedExpose); - isMoved = false; - } - if (!childExpose.isEmpty()) { - childExpose.translate(-data.crect.topLeft()); - repaintManager->markDirty(childExpose, q); - isMoved = false; - } + + if (childUpdatesEnabled && !childExpose.isEmpty()) { + childExpose.translate(-data.crect.topLeft()); + repaintManager->markDirty(childExpose, q); + isMoved = true; } QRegion parentExpose(parentRect); @@ -523,10 +480,12 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) if (extra && extra->hasMask) parentExpose += QRegion(newRect) - extra->mask.translated(data.crect.topLeft()); - if (!parentExpose.isEmpty()) + if (!parentExpose.isEmpty()) { repaintManager->markDirty(parentExpose, pw); + pd->isMoved = true; + } - if (childUpdatesEnabled && sourceRect.isValid()) { + if (childUpdatesEnabled) { QRegion needsFlush(sourceRect); needsFlush += destRect; repaintManager->markNeedsFlush(pw, needsFlush, toplevelOffset); @@ -547,12 +506,13 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) static const bool accelEnv = qEnvironmentVariableIntValue("QT_NO_FAST_SCROLL") == 0; - const QRect clipR = clipRect(); - const QRect scrollRect = rect & clipR; - const bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent); + QRect scrollRect = rect & clipRect(); + bool overlapped = false; + bool accelerateScroll = accelEnv && isOpaque && !q_func()->testAttribute(Qt::WA_WState_InPaintEvent) + && !(overlapped = isOverlapped(scrollRect.translated(data.crect.topLeft()))); if (!accelerateScroll) { - if (!overlappedRegion(scrollRect.translated(data.crect.topLeft()), true).isEmpty()) { + if (overlapped) { QRegion region(scrollRect); subtractOpaqueSiblings(region); invalidateBackingStore(region); @@ -564,23 +524,12 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) const QRect destRect = scrollRect.translated(dx, dy) & scrollRect; const QRect sourceRect = destRect.translated(-dx, -dy); - const QRegion overlappedExpose = (overlappedRegion(scrollRect.translated(data.crect.topLeft()))) - .translated(-data.crect.topLeft()) & clipR; QRegion childExpose(scrollRect); - - const qreal factor = QHighDpiScaling::factor(q->windowHandle()); - if (overlappedExpose.isEmpty() || qFloor(factor) == factor) { - const QList<QRect> rectsToScroll = - getSortedRectsToScroll(QRegion(sourceRect) - overlappedExpose, dx, dy); - for (const QRect &r : rectsToScroll) { - if (repaintManager->bltRect(r, dx, dy, q)) { - childExpose -= r.translated(dx, dy); - } - } + if (sourceRect.isValid()) { + if (repaintManager->bltRect(sourceRect, dx, dy, q)) + childExpose -= destRect; } - childExpose -= overlappedExpose; - if (inDirtyList) { if (rect == q->rect()) { dirty.translate(dx, dy); @@ -597,8 +546,6 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (!q->updatesEnabled()) return; - if (!overlappedExpose.isEmpty()) - invalidateBackingStore(overlappedExpose); if (!childExpose.isEmpty()) { repaintManager->markDirty(childExpose, q); isScrolled = true; |