From b6b1dee9460d6fdde0b8ad005301c0a315ad30bf Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Mon, 22 Mar 2010 08:04:46 +0100 Subject: Fix a crash when reparenting an item in QGraphicsView. Before calling addItem we need to invalidate the depth otherwise if someone call anything relating to sorting when itemChange is called (because of the scene change for instance) then qt_closestItemFirst for example can crash because of an invalid state. Task-number:QTBUG-6932 Reviewed-by:janarve --- src/gui/graphicsview/qgraphicsitem.cpp | 5 ++-- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 34 ++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index f3c90ca..9852323 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1130,6 +1130,9 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q } } + // Resolve depth. + invalidateDepthRecursively(); + if ((parent = newParent)) { if (parent->d_func()->scene && parent->d_func()->scene != scene) { // Move this item to its new parent's scene @@ -1180,8 +1183,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q } } - // Resolve depth. - invalidateDepthRecursively(); dirtySceneTransform = 1; // Restore the sub focus chain. diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 4d9f23f..75fb337 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -439,6 +439,7 @@ private slots: void QTBUG_7714_fullUpdateDiscardingOpacityUpdate2(); void QT_2653_fullUpdateDiscardingOpacityUpdate(); void QT_2649_focusScope(); + void sortItemsWhileAdding(); private: QList paintedItems; @@ -10070,5 +10071,38 @@ void tst_QGraphicsItem::QT_2649_focusScope() delete scene; } +class MyGraphicsItemWithItemChange : public QGraphicsWidget +{ +public: + MyGraphicsItemWithItemChange(QGraphicsItem *parent = 0) : QGraphicsWidget(parent) + {} + + QVariant itemChange(GraphicsItemChange change, const QVariant &value) + { + if (change == QGraphicsItem::ItemSceneHasChanged) { + foreach (QGraphicsView *view, scene()->views()) { + //We trigger a sort of unindexed items in the BSP + view->sceneRect(); + } + } + return QGraphicsWidget::itemChange(change, value); + } +}; + +void tst_QGraphicsItem::sortItemsWhileAdding() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + QGraphicsWidget grandGrandParent; + grandGrandParent.resize(200, 200); + scene.addItem(&grandGrandParent); + QGraphicsWidget grandParent; + grandParent.resize(200, 200); + QGraphicsWidget parent(&grandParent); + parent.resize(200, 200); + MyGraphicsItemWithItemChange item(&parent); + grandParent.setParentItem(&grandGrandParent); +} + QTEST_MAIN(tst_QGraphicsItem) #include "tst_qgraphicsitem.moc" -- cgit v0.12 From c8fa23a5edd790d9eed0620068a29e03e4202cac Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 24 Mar 2010 02:12:47 +0100 Subject: Invalidate the cache of QGraphicsEffect if a child becomes visible. The effect might rely on a child to draw itself. So we need to redraw if a child become visible or invisible. Task-number:QTBUG-7843 Reviewed-by:janarve --- src/gui/graphicsview/qgraphicsitem.cpp | 6 ++- tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp | 43 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9852323..e10c03a 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -2177,8 +2177,12 @@ void QGraphicsItemPrivate::setVisibleHelper(bool newVisible, bool explicitly, bo QGraphicsItemCache *c = (QGraphicsItemCache *)qVariantValue(extra(ExtraCacheData)); if (c) c->purge(); - if (scene) + if (scene) { +#ifndef QT_NO_GRAPHICSEFFECT + invalidateParentGraphicsEffectsRecursively(); +#endif //QT_NO_GRAPHICSEFFECT scene->d_func()->markDirty(q_ptr, QRectF(), /*invalidateChildren=*/false, /*force=*/true); + } } // Certain properties are dropped as an item becomes invisible. diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 1007d61..02899ae 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include "../../shared/util.h" @@ -73,6 +74,7 @@ private slots: void deviceCoordinateTranslateCaching(); void inheritOpacity(); void dropShadowClipping(); + void childrenVisibilityShouldInvalidateCache(); }; void tst_QGraphicsEffect::initTestCase() @@ -613,6 +615,47 @@ void tst_QGraphicsEffect::dropShadowClipping() QCOMPARE(img.pixel(x, y), img.pixel(x, y-1)); } +class MyGraphicsItem : public QGraphicsWidget +{ +public: + MyGraphicsItem(QGraphicsItem *parent = 0) : + QGraphicsWidget(parent), nbPaint(0) + {} + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + nbPaint++; + QGraphicsWidget::paint(painter, option, widget); + } + int nbPaint; +}; + +void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache() +{ + QGraphicsScene scene; + MyGraphicsItem parent; + parent.resize(200, 200); + QGraphicsWidget child(&parent); + child.resize(200, 200); + child.setVisible(false); + scene.addItem(&parent); + QGraphicsView view(&scene); + view.show(); + QApplication::setActiveWindow(&view); + QTest::qWaitForWindowShown(&view); + QCOMPARE(parent.nbPaint, 1); + //we set an effect on the parent + parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent)); + //flush the events + QApplication::processEvents(); + //new effect applied->repaint + QCOMPARE(parent.nbPaint, 2); + child.setVisible(true); + //flush the events + QApplication::processEvents(); + //a new child appears we need to redraw the effect. + QCOMPARE(parent.nbPaint, 3); +} + QTEST_MAIN(tst_QGraphicsEffect) #include "tst_qgraphicseffect.moc" -- cgit v0.12 From 4be83fa7337c5a4eb7b0ce085aa5854af5d33252 Mon Sep 17 00:00:00 2001 From: Alexis Menard Date: Wed, 24 Mar 2010 05:33:21 +0100 Subject: Add a children private property needed for QML to support QGraphicsObject Commit adds a private property that QML can use to add children for a given item. This is a custom list that calls a callback which actually reparent the item instead of just appending in the list (otherwise it will mess up the state of QGraphicsView). This is needed because childItems() is pretty useless you get a list but if you append something on it then it adds that into a copy. Also the children property is the default property a concept used by QML. Width and Height private properties has been added in order to support better the integration with QGraphicsWidget in QML. The actual implementation is in the private class of QGI and QGraphicsWidget reimplements it to return the geometry. (In 4.7 QDeclarativeItem reimplements it too). This change should be harmless everything is private. Task-number:QT-2757 Reviewed-by:andreas --- src/gui/graphicsview/qgraphicsitem.cpp | 103 +++++++++++++++++++++ src/gui/graphicsview/qgraphicsitem.h | 7 ++ src/gui/graphicsview/qgraphicsitem_p.h | 67 ++++++++++++++ src/gui/graphicsview/qgraphicswidget.cpp | 14 +++ src/gui/graphicsview/qgraphicswidget_p.cpp | 51 ++++++++++ src/gui/graphicsview/qgraphicswidget_p.h | 9 ++ tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp | 28 ++++++ 7 files changed, 279 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index e10c03a..f110a5c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -5224,6 +5224,8 @@ void QGraphicsItemPrivate::addChild(QGraphicsItem *child) needSortChildren = 1; // ### maybe 0 child->d_ptr->siblingIndex = children.size(); children.append(child); + if (isObject) + emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -5246,6 +5248,8 @@ void QGraphicsItemPrivate::removeChild(QGraphicsItem *child) // the child is not guaranteed to be at the index after the list is sorted. // (see ensureSortedChildren()). child->d_ptr->siblingIndex = -1; + if (isObject) + emit static_cast(q_ptr)->childrenChanged(); } /*! @@ -7453,6 +7457,88 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) } } +void QGraphicsItemPrivate::append(QDeclarativeListProperty *list, QGraphicsObject *item) +{ + QGraphicsItemPrivate::get(item)->setParentItemHelper(static_cast(list->object), /*newParentVariant=*/0, /*thisPointerVariant=*/0); +} + +/*! + Returns a list of this item's children. + + The items are sorted by stacking order. This takes into account both the + items' insertion order and their Z-values. + +*/ +QDeclarativeListProperty QGraphicsItemPrivate::childrenList() +{ + Q_Q(QGraphicsItem); + if (isObject) { + QGraphicsObject *that = static_cast(q); + return QDeclarativeListProperty(that, &children, QGraphicsItemPrivate::append); + } else { + //QGraphicsItem is not supported for this property + return QDeclarativeListProperty(); + } +} + +/*! + \internal + Returns the width of the item + Reimplemented by QGraphicsWidget +*/ +qreal QGraphicsItemPrivate::width() const +{ + return 0; +} + +/*! + \internal + Set the width of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::setWidth(qreal w) +{ + Q_UNUSED(w); +} + +/*! + \internal + Reset the width of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::resetWidth() +{ +} + +/*! + \internal + Returns the height of the item + Reimplemented by QGraphicsWidget +*/ +qreal QGraphicsItemPrivate::height() const +{ + return 0; +} + +/*! + \internal + Set the height of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::setHeight(qreal h) +{ + Q_UNUSED(h); +} + +/*! + \internal + Reset the height of the item + Reimplemented by QGraphicsWidget +*/ +void QGraphicsItemPrivate::resetHeight() +{ +} + /*! \property QGraphicsObject::parent \brief the parent of the item @@ -7639,6 +7725,23 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) \sa scale, rotation, QGraphicsItem::transformOriginPoint() */ +/*! + \fn void QGraphicsObject::widthChanged() + \internal +*/ + +/*! + \fn void QGraphicsObject::heightChanged() + \internal +*/ + +/*! + + \fn QGraphicsObject::childrenChanged() + + This signal gets emitted whenever the children list changes + \internal +*/ /*! \class QAbstractGraphicsShapeItem diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index d72833b..5023f60 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -547,6 +547,10 @@ class Q_GUI_EXPORT QGraphicsObject : public QObject, public QGraphicsItem Q_PROPERTY(qreal rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(qreal scale READ scale WRITE setScale NOTIFY scaleChanged) Q_PROPERTY(QPointF transformOriginPoint READ transformOriginPoint WRITE setTransformOriginPoint) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), QDeclarativeListProperty children READ childrenList DESIGNABLE false NOTIFY childrenChanged) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal width READ width WRITE setWidth NOTIFY widthChanged RESET resetWidth FINAL) + Q_PRIVATE_PROPERTY(QGraphicsItem::d_func(), qreal height READ height WRITE setHeight NOTIFY heightChanged RESET resetHeight FINAL) + Q_CLASSINFO("DefaultProperty", "children") Q_INTERFACES(QGraphicsItem) public: QGraphicsObject(QGraphicsItem *parent = 0); @@ -571,6 +575,9 @@ Q_SIGNALS: void zChanged(); void rotationChanged(); void scaleChanged(); + void childrenChanged(); + void widthChanged(); + void heightChanged(); protected: QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index ea04e0b..669ae1b 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -71,6 +71,62 @@ QT_BEGIN_NAMESPACE class QGraphicsItemPrivate; +#ifndef QDECLARATIVELISTPROPERTY +#define QDECLARATIVELISTPROPERTY +template +struct QDeclarativeListProperty { + typedef void (*AppendFunction)(QDeclarativeListProperty *, T*); + typedef int (*CountFunction)(QDeclarativeListProperty *); + typedef T *(*AtFunction)(QDeclarativeListProperty *, int); + typedef void (*ClearFunction)(QDeclarativeListProperty *); + + QDeclarativeListProperty() + : object(0), data(0), append(0), count(0), at(0), clear(0), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, QList &list) + : object(o), data(&list), append(qlist_append), count(qlist_count), at(qlist_at), + clear(qlist_clear), dummy1(0), dummy2(0) {} + QDeclarativeListProperty(QObject *o, void *d, AppendFunction a, CountFunction c = 0, AtFunction t = 0, + ClearFunction r = 0) + : object(o), data(d), append(a), count(c), at(t), clear(r), dummy1(0), dummy2(0) {} + + bool operator==(const QDeclarativeListProperty &o) const { + return object == o.object && + data == o.data && + append == o.append && + count == o.count && + at == o.at && + clear == o.clear; + } + + QObject *object; + void *data; + + AppendFunction append; + + CountFunction count; + AtFunction at; + + ClearFunction clear; + + void *dummy1; + void *dummy2; + +private: + static void qlist_append(QDeclarativeListProperty *p, T *v) { + ((QList *)p->data)->append(v); + } + static int qlist_count(QDeclarativeListProperty *p) { + return ((QList *)p->data)->count(); + } + static T *qlist_at(QDeclarativeListProperty *p, int idx) { + return ((QList *)p->data)->at(idx); + } + static void qlist_clear(QDeclarativeListProperty *p) { + return ((QList *)p->data)->clear(); + } +}; +#endif + class QGraphicsItemCache { public: @@ -237,6 +293,7 @@ public: void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); + QDeclarativeListProperty childrenList(); void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); @@ -423,11 +480,21 @@ public: inline QTransform transformToParent() const; inline void ensureSortedChildren(); + static void append(QDeclarativeListProperty *list, QGraphicsObject *item); static inline bool insertionOrder(QGraphicsItem *a, QGraphicsItem *b); void ensureSequentialSiblingIndex(); inline void sendScenePosChange(); virtual void siblingOrderChange(); + // Private Properties + virtual qreal width() const; + virtual void setWidth(qreal); + virtual void resetWidth(); + + virtual qreal height() const; + virtual void setHeight(qreal); + virtual void resetHeight(); + QRectF childrenBoundingRect; QRectF needsRepaint; QMap paintedViewBoundingRects; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index f42fe4f..a091347 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -324,6 +324,14 @@ void QGraphicsWidget::resize(const QSizeF &size) */ /*! + + \fn QGraphicsWidget::geometryChanged() + + This signal gets emitted whenever the geometry of the item changes + \internal +*/ + +/*! \property QGraphicsWidget::geometry \brief the geometry of the widget @@ -391,6 +399,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) QGraphicsSceneResizeEvent re; re.setOldSize(oldSize); re.setNewSize(newGeom.size()); + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); QApplication::sendEvent(this, &re); } } @@ -2322,5 +2334,7 @@ void QGraphicsWidget::dumpFocusChain() #endif QT_END_NAMESPACE + +#include "moc_qgraphicswidget.cpp" #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 1835c74..6e397b6 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -44,6 +44,7 @@ #ifndef QT_NO_GRAPHICSVIEW #include +#include #include "qgraphicswidget_p.h" #include "qgraphicslayout.h" #include "qgraphicsscene_p.h" @@ -825,6 +826,56 @@ void QGraphicsWidgetPrivate::setLayout_helper(QGraphicsLayout *l) } } +qreal QGraphicsWidgetPrivate::width() const +{ + Q_Q(const QGraphicsWidget); + return q->geometry().width(); +} + +void QGraphicsWidgetPrivate::setWidth(qreal w) +{ + if (qIsNaN(w)) + return; + Q_Q(QGraphicsWidget); + if (q->geometry().width() == w) + return; + + QRectF oldGeom = q->geometry(); + + q->setGeometry(QRectF(q->x(), q->y(), w, height())); +} + +void QGraphicsWidgetPrivate::resetWidth() +{ + Q_Q(QGraphicsWidget); + q->setGeometry(QRectF(q->x(), q->y(), 0, height())); +} + +qreal QGraphicsWidgetPrivate::height() const +{ + Q_Q(const QGraphicsWidget); + return q->geometry().height(); +} + +void QGraphicsWidgetPrivate::setHeight(qreal h) +{ + if (qIsNaN(h)) + return; + Q_Q(QGraphicsWidget); + if (q->geometry().height() == h) + return; + + QRectF oldGeom = q->geometry(); + + q->setGeometry(QRectF(q->x(), q->y(), width(), h)); +} + +void QGraphicsWidgetPrivate::resetHeight() +{ + Q_Q(QGraphicsWidget); + q->setGeometry(QRectF(q->x(), q->y(), width(), 0)); +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicswidget_p.h b/src/gui/graphicsview/qgraphicswidget_p.h index 2c5b3bf..f34a755 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.h +++ b/src/gui/graphicsview/qgraphicswidget_p.h @@ -130,6 +130,15 @@ public: void windowFrameHoverLeaveEvent(QGraphicsSceneHoverEvent *event); bool hasDecoration() const; + // Private Properties + qreal width() const; + void setWidth(qreal); + void resetWidth(); + + qreal height() const; + void setHeight(qreal); + void resetHeight(); + // State inline int attributeToBitIndex(Qt::WidgetAttribute att) const { diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index 0d1ad9e..5a3a54c 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -111,6 +111,8 @@ private slots: void fontPropagationSceneChange(); void geometry_data(); void geometry(); + void width(); + void height(); void getContentsMargins_data(); void getContentsMargins(); void initStyleOption_data(); @@ -775,6 +777,32 @@ void tst_QGraphicsWidget::geometry() QCOMPARE(widget.geometry(), QRectF(pos, size)); } +void tst_QGraphicsWidget::width() +{ + QGraphicsWidget w; + QCOMPARE(w.property("width").toReal(), qreal(0)); + QSignalSpy spy(&w, SIGNAL(widthChanged())); + w.setProperty("width", qreal(50)); + QCOMPARE(w.property("width").toReal(), qreal(50)); + QCOMPARE(spy.count(), 1); + //calling old school setGeometry should work too + w.setGeometry(0, 0, 200, 200); + QCOMPARE(spy.count(), 2); +} + +void tst_QGraphicsWidget::height() +{ + QGraphicsWidget w; + QCOMPARE(w.property("height").toReal(), qreal(0)); + QSignalSpy spy(&w, SIGNAL(heightChanged())); + w.setProperty("height", qreal(50)); + QCOMPARE(w.property("height").toReal(), qreal(50)); + QCOMPARE(spy.count(), 1); + //calling old school setGeometry should work too + w.setGeometry(0, 0, 200, 200); + QCOMPARE(spy.count(), 2); +} + void tst_QGraphicsWidget::getContentsMargins_data() { QTest::addColumn("left"); -- cgit v0.12 From 96bd304a62f88dc097d5ac4f16d60fd8751227fd Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 24 Mar 2010 13:52:57 +0100 Subject: Stabilize QGraphicsEffect test on X11 --- tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp index 02899ae..49b840f 100644 --- a/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp +++ b/tests/auto/qgraphicseffect/tst_qgraphicseffect.cpp @@ -512,6 +512,7 @@ void tst_QGraphicsEffect::drawPixmapItem() QGraphicsView view(&scene); view.show(); QTest::qWaitForWindowShown(&view); + QTRY_VERIFY(effect->repaints >= 1); item->rotate(180); QTest::qWait(50); @@ -642,7 +643,7 @@ void tst_QGraphicsEffect::childrenVisibilityShouldInvalidateCache() view.show(); QApplication::setActiveWindow(&view); QTest::qWaitForWindowShown(&view); - QCOMPARE(parent.nbPaint, 1); + QTRY_COMPARE(parent.nbPaint, 1); //we set an effect on the parent parent.setGraphicsEffect(new QGraphicsDropShadowEffect(&parent)); //flush the events -- cgit v0.12