revive the noPaintOnScreen fix on Windows
authorJoerg Bornemann <joerg.bornemann@nokia.com>
Tue, 3 Jul 2012 10:19:38 +0000 (12:19 +0200)
committerQt by Nokia <qt-info@nokia.com>
Tue, 3 Jul 2012 11:31:20 +0000 (13:31 +0200)
The original commit message follows.

Fixes:   Fix the windows PaintOnScreen issue once and for all

Details: To allow both the case where X11 people accidentally set
         PaintOnScreen (which should not have any effect on windows)
         and where people set it and subclass with paintEngine() {
         return 0 } to use GDI / DirectX we do this rather nasty hack.

Original commit in Qt4: 07a2f68bd5869152471e4ffc4a63c683ef141ae8
Autotest: tst_QWidget::paintOnScreenPossible

Change-Id: Ifbb7dc4611959be3ecc362c29a1c3436b0e0fa82
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Reviewed-by: Gunnar Sletta <gunnar.sletta@nokia.com>
src/widgets/kernel/qwidget.cpp
src/widgets/kernel/qwidget_p.h
src/widgets/kernel/qwidget_qpa.cpp

index a42fd7a..0da2841 100644 (file)
@@ -267,10 +267,12 @@ QWidgetPrivate::QWidgetPrivate(int version)
 #ifndef QT_NO_IM
       , inheritsInputMethodHints(0)
 #endif
+#if defined(Q_OS_WIN)
+      , noPaintOnScreen(0)
+#endif
 #if defined(Q_WS_X11)
       , picture(0)
 #elif defined(Q_WS_WIN)
-      , noPaintOnScreen(0)
   #ifndef QT_NO_GESTURES
       , nativeGesturePanEnabled(0)
   #endif
@@ -9939,10 +9941,10 @@ void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on)
     Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
                "QWidget::setAttribute(WidgetAttribute, bool)",
                "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
-#ifdef Q_WS_WIN
-    // ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0
+#ifdef Q_OS_WIN
+    // ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release
     if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) {
-        // see qwidget_win.cpp, ::paintEngine for details
+        // see qwidget_qpa.cpp, ::paintEngine for details
         paintEngine();
         if (d->noPaintOnScreen)
             return;
index 9036b7a..75d03f8 100644 (file)
@@ -694,6 +694,9 @@ public:
 #endif
 
     // *************************** Platform specific ************************************
+#if defined(Q_OS_WIN)
+    uint noPaintOnScreen : 1; // see qwidget_qpa.cpp ::paintEngine()
+#endif
 #if defined(Q_WS_X11) // <----------------------------------------------------------- X11
     Qt::HANDLE picture;
     static QWidget *mouseGrabber;
@@ -708,7 +711,6 @@ public:
     QPoint mapToGlobal(const QPoint &pos) const;
     QPoint mapFromGlobal(const QPoint &pos) const;
 #elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
-    uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
 #ifndef QT_NO_GESTURES
     uint nativeGesturePanEnabled : 1;
 #endif
index c524491..ef3d7a1 100644 (file)
@@ -980,6 +980,25 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
 QPaintEngine *QWidget::paintEngine() const
 {
     qWarning("QWidget::paintEngine: Should no longer be called");
+
+#ifdef Q_OS_WIN
+    // We set this bit which is checked in setAttribute for
+    // Qt::WA_PaintOnScreen. We do this to allow these two scenarios:
+    //
+    // 1. Users accidentally set Qt::WA_PaintOnScreen on X and port to
+    // Windows which would mean suddenly their widgets stop working.
+    //
+    // 2. Users set paint on screen and subclass paintEngine() to
+    // return 0, in which case we have a "hole" in the backingstore
+    // allowing use of GDI or DirectX directly.
+    //
+    // 1 is WRONG, but to minimize silent failures, we have set this
+    // bit to ignore the setAttribute call. 2. needs to be
+    // supported because its our only means of embedding native
+    // graphics stuff.
+    const_cast<QWidgetPrivate *>(d_func())->noPaintOnScreen = 1;
+#endif
+
     return 0; //##### @@@
 }