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

[REGRESSION] Widgets not rendered correctly if QGraphicsDropShadowEffect assigned (5.2.1 regression)

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P2: Important
    • 5.12.6
    • 5.3.0, 5.3.1, 5.3.2, 5.4.0, 5.4.1, 5.4.2, 5.5.0, 5.5.1, 5.6.0
    • None
    • Windows, msvc2012, msvc2013

    Description

      The attached example application demonstrates use case. The attached screenshots demonstrate difference between 5.2.1 and 5.4.0.
      Run app. Click on button 2 or 3 or 5 or 6. Even without clicking QTabWidget rendered incorrectly.
      If sibling widgets have assigned QGraphicsDropShadowEffect they're not drawn starting from Qt 5.3.0 release. After little investigation I found outthere is regression introduced in commit https://qt.gitorious.org/qt/qtbase/commit/071098b08b12fc1af6341ff6d7ba6713e5de1481
      To generate a pixmap QGraphicsDropShadowEffect use QWidgetEffectSourcePrivate::pixmap(). This method calls m_widget->render(&pixmap, pixmapOffset, QRegion(), QWidget::DrawChildren).
      In 5.2.1 this method called QWidgetPrivate::render() which do not set any sharedPainter.
      But in Qt version >= 5.3.0 that method calls another version of QWidget::render() which sets a sharedPainter.
      As you can see in QWidgetPrivate::drawWidget there is checking for valid sharedPainter and now there is such sharedPainter so there is drawing of siblings with offset.

      void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
                                      QPainter *sharedPainter, QWidgetBackingStore *backingStore)
      {
          if (rgn.isEmpty())
              return;
      
          const bool asRoot = flags & DrawAsRoot;
          bool onScreen = paintOnScreen();
      
          Q_Q(QWidget);
      #ifndef QT_NO_GRAPHICSEFFECT
          if (graphicsEffect && graphicsEffect->isEnabled()) {
              QGraphicsEffectSource *source = graphicsEffect->d_func()->source;
              QWidgetEffectSourcePrivate *sourced = static_cast<QWidgetEffectSourcePrivate *>
                                                               (source->d_func());
              if (!sourced->context) {
                  QWidgetPaintContext context(pdev, rgn, offset, flags, sharedPainter, backingStore);
                  sourced->context = &context;
                  if (!sharedPainter) {
                      setSystemClip(pdev, rgn.translated(offset)); //in Qt 5.2.1 this branch always executed when QGraphicsDropShadowEffect used
                      QPainter p(pdev);
                      p.translate(offset);
                      context.painter = &p;
                      graphicsEffect->draw(&p);
                      setSystemClip(pdev, QRegion());
                  } else {
                      context.painter = sharedPainter; //in Qt >= 5.3.0 this branch executed
                      if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
                          sourced->invalidateCache();
                          sourced->lastEffectTransform = sharedPainter->worldTransform();
                      }
                      sharedPainter->save();
                      sharedPainter->translate(offset); // <-------- here may be a problem
                      graphicsEffect->draw(sharedPainter);
                      sharedPainter->restore();
                  }
                  sourced->context = 0;
      

      Attachments

        1. example.zip
          3 kB
        2. qt5.2.1.png
          qt5.2.1.png
          15 kB
        3. qt5.4.png
          qt5.4.png
          12 kB
        4. QTBUG-44355.zip
          3 kB
        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            esabraha Eskil Abrahamsen Blomfeldt
            auric Igor Lifanov
            Votes:
            8 Vote for this issue
            Watchers:
            10 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes