Bug 145948 - Paint glitch when resizing KHTML window (gray block)
Summary: Paint glitch when resizing KHTML window (gray block)
Status: RESOLVED WORKSFORME
Alias: None
Product: konqueror
Classification: Applications
Component: khtml (show other bugs)
Version: 4.0
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: Konqueror Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-05-25 15:10 UTC by Thomas McGuire
Modified: 2008-04-21 14:34 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas McGuire 2007-05-25 15:10:15 UTC
Version:           SVN trunk (using KDE Devel)
Installed from:    Compiled sources
OS:                Linux

If you resize the KHTML area, a gray block will appear at the 
bottom of that area.

To reproduce, open Konqueror at www.kde.org, scroll to the bottom, and 
vertically enlarge the window (at the bottom). Now you should see a gray 
block.
Same with the messageviewer in KMail or the chat window in Kopete.

See also http://lists.kde.org/?l=kfm-devel&m=118000495330438&w=2.

This happens only in KDE4.
Comment 1 Germain Garand 2007-05-28 19:23:57 UTC
SVN commit 669159 by ggarand:

Adapt to Qt 4.3's renewed lack of forgiveness.

It is now mandatory to end any QPainter active on devices 
that are the target of a redirection, which in turn forces the 
unwinding of the stack, making save()/restore() useless.

=> reimplement save/restore for clipping ;(

BUG: 145948



 M  +25 -10    render_layer.cpp  
 M  +2 -0      render_layer.h  
 M  +7 -1      render_replaced.cpp  


--- trunk/KDE/kdelibs/khtml/rendering/render_layer.cpp #669158:669159
@@ -60,11 +60,13 @@
 #include "xml/dom_restyler.h"
 
 #include <QtGui/QStyle>
+#include <QtCore/QStack>
 
 using namespace DOM;
 using namespace khtml;
 
 ScrollBarWidget* RenderLayer::gScrollBar = 0;
+QStack<QRegion>* RenderLayer::s_clipHolder = 0;
 
 #ifndef NDEBUG
 static bool inRenderLayerDetach;
@@ -815,30 +817,37 @@
     paintLayer(this, p, damageRect, selectionOnly);
 }
 
-static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
+static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect, bool setup = false)
 {
     if (paintDirtyRect == clipRect)
         return;
-    p->save();
+    if (!RenderLayer::s_clipHolder)
+        RenderLayer::s_clipHolder = new QStack<QRegion>;
 
-#ifdef APPLE_CHANGES
-    p->addClip(clipRect);
-#else
-    p->setClipRect(clipRect, Qt::IntersectClip);
-#endif
-
+    QRegion r = clipRect;
+    if (!RenderLayer::s_clipHolder->isEmpty())
+        r &= RenderLayer::s_clipHolder->top();
+    
+    p->setClipRegion( r );
+    RenderLayer::s_clipHolder->push( r );
 }
 
-static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect)
+static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect, bool cleanup = false)
 {
     if (paintDirtyRect == clipRect)
         return;
-    p->restore();
+    RenderLayer::s_clipHolder->pop();
+    if (!RenderLayer::s_clipHolder->isEmpty())
+        p->setClipRegion( RenderLayer::s_clipHolder->top() );
+    else
+        p->setClipRegion( QRegion(), Qt::NoClip );
 }
 
 void RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p,
                         const QRect& paintDirtyRect, bool selectionOnly)
 {
+    assert( rootLayer != this || !s_clipHolder );
+
     // Calculate the clip rects we should use.
     QRect layerBounds, damageRect, clipRectToApply;
     calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply);
@@ -951,6 +960,12 @@
     // End our transparency layer
     if (isTransparent())
         p->setOpacity(previousOpacity);
+
+    if (s_clipHolder && rootLayer == this) {
+        assert(s_clipHolder->isEmpty());
+        delete s_clipHolder;
+        s_clipHolder = 0;
+    }
 }
 
 bool RenderLayer::nodeAtPoint(RenderObject::NodeInfo& info, int x, int y)
--- trunk/KDE/kdelibs/khtml/rendering/render_layer.h #669158:669159
@@ -51,6 +51,7 @@
 #include "render_object.h"
 
 //template <class T*> class QVector;
+template <class T> class QStack;
 
 namespace khtml {
     class RenderStyle;
@@ -128,6 +129,7 @@
 {
 public:
     static ScrollBarWidget* gScrollBar;
+    static QStack<QRegion>* s_clipHolder;
 
     RenderLayer(RenderObject* object);
     ~RenderLayer();
--- trunk/KDE/kdelibs/khtml/rendering/render_replaced.cpp #669158:669159
@@ -569,11 +569,17 @@
         pp.setCompositionMode(QPainter::CompositionMode_Clear);
         pp.eraseRect(r);
         d = pm;
-    }
+    } else
+        p->end();
+
     QPainter::setRedirected(widget, d, buffered ? QPoint(0,0) : -thePoint);
+
     QPaintEvent e( r );
     QApplication::sendEvent(widget, &e);
     QPainter::restoreRedirected(widget);
+
+    if (!p->isActive())
+        p->begin(p->device());
     p->setWorldMatrix( m );
 
     if (buffered) {
Comment 2 Thomas McGuire 2007-06-13 20:52:18 UTC
Reopening.
This still happens with today's SVN version.
Comment 3 FiNeX 2008-04-21 12:55:40 UTC
Cannot reproduce on konqueror 4 (trunk r797319) (qt4.4 rc1)
Comment 4 Thomas McGuire 2008-04-21 14:34:06 UTC
> Cannot reproduce on konqueror 4 (trunk r797319) (qt4.4 rc1) 
Right, seems to be fixed in the meantime.