diff options
author | Eirik Aavitsland <eirik.aavitsland@qt.io> | 2022-04-06 20:26:29 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2022-04-07 18:40:07 +0000 |
commit | 8c4f8ca931bf64e877f991547732c024d2b6cecc (patch) | |
tree | 5d6df169b6d5192d089a6e5db6a88a3bfc215e26 | |
parent | 388f959080c0c09ef7110f340f3e6a1799df4487 (diff) |
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
Change-Id: I9ccd4ee54660419a1db8c27358f1419de58ae932
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit f5174abec3720b7deec3157e482ca62c0d90fb19)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/gui/painting/qbackingstore.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index 762938e764..5b4faf1c80 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -227,8 +227,18 @@ void QBackingStore::flush(const QRegion ®ion, 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); } /*! |