From kde-commits Wed Sep 24 20:36:12 2008 From: Germain Garand Date: Wed, 24 Sep 2008 20:36:12 +0000 To: kde-commits Subject: branches/KDE/4.1/kdelibs/khtml Message-Id: <1222288572.093602.413.nullmailer () svn ! kde ! org> X-MARC-Message: https://marc.info/?l=kde-commits&m=122228860711359 SVN commit 864470 by ggarand: automatically merged revision 864463: introduce some heavy hacks to avoid QWidget::scroll's performance bug on unpatched Qt. BUG: 167739 M +102 -1 khtmlview.cpp --- branches/KDE/4.1/kdelibs/khtml/khtmlview.cpp #864469:864470 @@ -95,6 +95,7 @@ //#define DEBUG_FLICKER //#define DEBUG_PIXEL +#define FIX_QT_BROKEN_QWIDGET_SCROLL #include #ifdef Q_WS_X11 @@ -243,6 +244,14 @@ smoothScrolling = false; smoothScrollModeIsDefault = true; shouldSmoothScroll = false; +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + oldVScrollUpdatesEnabled = true; + oldHScrollUpdatesEnabled = true; + oldHScrollOpaquePE = false; + oldVScrollOpaquePE = false; + brokenQWidgetScroll = false; + shouldBeBlitting = false; +#endif complete = false; firstLayoutPending = true; firstRepaintPending = true; @@ -314,6 +323,22 @@ smoothScrolling = true; smoothScrollTimer.start(sSmoothScrollTick); shouldSmoothScroll = false; +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (view->horizontalScrollBar()->isVisible() && view->verticalScrollBar()->isVisible()) { + if (!dx) { + oldHScrollOpaquePE = view->horizontalScrollBar()->parentWidget()->testAttribute( Qt::WA_OpaquePaintEvent ); + view->horizontalScrollBar()->parentWidget()->setAttribute( Qt::WA_OpaquePaintEvent ); + oldHScrollUpdatesEnabled = view->horizontalScrollBar()->parentWidget()->updatesEnabled(); + view->horizontalScrollBar()->parentWidget()->setUpdatesEnabled( false ); + } + if (!dy) { + oldVScrollOpaquePE = view->verticalScrollBar()->parentWidget()->testAttribute( Qt::WA_OpaquePaintEvent ); + view->verticalScrollBar()->parentWidget()->setAttribute( Qt::WA_OpaquePaintEvent ); + oldVScrollUpdatesEnabled = view->verticalScrollBar()->parentWidget()->updatesEnabled(); + view->verticalScrollBar()->parentWidget()->setUpdatesEnabled( false ); + } + } +#endif } void stopScrolling() @@ -326,6 +351,16 @@ updateContentsXY(); smoothScrolling = false; shouldSmoothScroll = false; +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (!oldHScrollOpaquePE && view->horizontalScrollBar()->parentWidget()->testAttribute( Qt::WA_OpaquePaintEvent )) + view->horizontalScrollBar()->parentWidget()->setAttribute( Qt::WA_OpaquePaintEvent, false ); + if (!oldVScrollOpaquePE && view->verticalScrollBar()->parentWidget()->testAttribute( Qt::WA_OpaquePaintEvent )) + view->verticalScrollBar()->parentWidget()->setAttribute( Qt::WA_OpaquePaintEvent, false ); + if (!view->horizontalScrollBar()->parentWidget()->updatesEnabled() && oldHScrollUpdatesEnabled) + view->horizontalScrollBar()->parentWidget()->setUpdatesEnabled( true ); + if (!view->verticalScrollBar()->parentWidget()->updatesEnabled() && oldVScrollUpdatesEnabled) + view->verticalScrollBar()->parentWidget()->setUpdatesEnabled( true ); +#endif } void updateContentsXY() @@ -400,6 +435,14 @@ bool smoothScrolling :1; bool smoothScrollModeIsDefault :1; bool shouldSmoothScroll :1; +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + bool oldHScrollUpdatesEnabled :1; + bool oldVScrollUpdatesEnabled :1; + bool oldHScrollOpaquePE :1; + bool oldVScrollOpaquePE :1; + bool brokenQWidgetScroll :1; + bool shouldBeBlitting :1; +#endif bool complete :1; bool firstLayoutPending :1; bool firstRepaintPending :1; @@ -686,6 +729,10 @@ widget()->resize(w, h); if (!widget()->isVisible()) updateScrollBars(); +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (!horizontalScrollBar()->isVisible() || !verticalScrollBar()->isVisible()) + d->brokenQWidgetScroll = false; +#endif } int KHTMLView::contentsX() const @@ -874,6 +921,13 @@ if (!r.isValid() || r.isEmpty()) return; +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (d->shouldBeBlitting && r.width() == v.width() && r.height() == v.height()) { + d->brokenQWidgetScroll = true; + } + d->shouldBeBlitting = false; +#endif + if (d->haveZoom()) { p.scale( d->zoomLevel/100., d->zoomLevel/100.); @@ -3852,6 +3906,17 @@ w = v->widget(); } +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + bool hideScrollBars = false; + if (horizontalScrollBar()->isVisible() && verticalScrollBar()->isVisible()) { + if (!d->brokenQWidgetScroll) { + d->shouldBeBlitting = true; + } else { + hideScrollBars = true; + } + } +#endif + if ( d->staticWidget ) { // now remove from view the external widgets that must have completely @@ -3861,10 +3926,20 @@ if ( d->staticWidget == KHTMLViewPrivate::SBPartial && m_part->xmlDocImpl() && m_part->xmlDocImpl()->renderer() ) { +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (hideScrollBars) { + horizontalScrollBar()->parentWidget()->lower(); + verticalScrollBar()->parentWidget()->lower(); + } +#endif // static objects might be selectively repainted, like stones in flowing water QRegion r = static_cast(m_part->xmlDocImpl()->renderer())->staticRegion(); r.translate( -contentsX(), -contentsY()); QVector ar = r.rects(); +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (ar.size() == 1 && ar[0].width() >= visibleWidth() && ar[0].height() >= visibleHeight()) + d->shouldBeBlitting = false; +#endif for (int i = 0; i < ar.size() ; ++i) { widget()->update( ar[i] ); } @@ -3873,19 +3948,45 @@ for (int i = 0; i < ar.size() ; ++i) { w->scroll( dx, dy, ar[i].translated(off) ); } +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (hideScrollBars) { + horizontalScrollBar()->parentWidget()->raise(); + verticalScrollBar()->parentWidget()->raise(); + } +#endif d->scrollExternalWidgets(dx, dy); - } else + } else { +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + d->shouldBeBlitting = false; +#endif // we can't avoid a full update widget()->update(); + } return; } if (d->firstRepaintPending) return; + +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (hideScrollBars) { + horizontalScrollBar()->parentWidget()->lower(); + verticalScrollBar()->parentWidget()->lower(); + } +#endif + if (m_kwp->isRedirected()) { w->scroll(dx, dy, QRect(off.x(), off.y(), visibleWidth(), visibleHeight())); } else { widget()->scroll(dx, dy, widget()->rect() & viewport()->rect()); } + +#ifdef FIX_QT_BROKEN_QWIDGET_SCROLL + if (hideScrollBars) { + horizontalScrollBar()->parentWidget()->raise(); + verticalScrollBar()->parentWidget()->raise(); + } +#endif + d->scrollExternalWidgets(dx, dy); }