summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication_p.h12
-rw-r--r--src/gui/kernel/qapplication_win.cpp128
-rw-r--r--src/gui/kernel/qgesture.cpp37
-rw-r--r--src/gui/kernel/qgesture.h8
-rw-r--r--src/gui/kernel/qgesture_p.h5
-rw-r--r--src/gui/kernel/qstandardgestures.cpp126
-rw-r--r--src/gui/kernel/qstandardgestures.h4
-rw-r--r--src/gui/kernel/qstandardgestures_p.h5
-rw-r--r--src/gui/kernel/qwidget.cpp203
-rw-r--r--src/gui/kernel/qwidget.h4
-rw-r--r--src/gui/kernel/qwidget_mac.mm8
-rw-r--r--src/gui/kernel/qwidget_p.h60
-rw-r--r--src/gui/kernel/qwidget_qws.cpp8
-rw-r--r--src/gui/kernel/qwidget_win.cpp27
-rw-r--r--src/gui/kernel/qwidget_x11.cpp4
15 files changed, 468 insertions, 171 deletions
diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h
index 7a27756..e839617 100644
--- a/src/gui/kernel/qapplication_p.h
+++ b/src/gui/kernel/qapplication_p.h
@@ -249,6 +249,17 @@ typedef struct tagGESTURECONFIG
#endif // WM_GESTURE
+#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
+#undef GID_ZOOM
+#define GID_ZOOM 0xf000
+#undef GID_ROTATE
+#define GID_ROTATE 0xf001
+#undef GID_TWOFINGERTAP
+#define GID_TWOFINGERTAP 0xf002
+#undef GID_ROLLOVER
+#define GID_ROLLOVER 0xf003
+#endif
+
#endif // Q_WS_WIN
class QPanGesture;
@@ -536,6 +547,7 @@ public:
PtrBeginPanningFeedback BeginPanningFeedback;
PtrUpdatePanningFeedback UpdatePanningFeedback;
PtrEndPanningFeedback EndPanningFeedback;
+ QWidget *gestureWidget;
#endif
#ifdef QT_RX71_MULTITOUCH
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 7d9e6ea..12cd879 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -452,7 +452,7 @@ public:
bool translateConfigEvent(const MSG &msg);
bool translateCloseEvent(const MSG &msg);
bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets);
- bool translateGestureEvent(const MSG &msg);
+ bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi);
void repolishStyle(QStyle &style);
inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); }
inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); }
@@ -848,6 +848,7 @@ void qt_init(QApplicationPrivate *priv, int)
(PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"),
"EndPanningFeedback");
#endif
+ priv->gestureWidget = 0;
}
/*****************************************************************************
@@ -2513,10 +2514,38 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam
}
result = false;
break;
- case WM_GESTURE:
- widget->translateGestureEvent(msg);
+ case WM_GESTURE: {
+ GESTUREINFO gi;
+ memset(&gi, 0, sizeof(GESTUREINFO));
+ gi.cbSize = sizeof(GESTUREINFO);
+
+ QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
+ BOOL bResult = false;
+ if (qAppPriv->GetGestureInfo)
+ bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
+ if (bResult) {
+ if (gi.dwID == GID_BEGIN) {
+ // find the alien widget for the gesture position.
+ // This might not be accurate as the position is the center
+ // point of two fingers for multi-finger gestures.
+ QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y);
+ QWidget *w = widget->childAt(widget->mapFromGlobal(pt));
+ qAppPriv->gestureWidget = w ? w : widget;
+ }
+ if (qAppPriv->gestureWidget)
+ static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi);
+ if (qAppPriv->CloseGestureInfoHandle)
+ qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
+ if (gi.dwID == GID_END)
+ qAppPriv->gestureWidget = 0;
+ } else {
+ DWORD dwErr = GetLastError();
+ if (dwErr > 0)
+ qWarning() << "translateGestureEvent: error = " << dwErr;
+ }
result = true;
break;
+ }
default:
result = false; // event was not processed
break;
@@ -3725,69 +3754,42 @@ bool QETWidget::translateCloseEvent(const MSG &)
return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent);
}
-bool QETWidget::translateGestureEvent(const MSG &msg)
+bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi)
{
- GESTUREINFO gi;
- memset(&gi, 0, sizeof(GESTUREINFO));
- gi.cbSize = sizeof(GESTUREINFO);
+ const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
+ QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
+ if (alienWidget && alienWidget->internalWinId())
+ alienWidget = 0;
+ QWidget *widget = alienWidget ? alienWidget : this;
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
-#if defined(Q_WS_WINCE_WM) && defined(QT_WINCE_GESTURES)
-#undef GID_ZOOM
-#define GID_ZOOM 0xf000
-#undef GID_ROTATE
-#define GID_ROTATE 0xf001
-#undef GID_TWOFINGERTAP
-#define GID_TWOFINGERTAP 0xf002
-#undef GID_ROLLOVER
-#define GID_ROLLOVER 0xf003
-#endif
- BOOL bResult = false;
- if (qAppPriv->GetGestureInfo)
- bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi);
-
- if (bResult) {
- const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
- QWidget *alienWidget = !internalWinId() ? this : childAt(widgetPos);
- if (alienWidget && alienWidget->internalWinId())
- alienWidget = 0;
- QWidget *widget = alienWidget ? alienWidget : this;
-
- QNativeGestureEvent event;
- event.sequenceId = gi.dwSequenceID;
- event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
- event.argument = gi.ullArguments;
-
- switch (gi.dwID) {
- case GID_BEGIN:
- event.gestureType = QNativeGestureEvent::GestureBegin;
- break;
- case GID_END:
- event.gestureType = QNativeGestureEvent::GestureEnd;
- break;
- case GID_ZOOM:
- event.gestureType = QNativeGestureEvent::Zoom;
- break;
- case GID_PAN:
- event.gestureType = QNativeGestureEvent::Pan;
- break;
- case GID_ROTATE:
- event.gestureType = QNativeGestureEvent::Rotate;
- break;
- case GID_TWOFINGERTAP:
- case GID_ROLLOVER:
- default:
- break;
- }
- if (qAppPriv->CloseGestureInfoHandle)
- qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam);
- if (event.gestureType != QNativeGestureEvent::None)
- qt_sendSpontaneousEvent(widget, &event);
- } else {
- DWORD dwErr = GetLastError();
- if (dwErr > 0)
- qWarning() << "translateGestureEvent: error = " << dwErr;
+ QNativeGestureEvent event;
+ event.sequenceId = gi.dwSequenceID;
+ event.position = QPoint(gi.ptsLocation.x, gi.ptsLocation.y);
+ event.argument = gi.ullArguments;
+
+ switch (gi.dwID) {
+ case GID_BEGIN:
+ event.gestureType = QNativeGestureEvent::GestureBegin;
+ break;
+ case GID_END:
+ event.gestureType = QNativeGestureEvent::GestureEnd;
+ break;
+ case GID_ZOOM:
+ event.gestureType = QNativeGestureEvent::Zoom;
+ break;
+ case GID_PAN:
+ event.gestureType = QNativeGestureEvent::Pan;
+ break;
+ case GID_ROTATE:
+ event.gestureType = QNativeGestureEvent::Rotate;
+ break;
+ case GID_TWOFINGERTAP:
+ case GID_ROLLOVER:
+ default:
+ break;
}
+ if (event.gestureType != QNativeGestureEvent::None)
+ qt_sendSpontaneousEvent(widget, &event);
return true;
}
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 79dcae1..eeb6528 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -149,20 +149,18 @@ private:
\sa setGraphicsItem()
*/
-QGesture::QGesture(QObject *parent)
+QGesture::QGesture(QObject *gestureTarget, QObject *parent)
: QObject(*new QGesturePrivate, parent)
{
- if (parent)
- parent->installEventFilter(this);
+ setGestureTarget(gestureTarget);
}
/*! \internal
*/
-QGesture::QGesture(QGesturePrivate &dd, QObject *parent)
+QGesture::QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent)
: QObject(dd, parent)
{
- if (parent)
- parent->installEventFilter(this);
+ setGestureTarget(gestureTarget);
}
/*!
@@ -172,6 +170,33 @@ QGesture::~QGesture()
{
}
+/*!
+ \property QGesture::gestureTarget
+
+ Gesture target is the object that the gesture will observe for events.
+ Typically this means that the gesture installs an event filter on the
+ target object.
+*/
+void QGesture::setGestureTarget(QObject *object)
+{
+ d_func()->setupGestureTarget(object);
+}
+
+QObject* QGesture::gestureTarget() const
+{
+ return d_func()->gestureTarget;
+}
+
+void QGesturePrivate::setupGestureTarget(QObject *object)
+{
+ Q_Q(QGesture);
+ if (gestureTarget)
+ gestureTarget->removeEventFilter(q);
+ if (object)
+ object->installEventFilter(q);
+ gestureTarget = object;
+}
+
/*! \internal
*/
bool QGesture::eventFilter(QObject *receiver, QEvent *event)
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index ee28ea4..1d2fa6d 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -63,20 +63,24 @@ class Q_GUI_EXPORT QGesture : public QObject
Q_DECLARE_PRIVATE(QGesture)
Q_PROPERTY(Qt::GestureState state READ state)
+ Q_PROPERTY(QObject* gestureTarget READ gestureTarget WRITE setGestureTarget)
public:
- explicit QGesture(QObject *parent = 0);
+ explicit QGesture(QObject *gestureTarget = 0, QObject *parent = 0);
~QGesture();
virtual bool filterEvent(QEvent *event) = 0;
+ void setGestureTarget(QObject *object);
+ QObject* gestureTarget() const;
+
void setGraphicsItem(QGraphicsItem *);
QGraphicsItem *graphicsItem() const;
Qt::GestureState state() const;
protected:
- QGesture(QGesturePrivate &dd, QObject *parent);
+ QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent);
bool eventFilter(QObject*, QEvent*);
virtual void reset();
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 37f3146..f584713 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -69,11 +69,14 @@ class QGesturePrivate : public QObjectPrivate
public:
QGesturePrivate()
- : graphicsItem(0), eventFilterProxyGraphicsItem(0), state(Qt::NoGesture)
+ : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0),
+ state(Qt::NoGesture)
{
}
+ virtual void setupGestureTarget(QObject *o);
+ QPointer<QObject> gestureTarget;
QGraphicsItem *graphicsItem;
QGraphicsItem *eventFilterProxyGraphicsItem;
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index 10689ba..d798d32 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -69,42 +69,35 @@ QWidgetPrivate *qt_widget_private(QWidget *widget);
On some platform like Windows it's necessary to provide a non-null widget
as \a parent to get native gesture support.
*/
-QPanGesture::QPanGesture(QWidget *parent)
- : QGesture(*new QPanGesturePrivate, parent)
+QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent)
+ : QGesture(*new QPanGesturePrivate, gestureTarget, parent)
{
- if (parent) {
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- qAppPriv->widgetGestures[parent].pan = this;
-#ifdef Q_WS_WIN
- qt_widget_private(parent)->winSetupGestures();
-#endif
- }
}
-/*! \internal */
-bool QPanGesture::event(QEvent *event)
+void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
{
- switch (event->type()) {
- case QEvent::ParentAboutToChange:
- if (QWidget *w = qobject_cast<QWidget*>(parent())) {
- QApplicationPrivate::instance()->widgetGestures[w].pan = 0;
+ Q_Q(QPanGesture);
+ if (gestureTarget && gestureTarget->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(gestureTarget.data());
+ QApplicationPrivate::instance()->widgetGestures[w].pan = 0;
#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
+ qt_widget_private(w)->winSetupGestures();
#endif
- }
- break;
- case QEvent::ParentChange:
- if (QWidget *w = qobject_cast<QWidget*>(parent())) {
- QApplicationPrivate::instance()->widgetGestures[w].pan = this;
+ }
+
+ if (newGestureTarget && newGestureTarget->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(newGestureTarget);
+ QApplicationPrivate::instance()->widgetGestures[w].pan = q;
#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
+ qt_widget_private(w)->winSetupGestures();
#endif
- }
- break;
- default:
- break;
}
+ QGesturePrivate::setupGestureTarget(newGestureTarget);
+}
+/*! \internal */
+bool QPanGesture::event(QEvent *event)
+{
#if defined(Q_OS_MAC) && !defined(QT_MAC_USE_COCOA)
Q_D(QPanGesture);
if (event->type() == QEvent::Timer) {
@@ -179,27 +172,29 @@ bool QPanGesture::filterEvent(QEvent *event)
d->lastOffset = d->totalOffset = QSize();
} else if (event->type() == QEvent::TouchEnd) {
if (state() != Qt::NoGesture) {
- if (!ev->touchPoints().isEmpty()) {
- QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
- const QPoint pos = p.pos().toPoint();
- const QPoint lastPos = p.lastPos().toPoint();
- const QPoint startPos = p.startPos().toPoint();
- d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y());
- d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y());
+ if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ d->lastOffset =
+ QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
+ p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
+ d->totalOffset += d->lastOffset;
}
updateState(Qt::GestureFinished);
}
reset();
} else if (event->type() == QEvent::TouchUpdate) {
- QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
- const QPoint pos = p.pos().toPoint();
- const QPoint lastPos = p.lastPos().toPoint();
- const QPoint startPos = p.startPos().toPoint();
- d->lastOffset = QSize(pos.x() - lastPos.x(), pos.y() - lastPos.y());
- d->totalOffset = QSize(pos.x() - startPos.x(), pos.y() - startPos.y());
- if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 ||
- d->totalOffset.width() < -10 || d->totalOffset.height() < -10) {
- updateState(Qt::GestureUpdated);
+ if (ev->touchPoints().size() == 2) {
+ QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
+ QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
+ d->lastOffset =
+ QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
+ p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
+ d->totalOffset += d->lastOffset;
+ if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 ||
+ d->totalOffset.width() < -10 || d->totalOffset.height() < -10) {
+ updateState(Qt::GestureUpdated);
+ }
}
}
#ifdef Q_OS_MAC
@@ -287,41 +282,35 @@ QSize QPanGesture::lastOffset() const
On some platform like Windows it's necessary to provide a non-null widget
as \a parent to get native gesture support.
*/
-QPinchGesture::QPinchGesture(QWidget *parent)
- : QGesture(*new QPinchGesturePrivate, parent)
+QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent)
+ : QGesture(*new QPinchGesturePrivate, gestureTarget, parent)
{
- if (parent) {
- QApplicationPrivate *qAppPriv = QApplicationPrivate::instance();
- qAppPriv->widgetGestures[parent].pinch = this;
-#ifdef Q_WS_WIN
- qt_widget_private(parent)->winSetupGestures();
-#endif
- }
}
-/*! \internal */
-bool QPinchGesture::event(QEvent *event)
+void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget)
{
- switch (event->type()) {
- case QEvent::ParentAboutToChange:
- if (QWidget *w = qobject_cast<QWidget*>(parent())) {
- QApplicationPrivate::instance()->widgetGestures[w].pinch = 0;
+ Q_Q(QPinchGesture);
+ if (gestureTarget && gestureTarget->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(gestureTarget.data());
+ QApplicationPrivate::instance()->widgetGestures[w].pinch = 0;
#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
+ qt_widget_private(w)->winSetupGestures();
#endif
- }
- break;
- case QEvent::ParentChange:
- if (QWidget *w = qobject_cast<QWidget*>(parent())) {
- QApplicationPrivate::instance()->widgetGestures[w].pinch = this;
+ }
+
+ if (newGestureTarget && newGestureTarget->isWidgetType()) {
+ QWidget *w = static_cast<QWidget*>(newGestureTarget);
+ QApplicationPrivate::instance()->widgetGestures[w].pinch = q;
#ifdef Q_WS_WIN
- qt_widget_private(w)->winSetupGestures();
+ qt_widget_private(w)->winSetupGestures();
#endif
- }
- break;
- default:
- break;
}
+ QGesturePrivate::setupGestureTarget(newGestureTarget);
+}
+
+/*! \internal */
+bool QPinchGesture::event(QEvent *event)
+{
return QObject::event(event);
}
@@ -399,6 +388,7 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event)
return QGesture::eventFilter(receiver, event);
}
+
/*! \internal */
bool QPinchGesture::filterEvent(QEvent *event)
{
diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h
index 8b5421b..0eb9d92 100644
--- a/src/gui/kernel/qstandardgestures.h
+++ b/src/gui/kernel/qstandardgestures.h
@@ -63,7 +63,7 @@ class Q_GUI_EXPORT QPanGesture : public QGesture
Q_PROPERTY(QSize lastOffset READ lastOffset)
public:
- QPanGesture(QWidget *parent);
+ QPanGesture(QWidget *gestureTarget, QObject *parent = 0);
bool filterEvent(QEvent *event);
@@ -97,7 +97,7 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture
Q_PROPERTY(QPoint centerPoint READ centerPoint)
public:
- QPinchGesture(QWidget *parent);
+ QPinchGesture(QWidget *gestureTarget, QObject *parent = 0);
bool filterEvent(QEvent *event);
void reset();
diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h
index c52d16b..5fbcc5d 100644
--- a/src/gui/kernel/qstandardgestures_p.h
+++ b/src/gui/kernel/qstandardgestures_p.h
@@ -76,6 +76,8 @@ public:
#endif
}
+ void setupGestureTarget(QObject *o);
+
QSize totalOffset;
QSize lastOffset;
QPoint lastPosition;
@@ -98,6 +100,9 @@ public:
#endif
{
}
+
+ void setupGestureTarget(QObject *o);
+
qreal scaleFactor;
qreal lastScaleFactor;
qreal rotationAngle;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 4de08fd..bbda469 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -186,6 +186,7 @@ QWidgetPrivate::QWidgetPrivate(int version)
, widgetItem(0)
, extraPaintEngine(0)
, polished(0)
+ , graphicsEffect(0)
, inheritedFontResolveMask(0)
, inheritedPaletteResolveMask(0)
, leftmargin(0)
@@ -242,6 +243,8 @@ QWidgetPrivate::~QWidgetPrivate()
if (extra)
deleteExtra();
+
+ delete graphicsEffect;
}
QWindowSurface *QWidgetPrivate::createDefaultWindowSurface()
@@ -1628,9 +1631,9 @@ bool QWidgetPrivate::isOverlapped(const QRect &rect) const
continue;
}
- if (qRectIntersects(sibling->data->crect, r)) {
+ if (qRectIntersects(sibling->d_func()->effectiveRectFor(sibling->data->crect), r)) {
const QWExtra *siblingExtra = sibling->d_func()->extra;
- if (siblingExtra && siblingExtra->hasMask
+ if (siblingExtra && siblingExtra->hasMask && !sibling->d_func()->graphicsEffect
&& !siblingExtra->mask.translated(sibling->data->crect.topLeft()).intersects(r)) {
continue;
}
@@ -1729,7 +1732,7 @@ QRect QWidgetPrivate::clipRect() const
const QWidget * w = q;
if (!w->isVisible())
return QRect();
- QRect r = q->rect();
+ QRect r = effectiveRectFor(q->rect());
int ox = 0;
int oy = 0;
while (w
@@ -1871,12 +1874,14 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
break;
QWidgetPrivate *pd = w->parentWidget()->d_func();
const int myIndex = pd->children.indexOf(const_cast<QWidget *>(w));
+ const QRect widgetGeometry = w->d_func()->effectiveRectFor(w->data->crect);
for (int i = myIndex + 1; i < pd->children.size(); ++i) {
QWidget *sibling = qobject_cast<QWidget *>(pd->children.at(i));
if (!sibling || !sibling->isVisible() || sibling->isWindow())
continue;
- if (!qRectIntersects(sibling->data->crect, w->data->crect))
+ const QRect siblingGeometry = sibling->d_func()->effectiveRectFor(sibling->data->crect);
+ if (!qRectIntersects(siblingGeometry, widgetGeometry))
continue;
if (dirtyClipBoundingRect) {
@@ -1884,7 +1889,7 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
dirtyClipBoundingRect = false;
}
- if (!qRectIntersects(sibling->data->crect, clipBoundingRect.translated(parentOffset)))
+ if (!qRectIntersects(siblingGeometry, clipBoundingRect.translated(parentOffset)))
continue;
if (dirtyParentClip) {
@@ -1896,7 +1901,8 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
const QRect siblingClipRect(sibling->d_func()->clipRect());
QRegion siblingDirty(parentClip);
siblingDirty &= (siblingClipRect.translated(siblingPos));
- const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask;
+ const bool hasMask = sibling->d_func()->extra && sibling->d_func()->extra->hasMask
+ && !sibling->d_func()->graphicsEffect;
if (hasMask)
siblingDirty &= sibling->d_func()->extra->mask.translated(siblingPos);
if (siblingDirty.isEmpty())
@@ -1907,7 +1913,7 @@ void QWidgetPrivate::subtractOpaqueSiblings(QRegion &sourceRegion, bool *hasDirt
siblingDirty.translate(-parentOffset);
sourceRegion -= siblingDirty;
} else {
- sourceRegion -= sibling->data->crect.translated(-parentOffset);
+ sourceRegion -= siblingGeometry.translated(-parentOffset);
}
} else {
if (hasDirtySiblingsAbove)
@@ -1938,6 +1944,11 @@ void QWidgetPrivate::clipToEffectiveMask(QRegion &region) const
const QWidget *w = q;
QPoint offset;
+ if (graphicsEffect) {
+ w = q->parentWidget();
+ offset -= data.crect.topLeft();
+ }
+
while (w) {
const QWidgetPrivate *wd = w->d_func();
if (wd->extra && wd->extra->hasMask)
@@ -1971,6 +1982,12 @@ void QWidgetPrivate::updateIsOpaque()
// hw: todo: only needed if opacity actually changed
setDirtyOpaqueRegion();
+ if (graphicsEffect) {
+ // ### We should probably add QGraphicsEffect::isOpaque at some point.
+ setOpaque(false);
+ return;
+ }
+
Q_Q(QWidget);
#ifdef Q_WS_X11
if (q->testAttribute(Qt::WA_X11OpenGLOverlay)) {
@@ -4948,6 +4965,54 @@ void QWidgetPrivate::setSoftKeys_sys(const QList<QAction*> &softkeys)
}
#endif // !defined(Q_OS_SYMBIAN)
+QGraphicsEffect *QWidget::graphicsEffect() const
+{
+ Q_D(const QWidget);
+ return d->graphicsEffect;
+}
+
+/*!
+ Sets \a effect as the widget's effect. If there already is an effect installed
+ on this widget, QWidget will delete the existing effect before installing
+ the new \a effect.
+
+ If \a effect is the installed on a different widget, setGraphicsEffect() will remove
+ the effect from the widget and install it on this widget.
+
+ \note This function will apply the effect on itself and all its children.
+
+ \since 4.6
+*/
+void QWidget::setGraphicsEffect(QGraphicsEffect *effect)
+{
+ Q_D(QWidget);
+ if (d->graphicsEffect == effect)
+ return;
+
+ if (d->graphicsEffect && effect) {
+ delete d->graphicsEffect;
+ d->graphicsEffect = 0;
+ }
+
+ if (!effect) {
+ // Unset current effect.
+ QGraphicsEffectPrivate *oldEffectPrivate = d->graphicsEffect->d_func();
+ d->graphicsEffect = 0;
+ if (oldEffectPrivate) {
+ oldEffectPrivate->setGraphicsEffectSource(0); // deletes the current source.
+ }
+ } else {
+ // Set new effect.
+ QGraphicsEffectSourcePrivate *sourced = new QWidgetEffectSourcePrivate(this);
+ QGraphicsEffectSource *source = new QGraphicsEffectSource(*sourced);
+ d->graphicsEffect = effect;
+ effect->d_func()->setGraphicsEffectSource(source);
+ }
+
+ d->updateIsOpaque();
+ update();
+}
+
bool QWidgetPrivate::isAboutToShow() const
{
if (data.in_show)
@@ -5092,6 +5157,33 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
return;
Q_Q(QWidget);
+ 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) {
+ QPaintEngine *paintEngine = pdev->paintEngine();
+ paintEngine->d_func()->systemClip = rgn.translated(offset);
+ QPainter p(pdev);
+ p.translate(offset);
+ context.painter = &p;
+ graphicsEffect->draw(&p, source);
+ paintEngine->d_func()->systemClip = QRegion();
+ } else {
+ context.painter = sharedPainter;
+ sharedPainter->save();
+ sharedPainter->translate(offset);
+ graphicsEffect->draw(sharedPainter, source);
+ sharedPainter->restore();
+ }
+ sourced->context = 0;
+ return;
+ }
+ }
+
const bool asRoot = flags & DrawAsRoot;
const bool alsoOnScreen = flags & DrawPaintOnScreen;
const bool recursive = flags & DrawRecursive;
@@ -5124,7 +5216,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
if (sharedPainter)
paintEngine->d_func()->systemClip = toBePainted;
else
- paintEngine->setSystemRect(q->data->crect);
+ paintEngine->d_func()->systemRect = q->data->crect;
//paint the background
if ((asRoot || q->autoFillBackground() || onScreen || q->testAttribute(Qt::WA_StyledBackground))
@@ -5163,7 +5255,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
if (paintEngine) {
restoreRedirected();
if (!sharedPainter)
- paintEngine->setSystemRect(QRect());
+ paintEngine->d_func()->systemRect = QRect();
else
paintEngine->d_func()->currentClipWidget = 0;
paintEngine->d_func()->systemClip = QRegion();
@@ -5226,7 +5318,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
dirtyBoundingRect = false;
}
- if (qRectIntersects(boundingRect, x->data->crect)) {
+ if (qRectIntersects(boundingRect, x->d_func()->effectiveRectFor(x->data->crect))) {
#ifdef Q_BACKINGSTORE_SUBSURFACES
if (x->windowSurface() == currentSurface)
#endif
@@ -5244,7 +5336,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
QWidgetPrivate *wd = w->d_func();
const QPoint widgetPos(w->data->crect.topLeft());
- const bool hasMask = wd->extra && wd->extra->hasMask;
+ const bool hasMask = wd->extra && wd->extra->hasMask && !wd->graphicsEffect;
if (index > 0) {
QRegion wr(rgn);
@@ -5259,7 +5351,7 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
if (w->updatesEnabled() && (!w->d_func()->extra || !w->d_func()->extra->proxyWidget)) {
QRegion wRegion(rgn);
- wRegion &= w->data->crect;
+ wRegion &= wd->effectiveRectFor(w->data->crect);
wRegion.translate(-widgetPos);
if (hasMask)
wRegion &= wd->extra->mask;
@@ -5267,6 +5359,93 @@ void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectLis
}
}
+QRectF QWidgetEffectSourcePrivate::boundingRect(Qt::CoordinateSystem system) const
+{
+ if (system != Qt::DeviceCoordinates)
+ return m_widget->rect();
+
+ if (!context) {
+ // Device coordinates without context not yet supported.
+ qWarning("QGraphicsEffectSource::boundingRect: Not yet implemented, lacking device context");
+ return QRectF();
+ }
+
+ return context->painter->worldTransform().mapRect(m_widget->rect());
+}
+
+void QWidgetEffectSourcePrivate::draw(QPainter *painter)
+{
+ if (!context || context->painter != painter) {
+ m_widget->render(painter);
+ return;
+ }
+
+ // The region saved in the context is neither clipped to the rect
+ // nor the mask, so we have to clip it here before calling drawWidget.
+ QRegion toBePainted = context->rgn;
+ toBePainted &= m_widget->rect();
+ QWidgetPrivate *wd = qt_widget_private(m_widget);
+ if (wd->extra && wd->extra->hasMask)
+ toBePainted &= wd->extra->mask;
+
+ wd->drawWidget(context->pdev, toBePainted, context->offset, context->flags,
+ context->sharedPainter, context->backingStore);
+}
+
+QPixmap QWidgetEffectSourcePrivate::pixmap(Qt::CoordinateSystem system, QPoint *offset) const
+{
+ const bool deviceCoordinates = (system == Qt::DeviceCoordinates);
+ if (!context && deviceCoordinates) {
+ // Device coordinates without context not yet supported.
+ qWarning("QGraphicsEffectSource::pixmap: Not yet implemented, lacking device context");
+ return QPixmap();
+ }
+
+ QPoint pixmapOffset;
+ QRectF sourceRect = m_widget->rect();
+
+ if (deviceCoordinates) {
+ const QTransform &painterTransform = context->painter->worldTransform();
+ sourceRect = painterTransform.mapRect(sourceRect);
+ pixmapOffset = painterTransform.map(pixmapOffset);
+ }
+
+ QRect effectRect = m_widget->graphicsEffect()->boundingRectFor(sourceRect).toAlignedRect();
+ if (offset)
+ *offset = effectRect.topLeft();
+
+ if (deviceCoordinates) {
+ // Clip to device rect.
+ int left, top, right, bottom;
+ effectRect.getCoords(&left, &top, &right, &bottom);
+ if (left < 0) {
+ if (offset)
+ offset->rx() += -left;
+ effectRect.setX(0);
+ }
+ if (top < 0) {
+ if (offset)
+ offset->ry() += -top;
+ effectRect.setY(0);
+ }
+ // NB! We use +-1 for historical reasons (see QRect documentation).
+ QPaintDevice *device = context->painter->device();
+ const int deviceWidth = device->width();
+ const int deviceHeight = device->height();
+ if (right + 1 > deviceWidth)
+ effectRect.setRight(deviceWidth - 1);
+ if (bottom + 1 > deviceHeight)
+ effectRect.setBottom(deviceHeight -1);
+ }
+
+ pixmapOffset -= effectRect.topLeft();
+
+ QPixmap pixmap(effectRect.size());
+ pixmap.fill(Qt::transparent);
+ m_widget->render(&pixmap, pixmapOffset);
+ return pixmap;
+}
+
/*!
\internal
diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h
index a40b52d..2484ba6 100644
--- a/src/gui/kernel/qwidget.h
+++ b/src/gui/kernel/qwidget.h
@@ -96,6 +96,7 @@ class QWindowSurface;
class QLocale;
class QGraphicsProxyWidget;
class QGestureManager;
+class QGraphicsEffect;
#if defined(Q_WS_X11)
class QX11Info;
#endif
@@ -353,6 +354,9 @@ public:
const QRegion &sourceRegion = QRegion(),
RenderFlags renderFlags = RenderFlags(DrawWindowBackground | DrawChildren));
+ QGraphicsEffect *graphicsEffect() const;
+ void setGraphicsEffect(QGraphicsEffect *effect);
+
public Q_SLOTS:
void setWindowTitle(const QString &);
#ifndef QT_NO_STYLE_STYLESHEET
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 4bd7222..ea5a53e 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2567,7 +2567,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(geometry());
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
d->deactivateWidgetCleanup();
qt_mac_event_release(this);
if(testAttribute(Qt::WA_WState_Created)) {
@@ -2673,7 +2673,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
OSViewRef old_id = 0;
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
// Maintain the glWidgets list on parent change: remove "our" gl widgets
// from the list on the old parent and grandparents.
@@ -4169,12 +4169,12 @@ void QWidgetPrivate::setGeometry_sys_helper(int x, int y, int w, int h, bool isM
setWSGeometry(false, oldRect);
if (isResize && QApplicationPrivate::graphicsSystem()) {
invalidateBuffer(q->rect());
- if (extra && !extra->mask.isEmpty()) {
+ if (extra && !graphicsEffect && !extra->mask.isEmpty()) {
QRegion oldRegion(extra->mask.translated(oldp));
oldRegion &= oldRect;
q->parentWidget()->d_func()->invalidateBuffer(oldRegion);
} else {
- q->parentWidget()->d_func()->invalidateBuffer(oldRect);
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(oldRect));
}
}
}
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 8e58498..ed0abce 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -62,6 +62,7 @@
#include "QtGui/qsizepolicy.h"
#include "QtGui/qstyle.h"
#include "QtGui/qapplication.h"
+#include <private/qgraphicseffect_p.h>
#ifdef Q_WS_WIN
#include "QtCore/qt_windows.h"
@@ -460,6 +461,13 @@ public:
return extra ? extra->nativeChildrenForced : false;
}
+ inline QRect effectiveRectFor(const QRect &rect) const
+ {
+ if (graphicsEffect && graphicsEffect->isEnabled())
+ return graphicsEffect->boundingRectFor(rect).toAlignedRect();
+ return rect;
+ }
+
QSize adjustedSize() const;
inline void handleSoftwareInputPanel(Qt::MouseButton button, bool clickCausedFocus)
@@ -504,6 +512,7 @@ public:
QWidgetItemV2 *widgetItem;
QPaintEngine *extraPaintEngine;
mutable const QMetaObject *polished;
+ QGraphicsEffect *graphicsEffect;
// All widgets are added into the allWidgets set. Once
// they receive a window id they are also added to the mapper.
// This should just ensure that all widgets are deleted by QApplication
@@ -681,6 +690,57 @@ public:
};
+struct QWidgetPaintContext
+{
+ inline QWidgetPaintContext(QPaintDevice *d, const QRegion &r, const QPoint &o, int f,
+ QPainter *p, QWidgetBackingStore *b)
+ : pdev(d), rgn(r), offset(o), flags(f), sharedPainter(p), backingStore(b), painter(0) {}
+
+ QPaintDevice *pdev;
+ QRegion rgn;
+ QPoint offset;
+ int flags;
+ QPainter *sharedPainter;
+ QWidgetBackingStore *backingStore;
+ QPainter *painter;
+};
+
+class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
+{
+public:
+ QWidgetEffectSourcePrivate(QWidget *widget)
+ : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0)
+ {}
+
+ inline void detach()
+ { m_widget->setGraphicsEffect(0); }
+
+ inline const QGraphicsItem *graphicsItem() const
+ { return 0; }
+
+ inline const QWidget *widget() const
+ { return m_widget; }
+
+ inline void update()
+ { m_widget->update(); }
+
+ inline bool isPixmap() const
+ { return false; }
+
+ inline const QStyleOption *styleOption() const
+ { return 0; }
+
+ inline QRect deviceRect() const
+ { return m_widget->window()->rect(); }
+
+ QRectF boundingRect(Qt::CoordinateSystem system) const;
+ void draw(QPainter *p);
+ QPixmap pixmap(Qt::CoordinateSystem system, QPoint *offset) const;
+
+ QWidget *m_widget;
+ QWidgetPaintContext *context;
+};
+
inline QWExtra *QWidgetPrivate::extraData() const
{
return extra;
diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp
index 09bffe6..f8ac252 100644
--- a/src/gui/kernel/qwidget_qws.cpp
+++ b/src/gui/kernel/qwidget_qws.cpp
@@ -258,7 +258,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
Q_D(QWidget);
if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(geometry());
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
d->deactivateWidgetCleanup();
if (testAttribute(Qt::WA_WState_Created)) {
@@ -317,7 +317,7 @@ void QWidgetPrivate::setParent_sys(QWidget *newparent, Qt::WindowFlags f)
Q_Q(QWidget);
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
#ifndef QT_NO_CURSOR
QCursor oldcurs;
bool setcurs=q->testAttribute(Qt::WA_SetCursor);
@@ -814,7 +814,7 @@ void QWidgetPrivate::lower_sys()
QWSChangeAltitudeCommand::Lower);
} else if (QWidget *p = q->parentWidget()) {
setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(q->geometry());
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
}
}
@@ -823,7 +823,7 @@ void QWidgetPrivate::stackUnder_sys(QWidget*)
Q_Q(QWidget);
if (QWidget *p = q->parentWidget()) {
setDirtyOpaqueRegion();
- p->d_func()->invalidateBuffer(q->geometry());
+ p->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
}
}
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 3d618fe..40e3fa2 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -535,7 +535,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(geometry());
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
d->deactivateWidgetCleanup();
if (testAttribute(Qt::WA_WState_Created)) {
setAttribute(Qt::WA_WState_Created, false);
@@ -601,7 +601,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
Q_Q(QWidget);
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
WId old_winid = data.winid;
// hide and reparent our own window away. Otherwise we might get
@@ -2070,11 +2070,21 @@ void QWidgetPrivate::winSetupGestures()
bool needh = false;
bool needv = false;
bool singleFingerPanEnabled = false;
- QStandardGestures gestures = qAppPriv->widgetGestures[q];
+ QApplicationPrivate::WidgetStandardGesturesMap::const_iterator it =
+ qAppPriv->widgetGestures.find(q);
+ if (it == qAppPriv->widgetGestures.end())
+ return;
+ const QStandardGestures &gestures = it.value();
WId winid = 0;
if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q)) {
- winid = asa->viewport()->winId();
+ winid = asa->viewport()->internalWinId();
+ if (!winid) {
+ QWidget *nativeParent = asa->viewport()->nativeParentWidget();
+ if (!nativeParent)
+ return;
+ winid = nativeParent->internalWinId();
+ }
QScrollBar *hbar = asa->horizontalScrollBar();
QScrollBar *vbar = asa->verticalScrollBar();
Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy();
@@ -2085,9 +2095,13 @@ void QWidgetPrivate::winSetupGestures()
(vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum()));
singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled;
} else {
- winid = q->winId();
+ winid = q->internalWinId();
+ if (!winid) {
+ if (QWidget *nativeParent = q->nativeParentWidget())
+ winid = nativeParent->internalWinId();
+ }
}
- if (qAppPriv->SetGestureConfig) {
+ if (winid && qAppPriv->SetGestureConfig) {
GESTURECONFIG gc[3];
memset(gc, 0, sizeof(gc));
gc[0].dwID = GID_PAN;
@@ -2116,7 +2130,6 @@ void QWidgetPrivate::winSetupGestures()
else
gc[2].dwBlock = GC_ROTATE;
- Q_ASSERT(winid);
qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0]));
}
}
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 5e3897b..62aba45 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -971,7 +971,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows)
{
Q_D(QWidget);
if (!isWindow() && parentWidget())
- parentWidget()->d_func()->invalidateBuffer(geometry());
+ parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry()));
d->deactivateWidgetCleanup();
if (testAttribute(Qt::WA_WState_Created)) {
setAttribute(Qt::WA_WState_Created, false);
@@ -1054,7 +1054,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f)
QTLWExtra *topData = maybeTopData();
bool wasCreated = q->testAttribute(Qt::WA_WState_Created);
if (q->isVisible() && q->parentWidget() && parent != q->parentWidget())
- q->parentWidget()->d_func()->invalidateBuffer(q->geometry());
+ q->parentWidget()->d_func()->invalidateBuffer(effectiveRectFor(q->geometry()));
extern void qPRCreate(const QWidget *, Window);
#ifndef QT_NO_CURSOR
QCursor oldcurs;