aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickdrag.cpp
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-03-02 12:58:45 +1000
committerQt by Nokia <qt-info@nokia.com>2012-05-25 14:44:05 +0200
commit7f626e206614f6030ee0fc994eb9b3602f133d87 (patch)
treea212d0f4eae0535ebba56f9f9d848a4dfdab856e /src/quick/items/qquickdrag.cpp
parent9ce3a474e6eae130aa3d1c28e84f934dc3f01d19 (diff)
Don't deliver drag move events immediately.
Rather than delivering drag move events everytime the position of an item changes queue up an event to process in the event loop. This filters out noisy intermediate positions particularly where the x and y values are set independently and better insulates against feedback. Change-Id: I5d787d63ed01441a9080d0daaee9db1373d5f073 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/quick/items/qquickdrag.cpp')
-rw-r--r--src/quick/items/qquickdrag.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp
index ca7b716ef2..bc9732b6b3 100644
--- a/src/quick/items/qquickdrag.cpp
+++ b/src/quick/items/qquickdrag.cpp
@@ -45,6 +45,7 @@
#include <QtQuick/private/qquickevents_p_p.h>
#include <private/qquickitemchangelistener_p.h>
#include <private/qv8engine_p.h>
+#include <QtCore/qcoreapplication.h>
#include <QtQml/qqmlinfo.h>
#include <QtGui/qevent.h>
@@ -65,10 +66,13 @@ public:
, active(false)
, listening(false)
, inEvent(false)
+ , itemMoved(false)
+ , eventQueued(false)
{
}
void itemGeometryChanged(QQuickItem *, const QRectF &, const QRectF &);
+ void deliverMoveEvent();
void deliverEvent(QQuickCanvas *canvas, QEvent *event);
void start() { start(supportedActions); }
void start(Qt::DropActions supportedActions);
@@ -85,6 +89,8 @@ public:
bool active : 1;
bool listening : 1;
bool inEvent : 1;
+ bool itemMoved : 1;
+ bool eventQueued : 1;
QPointF hotSpot;
QStringList keys;
};
@@ -119,9 +125,22 @@ public:
void QQuickDragAttachedPrivate::itemGeometryChanged(QQuickItem *, const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_Q(QQuickDragAttached);
- if (newGeometry.topLeft() == oldGeometry.topLeft() || !active || inEvent)
+ if (newGeometry.topLeft() == oldGeometry.topLeft() || !active || itemMoved)
return;
+ itemMoved = true;
+
+ if (!eventQueued) {
+ eventQueued = true;
+ QCoreApplication::postEvent(q, new QEvent(QEvent::User));
+ }
+}
+
+void QQuickDragAttachedPrivate::deliverMoveEvent()
+{
+ Q_Q(QQuickDragAttached);
+
+ itemMoved = false;
if (QQuickCanvas *canvas = attachedItem->canvas()) {
QPoint scenePos = attachedItem->mapToScene(hotSpot).toPoint();
QDragMoveEvent event(scenePos, mimeData->m_supportedActions, mimeData, Qt::NoButton, Qt::NoModifier);
@@ -142,6 +161,20 @@ void QQuickDragAttachedPrivate::deliverEvent(QQuickCanvas *canvas, QEvent *event
inEvent = false;
}
+bool QQuickDragAttached::event(QEvent *event)
+{
+ Q_D(QQuickDragAttached);
+
+ if (event->type() == QEvent::User) {
+ d->eventQueued = false;
+ if (d->itemMoved)
+ d->deliverMoveEvent();
+ return true;
+ } else {
+ return QObject::event(event);
+ }
+}
+
QQuickDragAttached::QQuickDragAttached(QObject *parent)
: QObject(*new QQuickDragAttachedPrivate, parent)
{
@@ -260,8 +293,17 @@ void QQuickDragAttached::setHotSpot(const QPointF &hotSpot)
Q_D(QQuickDragAttached);
if (d->hotSpot != hotSpot) {
d->hotSpot = hotSpot;
+
+ if (d->active) {
+ d->itemMoved = true;
+
+ if (!d->eventQueued) {
+ d->eventQueued = true;
+ QCoreApplication::postEvent(this, new QEvent(QEvent::User));
+ }
+ }
+
emit hotSpotChanged();
- // Send a move event if active?
}
}
@@ -428,6 +470,9 @@ int QQuickDragAttached::drop()
return acceptedAction;
}
+ if (d->itemMoved)
+ d->deliverMoveEvent();
+
if (!d->active)
return acceptedAction;
d->active = false;
@@ -475,6 +520,7 @@ void QQuickDragAttached::cancel()
if (!d->active)
return;
d->active = false;
+ d->itemMoved = false;
if (QQuickCanvas *canvas = d->attachedItem->canvas()) {
QDragLeaveEvent event;