revive the noPaintOnScreen fix on Windows

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>
This commit is contained in:
Joerg Bornemann 2012-07-03 12:19:38 +02:00 committed by Qt by Nokia
parent 8ccab9b029
commit 3037525530
3 changed files with 28 additions and 5 deletions

View File

@ -267,10 +267,12 @@ QWidgetPrivate::QWidgetPrivate(int version)
#ifndef QT_NO_IM #ifndef QT_NO_IM
, inheritsInputMethodHints(0) , inheritsInputMethodHints(0)
#endif #endif
#if defined(Q_OS_WIN)
, noPaintOnScreen(0)
#endif
#if defined(Q_WS_X11) #if defined(Q_WS_X11)
, picture(0) , picture(0)
#elif defined(Q_WS_WIN) #elif defined(Q_WS_WIN)
, noPaintOnScreen(0)
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
, nativeGesturePanEnabled(0) , nativeGesturePanEnabled(0)
#endif #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), Q_ASSERT_X(sizeof(d->high_attributes)*8 >= (Qt::WA_AttributeCount - sizeof(uint)*8),
"QWidget::setAttribute(WidgetAttribute, bool)", "QWidget::setAttribute(WidgetAttribute, bool)",
"QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute"); "QWidgetPrivate::high_attributes[] too small to contain all attributes in WidgetAttribute");
#ifdef Q_WS_WIN #ifdef Q_OS_WIN
// ### Don't use PaintOnScreen+paintEngine() to do native painting in 5.0 // ### Don't use PaintOnScreen+paintEngine() to do native painting in some future release
if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) { if (attribute == Qt::WA_PaintOnScreen && on && !inherits("QGLWidget")) {
// see qwidget_win.cpp, ::paintEngine for details // see qwidget_qpa.cpp, ::paintEngine for details
paintEngine(); paintEngine();
if (d->noPaintOnScreen) if (d->noPaintOnScreen)
return; return;

View File

@ -694,6 +694,9 @@ public:
#endif #endif
// *************************** Platform specific ************************************ // *************************** Platform specific ************************************
#if defined(Q_OS_WIN)
uint noPaintOnScreen : 1; // see qwidget_qpa.cpp ::paintEngine()
#endif
#if defined(Q_WS_X11) // <----------------------------------------------------------- X11 #if defined(Q_WS_X11) // <----------------------------------------------------------- X11
Qt::HANDLE picture; Qt::HANDLE picture;
static QWidget *mouseGrabber; static QWidget *mouseGrabber;
@ -708,7 +711,6 @@ public:
QPoint mapToGlobal(const QPoint &pos) const; QPoint mapToGlobal(const QPoint &pos) const;
QPoint mapFromGlobal(const QPoint &pos) const; QPoint mapFromGlobal(const QPoint &pos) const;
#elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN #elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN
uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine()
#ifndef QT_NO_GESTURES #ifndef QT_NO_GESTURES
uint nativeGesturePanEnabled : 1; uint nativeGesturePanEnabled : 1;
#endif #endif

View File

@ -980,6 +980,25 @@ void QWidgetPrivate::setWSGeometry(bool dontShow, const QRect &oldRect)
QPaintEngine *QWidget::paintEngine() const QPaintEngine *QWidget::paintEngine() const
{ {
qWarning("QWidget::paintEngine: Should no longer be called"); 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; //##### @@@ return 0; //##### @@@
} }