Buffered QIconView. For every QIconView this patch creates a backbuffer where the image will grow up (aka will be painted) before blitting the results to the screen. This solves the konqueror flickering problems at its roots. There are some more bugs that make conqueror repaint without reason.. patches will follow. Enrico Ros --- src.orig/iconview/qiconview.cpp 2004-03-24 15:58:05.000000000 +0000 +++ src/iconview/qiconview.cpp 2004-03-30 16:23:32.521253280 +0000 @@ -211,6 +211,7 @@ QIconViewItem *currentItem, *tmpCurrentItem, *highlightedItem, *startDragItem, *pressedItem, *selectAnchor, *renamingItem; QRect *rubber; + QPixmap *backBuffer; QTimer *scrollTimer, *adjustTimer, *updateTimer, *inputTimer, *fullRedrawTimer; int rastX, rastY, spacing; @@ -2731,6 +2732,7 @@ d->currentItem = 0; d->highlightedItem = 0; d->rubber = 0; + d->backBuffer = 0; d->scrollTimer = 0; d->startDragItem = 0; d->tmpCurrentItem = 0; @@ -2883,6 +2885,8 @@ delete item; item = tmp; } + delete d->backBuffer; + d->backBuffer = 0; delete d->fm; d->fm = 0; #ifndef QT_NO_TOOLTIP @@ -4845,6 +4849,47 @@ #endif /*! + This function grabs all paintevents that otherwise would have been + processed by the QScrollView::viewportPaintEvent(). Here we use a + doublebuffer to reduce 'on-paint' flickering on QIconView + (and of course its childs). + + \sa QScrollView::viewportPaintEvent(), QIconView::drawContents() +*/ + +void QIconView::bufferedPaintEvent( QPaintEvent* pe ) +{ + QWidget* vp = viewport(); + QRect r = pe->rect() & vp->rect(); + int ex = r.x() + contentsX(); + int ey = r.y() + contentsY(); + int ew = r.width(); + int eh = r.height(); + + if ( !d->backBuffer ) + d->backBuffer = new QPixmap(vp->size()); + if ( d->backBuffer->size() != vp->size() ) { + //Resize function (with hysteesis). Uses a good compromise between memory + //consumption and speed (number) of resizes. + float newWidth = (float)vp->width(); + float newHeight = (float)vp->height(); + if ( newWidth > d->backBuffer->width() || newHeight > d->backBuffer->height() ) + { + newWidth *= 1.1892; + newHeight *= 1.1892; + d->backBuffer->resize( (int)newWidth, (int)newHeight ); + } else if ( 1.5*newWidth < d->backBuffer->width() || 1.5*newHeight < d->backBuffer->height() ) + d->backBuffer->resize( (int)newWidth, (int)newHeight ); + } + + QPainter p; + p.begin(d->backBuffer, vp); + drawContentsOffset(&p, contentsX(), contentsY(), ex, ey, ew, eh); + p.end(); + bitBlt(vp, r.x(), r.y(), d->backBuffer, r.x(), r.y(), ew, eh); +} + +/*! \reimp */ @@ -5627,7 +5676,7 @@ if ( !d->rubber ) drawDragShapes( d->oldDragPos ); } - viewportPaintEvent( (QPaintEvent*)e ); + bufferedPaintEvent( (QPaintEvent*)e ); if ( d->dragging ) { if ( !d->rubber ) drawDragShapes( d->oldDragPos ); --- src.orig/iconview/qiconview.h 2004-03-30 16:00:47.605751976 +0000 +++ src/iconview/qiconview.h 2003-05-16 13:02:38.000000000 +0000 @@ -445,6 +445,7 @@ void contentsDropEvent( QDropEvent *e ); #endif + void bufferedPaintEvent( QPaintEvent* ); void resizeEvent( QResizeEvent* e ); void keyPressEvent( QKeyEvent *e ); void focusInEvent( QFocusEvent *e );