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