Fix backingstore fractional DPR glitches for widgets in child windows

For such widgets, QBackingStore::flush() takes both a region and an
offset. Both must to be DPR scaled to the native backingstore
coordinates. When the DPR is fractional, it can happen that the
rounding of both effectively accumulate into an off-by-one error.
Detect and adjust for this situation to avoid painting glitches.

Task-number: QTBUG-96223
Fixes: QTBUG-102366
Pick-to: 6.3 6.2 5.15
Change-Id: I9ccd4ee54660419a1db8c27358f1419de58ae932
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
bb10
Eirik Aavitsland 2022-04-06 20:26:29 +02:00
parent 9e0ba8b927
commit f5174abec3
1 changed files with 12 additions and 2 deletions

View File

@ -220,8 +220,18 @@ void QBackingStore::flush(const QRegion &region, QWindow *window, const QPoint &
Q_ASSERT(window == topLevelWindow || topLevelWindow->isAncestorOf(window, QWindow::ExcludeTransients));
handle()->flush(window, QHighDpi::toNativeLocalRegion(region, window),
QHighDpi::toNativeLocalPosition(offset, window));
QRegion nativeRegion = QHighDpi::toNativeLocalRegion(region, window);
QPoint nativeOffset;
if (!offset.isNull()) {
nativeOffset = QHighDpi::toNativeLocalPosition(offset, window);
// Under fractional DPR, rounding of region and offset may accumulate to an off-by-one
QPoint topLeft = region.boundingRect().topLeft() + offset;
QPoint nativeTopLeft = QHighDpi::toNativeLocalPosition(topLeft, window);
QPoint diff = nativeTopLeft - (nativeRegion.boundingRect().topLeft() + nativeOffset);
Q_ASSERT(qMax(qAbs(diff.x()), qAbs(diff.y())) <= 1);
nativeRegion.translate(diff);
}
handle()->flush(window, nativeRegion, nativeOffset);
}
/*!