From 79bf1b7e348d186934b14c417859a48bf9b3a06c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Mon, 26 Aug 2019 22:08:59 +0200 Subject: widgets: Mark widgets as needing flush during painting Except for the case of syncing in response to an expose event, where the platform asked us to flush a specific region, we should strive to only flush parts that have been repainted. And we should flush those parts to their nearest native child, instead of unconditionally flushing the root/top level widget as well. By allowing drawWidget to schedule the flush we automatically flush the minimal region, to the right widgets. Change-Id: I73c143761d4a0da6991433b41dea0a0bc83a448a Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qwidget.cpp | 7 ++----- src/widgets/kernel/qwidgetrepaintmanager.cpp | 12 ++---------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'src/widgets/kernel') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 45be132e59..cf5a81c204 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -5313,9 +5313,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP } sourced->context = 0; - // Native widgets need to be marked dirty on screen so painting will be done in correct context - // Same check as in the no effects case below. - if (repaintManager && !asRoot && (q->internalWinId() || !q->nativeParentWidget()->isWindow())) + if (repaintManager) repaintManager->markNeedsFlush(q, rgn, offset); return; @@ -5422,8 +5420,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP sendPaintEvent(toBePainted); } - // Native widgets need to be marked dirty on screen so painting will be done in correct context - if (repaintManager && !asRoot && (q->internalWinId() || (q->nativeParentWidget() && !q->nativeParentWidget()->isWindow()))) + if (repaintManager) repaintManager->markNeedsFlush(q, toBePainted, offset); //restore diff --git a/src/widgets/kernel/qwidgetrepaintmanager.cpp b/src/widgets/kernel/qwidgetrepaintmanager.cpp index d1ebf7dc25..4eb298e108 100644 --- a/src/widgets/kernel/qwidgetrepaintmanager.cpp +++ b/src/widgets/kernel/qwidgetrepaintmanager.cpp @@ -979,12 +979,6 @@ void QWidgetRepaintManager::paintAndFlush() } #endif - // Always flush repainted areas. FIXME: We should mark individual widgets, - // not the top level widget unconditionally, as this results in always - // flushing the top level widget, even if the painted region is entirely - // within a native child. - markNeedsFlush(tlw, toClean, QPoint()); - store->beginPaint(toClean); // Must do this before sending any paint events because @@ -1041,8 +1035,7 @@ void QWidgetRepaintManager::markNeedsFlush(QWidget *widget, const QRegion ®io // Top-level (native) qCInfo(lcWidgetPainting) << "Marking" << region << "of top level" << widget << "as needing flush"; - if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) - topLevelNeedsFlush += region; + topLevelNeedsFlush += region; } else if (!hasPlatformWindow(widget) && !widget->isWindow()) { QWidget *nativeParent = widget->nativeParentWidget(); qCInfo(lcWidgetPainting) << "Marking" << region << "of" @@ -1050,8 +1043,7 @@ void QWidgetRepaintManager::markNeedsFlush(QWidget *widget, const QRegion ®io << "at offset" << topLevelOffset; if (nativeParent == tlw) { // Alien widgets with the top-level as the native parent (common case) - if (!widget->testAttribute(Qt::WA_WState_InPaintEvent)) - topLevelNeedsFlush += region.translated(topLevelOffset); + topLevelNeedsFlush += region.translated(topLevelOffset); } else { // Alien widgets with native parent != tlw const QPoint nativeParentOffset = widget->mapTo(nativeParent, QPoint()); -- cgit v1.2.3