Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-13104

QWS Windows partially on screen cause unnecessary paint events

    XMLWordPrintable

Details

    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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            Unassigned Unassigned
            janichol Andy Nichols
            Votes:
            1 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes