About KHTMLView::scheduleRepaint
Koos Vriezen
koos.vriezen at xs4all.nl
Fri Jun 21 23:53:02 BST 2002
Hi,
I attached a patch for KHTMLView::scheduleRepaint, which does:
- replace 'QRect updateRect' with 'QValueList<QRect> pendingRects' so
rectangles don't get united when they don't intersect with each other.
- don't re-schedule an already scheduled repaint. This can cause timer
event never to get delivered, when there are a lot gif movies running
fast (see the 'Turbo gif' thread).
- schedule at a minimal time of 40 msec. This improves selecting text a
bit (particularly on remote X desktops).
Any comments?
Regards,
Koos Vriezen
-------------- next part --------------
Index: khtmlview.cpp
===================================================================
RCS file: /home/kde/kdelibs/khtml/khtmlview.cpp,v
retrieving revision 1.473
diff -u -3 -p -r1.473 khtmlview.cpp
--- khtmlview.cpp 2002/06/14 08:11:36 1.473
+++ khtmlview.cpp 2002/06/21 22:41:18
@@ -50,6 +50,7 @@
#include <qtooltip.h>
#include <qpainter.h>
#include <qpaintdevicemetrics.h>
+#include <qvaluelist.h>
#include <kapplication.h>
#include <kimageio.h>
@@ -142,7 +143,6 @@ public:
complete = false;
firstRelayout = true;
layoutSchedulingEnabled = true;
- updateRect = QRect();
}
QPainter *tp;
@@ -177,7 +177,7 @@ public:
bool complete;
bool firstRelayout;
bool layoutSchedulingEnabled;
- QRect updateRect;
+ QValueList<QRect> pendingRects;
KHTMLToolTip *tooltip;
};
@@ -1457,7 +1457,8 @@ void KHTMLView::timerEvent ( QTimerEvent
d->timerId = 0;
//scheduleRepaint(contentsX(),contentsY(),visibleWidth(),visibleHeight());
- d->updateRect = QRect(contentsX(),contentsY(),visibleWidth(),visibleHeight());
+ d->pendingRects.clear();
+ d->pendingRects.push_back(QRect(contentsX(),contentsY(),visibleWidth(),visibleHeight()));
}
if( m_part->xmlDocImpl() ) {
@@ -1476,9 +1477,13 @@ void KHTMLView::timerEvent ( QTimerEvent
// kdDebug() << "scheduled repaint "<< d->repaintTimerId << endl;
killTimer(d->repaintTimerId);
- updateContents( d->updateRect );
-
d->repaintTimerId = 0;
+ QValueList<QRect>::iterator it = d->pendingRects.begin();
+ for (; it != d->pendingRects.end(); it = d->pendingRects.begin()) {
+ updateContents(*it);
+ d->pendingRects.pop_front();
+ }
+
}
void KHTMLView::scheduleRelayout()
@@ -1513,7 +1518,7 @@ void KHTMLView::scheduleRepaint(int x, i
// if complete...
if (d->complete)
// ...repaint immediatly
- time = 0;
+ time = 40;
else
{
if (parsing)
@@ -1522,16 +1527,38 @@ void KHTMLView::scheduleRepaint(int x, i
else
// not complete, not parsing, extend the timer if it exists
// otherwise, repaint immediatly
- time = d->repaintTimerId ? 400 : 0;
+ time = d->repaintTimerId ? 400 : 40;
}
- if (d->repaintTimerId) {
- killTimer(d->repaintTimerId);
- d->updateRect = d->updateRect.unite(QRect(x,y,w,h));
- } else
- d->updateRect = QRect(x,y,w,h);
+ QRect r = QRect(x,y,w,h);
+ QValueList<QRect>::iterator insert = d->pendingRects.end();
+ QValueList<QRect>::iterator replaced = d->pendingRects.end();
+ QValueList<QRect>::iterator remove = d->pendingRects.end();
+ QValueList<QRect>::iterator it = d->pendingRects.begin();
+ for (; it != d->pendingRects.end(); it++) {
+ if (r.intersects(*it)) {
+ r = r.unite(*it);
+ if (replaced == d->pendingRects.end())
+ replaced = it;
+ else {
+ if (remove != d->pendingRects.end())
+ d->pendingRects.erase(remove);
+ remove = it;
+ }
+ *replaced = r;
+ } else if ((*it).y() > y)
+ insert = it;
+ if (y + h <= (*it).y()) {
+ break;
+ }
+ }
+ if (replaced == d->pendingRects.end())
+ d->pendingRects.insert(insert, r);
+ else if (remove != d->pendingRects.end())
+ d->pendingRects.erase(remove);
- d->repaintTimerId = startTimer( time );
+ if (!d->repaintTimerId)
+ d->repaintTimerId = startTimer( time );
// kdDebug() << "starting timer " << time << endl;
}
More information about the kfm-devel
mailing list