Details
-
Bug
-
Resolution: Out of scope
-
P3: Somewhat important
-
4.6.3
-
None
Description
If the widget is larger than the QScreen geometry an extra paintEvent is called due to the area of a widget outside of the QScreen geometry being marked dirty by the QBackingStore each time the widget is updated.
Envrironment:
Qt 4.6.3 embedded Linux.
Steps to reproduce)
1) qvfb -width 800 -height 600
2) ./example -qws
As a result, paintEvent() is called two times by one repaint(10,10,10,10).
The arrived rectangles are as follows
x y width height
-------------------------------------
qvfb - - 800 600
sample_app 0 0 1000 400
repaint rect 10 10 10 10
1st rect 10 10 10 10
2nd rect 800 0 200 400
Use the following example to reproduce:
#include <QtGui> class Widget : public QWidget { Q_OBJECT private: QTimer *timer; public: Widget() : QWidget (0) { setWindowFlags(Qt::FramelessWindowHint); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(slotRepaint())); timer->start(1000); resize(1000, 400); } protected: void paintEvent(QPaintEvent *event) { qDebug() << event->region(); } private slots: void slotRepaint() { qDebug() << "=== call repaint ====================="; repaint(QRect(10, 10, 10, 10)); } }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Widget w; w.show(); return app.exec(); } #include "main.moc"
The code at fault seems to be here:
src/gui/painting/qbackingstore.cpp:336
if (surfaceWidget->isWindow()) { if (toCleanUnclipped != toClean) { dirtyFromPreviousSync += (toCleanUnclipped - surface->clipRegion()); hasDirtyFromPreviousSync = true; } if (hasDirtyFromPreviousSync) { dirtyFromPreviousSync -= toClean; hasDirtyFromPreviousSync = !dirtyFromPreviousSync.isEmpty(); } }
Anywhere the widget is outside of the QScreen geometry will be marked as dirty each time the widget is updated.