Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[qtdeclarative] Fix touch to mouse synthesis/propagation.
  • Loading branch information
martinjones committed Oct 28, 2013
1 parent 22b4145 commit 42284e3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
7 changes: 4 additions & 3 deletions qtdeclarative/src/quick/items/qquickflickable.cpp
Expand Up @@ -1243,6 +1243,7 @@ void QQuickFlickable::mouseMoveEvent(QMouseEvent *event)
{
Q_D(QQuickFlickable);
if (d->interactive) {
d->handleMouseMoveEvent(event);
if (d->delayedPressEvent) {
// A move beyond the threshold replays the press to give nested Flickables
// the opportunity to grab the gesture.
Expand All @@ -1252,7 +1253,6 @@ void QQuickFlickable::mouseMoveEvent(QMouseEvent *event)
d->replayDelayedPress();
}
}
d->handleMouseMoveEvent(event);
event->accept();
} else {
QQuickItem::mouseMoveEvent(event);
Expand Down Expand Up @@ -2084,12 +2084,13 @@ bool QQuickFlickable::sendMouseEvent(QQuickItem *item, QMouseEvent *event)
if ((grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) || grabberDisabled) {
d->clearDelayedPress();
grabMouse();
} else if (d->delayedPressEvent) {
grabMouse();
}

// Do not accept this event when filtering, as this would force the mouse grab to the child
const bool filtered = stealThisEvent || d->delayedPressEvent || grabberDisabled;
if (filtered) {
event->setAccepted(false);
event->setAccepted(true);
}
return filtered;
} else if (d->lastPosTime != -1) {
Expand Down
10 changes: 1 addition & 9 deletions qtdeclarative/src/quick/items/qquickitem.cpp
Expand Up @@ -6612,15 +6612,7 @@ void QQuickItem::grabMouse()
if (!d->window)
return;
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
if (windowPriv->mouseGrabberItem == this)
return;

QQuickItem *oldGrabber = windowPriv->mouseGrabberItem;
windowPriv->mouseGrabberItem = this;
if (oldGrabber) {
QEvent ev(QEvent::UngrabMouse);
d->window->sendEvent(oldGrabber, &ev);
}
windowPriv->setMouseGrabber(this);
}

/*!
Expand Down
36 changes: 31 additions & 5 deletions qtdeclarative/src/quick/items/qquickwindow.cpp
Expand Up @@ -567,6 +567,28 @@ bool QQuickWindowPrivate::translateTouchToMouse(QQuickItem *item, QTouchEvent *e
return false;
}

void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
{
Q_Q(QQuickWindow);
if (mouseGrabberItem == grabber)
return;

QQuickItem *oldGrabber = mouseGrabberItem;
mouseGrabberItem = grabber;

if (touchMouseId != -1) {
// update the touch item for mouse touch id to the new grabber
itemForTouchPointId.remove(touchMouseId);
if (grabber)
itemForTouchPointId[touchMouseId] = grabber;
}

if (oldGrabber) {
QEvent ev(QEvent::UngrabMouse);
q->sendEvent(oldGrabber, &ev);
}
}

void QQuickWindowPrivate::transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform)
{
QMatrix4x4 transformMatrix(transform);
Expand Down Expand Up @@ -1283,8 +1305,11 @@ bool QQuickWindow::event(QEvent *e)
case QEvent::TouchEnd: {
QTouchEvent *touch = static_cast<QTouchEvent*>(e);
d->translateTouchEvent(touch);
// return in order to avoid the QWindow::event below
return d->deliverTouchEvent(touch);
d->deliverTouchEvent(touch);
// we consume all touch events ourselves to avoid duplicate
// mouse delivery by QtGui mouse synthesis
e->accept();
return true;
}
break;
case QEvent::TouchCancel:
Expand Down Expand Up @@ -1831,7 +1856,10 @@ bool QQuickWindowPrivate::deliverMatchingPointsToItem(QQuickItem *item, QTouchEv
// First check whether the parent wants to be a filter,
// and if the parent accepts the event we are done.
if (sendFilteredTouchEvent(item->parentItem(), item, event)) {
event->accept();
// If the touch was accepted (regardless by whom or in what form),
// update acceptedNewPoints.
foreach (int id, matchingNewPoints)
acceptedNewPoints->insert(id);
return true;
}

Expand Down Expand Up @@ -2131,13 +2159,11 @@ bool QQuickWindowPrivate::sendFilteredTouchEvent(QQuickItem *target, QQuickItem
t = QEvent::MouseMove;
break;
}

// targetEvent is already transformed wrt local position, velocity, etc.
QScopedPointer<QMouseEvent> mouseEvent(touchToMouseEvent(t, targetEvent->touchPoints().first(), event, item, false));
if (target->childMouseEventFilter(item, mouseEvent.data())) {
itemForTouchPointId[tp.id()] = target;
touchMouseId = tp.id();
target->grabMouse();
return true;
}
}
Expand Down
1 change: 1 addition & 0 deletions qtdeclarative/src/quick/items/qquickwindow_p.h
Expand Up @@ -161,6 +161,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickWindowPrivate : public QWindowPrivate
QPointF lastMousePosition;
bool translateTouchToMouse(QQuickItem *item, QTouchEvent *event);
void translateTouchEvent(QTouchEvent *touchEvent);
void setMouseGrabber(QQuickItem *grabber);
static void transformTouchPoints(QList<QTouchEvent::TouchPoint> &touchPoints, const QTransform &transform);
static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0);
bool deliverInitialMousePressEvent(QQuickItem *, QMouseEvent *);
Expand Down

0 comments on commit 42284e3

Please sign in to comment.