diff options
author | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-04-17 19:34:29 (GMT) |
---|---|---|
committer | Denis Dzyubenko <denis.dzyubenko@nokia.com> | 2009-05-11 14:51:49 (GMT) |
commit | 0cc862890384929c4c3b07c6dc5787362f3aeb9c (patch) | |
tree | a6212c08819746e7ca6887c2d5dd74f578d3a104 | |
parent | ff58f277fdbe83f3ce958dca17da4d90b37d1050 (diff) | |
download | Qt-0cc862890384929c4c3b07c6dc5787362f3aeb9c.zip Qt-0cc862890384929c4c3b07c6dc5787362f3aeb9c.tar.gz Qt-0cc862890384929c4c3b07c6dc5787362f3aeb9c.tar.bz2 |
Implemented delaying and replaying mouse events when gesture is about
to start.
-rw-r--r-- | src/gui/kernel/qgesturemanager.cpp | 121 | ||||
-rw-r--r-- | src/gui/kernel/qgesturemanager_p.h | 3 |
2 files changed, 102 insertions, 22 deletions
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 54c32ea..bb0ee6d 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -62,10 +62,13 @@ QT_BEGIN_NAMESPACE bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); -static const unsigned int maximumGestureRecognitionTimeout = 2000; +static const unsigned int MaximumGestureRecognitionTimeout = 2000; +static const unsigned int DelayedPressTimeout = 300; QGestureManager::QGestureManager(QObject *parent) - : QObject(parent), targetWidget(0), state(NotGesture) + : QObject(parent), targetWidget(0), delayedPressTimer(0), + lastMousePressEvent(QEvent::None, QPoint(), Qt::NoButton, 0, 0), + state(NotGesture) { qRegisterMetaType<Qt::DirectionType>(); qRegisterMetaType<Qt::GestureState>(); @@ -147,7 +150,7 @@ bool QGestureManager::filterEvent(QEvent *event) } foreach(QGestureRecognizer *r, newMaybeGestures) { if (!maybeGestures.contains(r)) { - int timerId = startTimer(maximumGestureRecognitionTimeout); + int timerId = startTimer(MaximumGestureRecognitionTimeout); if (!timerId) qWarning("QGestureManager: couldn't start timer!"); maybeGestures.insert(r, timerId); @@ -248,7 +251,7 @@ bool QGestureManager::filterEvent(QEvent *event) } foreach(QGestureRecognizer *r, newMaybeGestures) { if (!maybeGestures.contains(r)) { - int timerId = startTimer(maximumGestureRecognitionTimeout); + int timerId = startTimer(MaximumGestureRecognitionTimeout); if (!timerId) qWarning("QGestureManager: couldn't start timer!"); maybeGestures.insert(r, timerId); @@ -296,31 +299,100 @@ bool QGestureManager::filterEvent(QEvent *event) } } + if (delayedPressTimer && state == Gesture) { + DEBUG() << "QGestureManager: gesture started. Forgetting about postponed mouse press event"; + killTimer(delayedPressTimer); + delayedPressTimer = 0; + } else if (delayedPressTimer && (state == NotGesture || + event->type() == QEvent::MouseButtonRelease)) { + // not a gesture or released button too fast, so replay press + // event back. + DEBUG() << "QGestureManager: replaying mouse press event"; + QMap<QGestureRecognizer*, int>::const_iterator it = maybeGestures.begin(), + e = maybeGestures.end();; + for (; it != e; ++it) { + it.key()->reset(); + killTimer(it.value()); + } + maybeGestures.clear(); + state = NotGesture; + + Q_ASSERT(targetWidget != 0); + QApplication::sendEvent(targetWidget, &lastMousePressEvent); + if (event->type() == QEvent::MouseButtonRelease) { + QMouseEvent *me = static_cast<QMouseEvent*>(event); + QMouseEvent move(QEvent::MouseMove, me->pos(), me->globalPos(), me->button(), + me->buttons(), me->modifiers()); + QApplication::sendEvent(targetWidget, &move); + ret = false; + } + killTimer(delayedPressTimer); + delayedPressTimer = 0; + } else if (state == MaybeGesture && event->type() == QEvent::MouseButtonPress) { + // postpone the press event delivery until we know for + // sure whether it is a gesture. + DEBUG() << "QGestureManager: postponing mouse press event"; + QMouseEvent *me = static_cast<QMouseEvent*>(event); + lastMousePressEvent = QMouseEvent(QEvent::MouseButtonPress, me->pos(), + me->globalPos(), me->button(), + me->buttons(), me->modifiers()); + Q_ASSERT(delayedPressTimer == 0); + delayedPressTimer = startTimer(DelayedPressTimeout); + if (!delayedPressTimer) + qWarning("QGestureManager: couldn't start delayed press timer!"); + } + // if we have postponed a mouse press event, postpone all + // following event + if (delayedPressTimer) + ret = true; + lastPos = currentPos; return ret; } void QGestureManager::timerEvent(QTimerEvent *event) { - // sanity checks, remove later - Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty())); - - typedef QMap<QGestureRecognizer*, int> MaybeGestureMap; - for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end(); - it != e; ++it) { - if (it.value() == event->timerId()) { - DEBUG() << "QGestureManager: gesture timeout."; - QGestureRecognizer *r = it.key(); - r->reset(); - maybeGestures.erase(it); - killTimer(event->timerId()); - break; + if (event->timerId() == delayedPressTimer) { + DEBUG() << "QGestureManager: replaying mouse press event due to timeout"; + // sanity checks + Q_ASSERT(state != Gesture); + + QMap<QGestureRecognizer*, int>::const_iterator it = maybeGestures.begin(), + e = maybeGestures.end();; + for (; it != e; ++it) { + it.key()->reset(); + killTimer(it.value()); } - } - - if (state == MaybeGesture && maybeGestures.isEmpty()) { - DEBUG() << "QGestureManager: new state = NotGesture because of timeout"; + maybeGestures.clear(); state = NotGesture; + + // we neither received a mouse release event nor gesture + // started, so we replay stored mouse press event. + QApplication::sendEvent(targetWidget, &lastMousePressEvent); + + killTimer(delayedPressTimer); + delayedPressTimer = 0; + } else { + // sanity checks, remove later + Q_ASSERT((state == Gesture && !activeGestures.isEmpty()) || (state != Gesture && activeGestures.isEmpty())); + + typedef QMap<QGestureRecognizer*, int> MaybeGestureMap; + for (MaybeGestureMap::iterator it = maybeGestures.begin(), e = maybeGestures.end(); + it != e; ++it) { + if (it.value() == event->timerId()) { + DEBUG() << "QGestureManager: gesture timeout."; + QGestureRecognizer *r = it.key(); + r->reset(); + maybeGestures.erase(it); + killTimer(event->timerId()); + break; + } + } + + if (state == MaybeGesture && maybeGestures.isEmpty()) { + DEBUG() << "QGestureManager: new state = NotGesture because of timeout"; + state = NotGesture; + } } } @@ -378,7 +450,7 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) sendGestureEvent(targetWidget, &event); } if (!maybeGestures.contains(recognizer)) { - int timerId = startTimer(maximumGestureRecognitionTimeout); + int timerId = startTimer(MaximumGestureRecognitionTimeout); if (!timerId) qWarning("QGestureManager: couldn't start timer!"); maybeGestures.insert(recognizer, timerId); @@ -396,6 +468,11 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result) default: Q_ASSERT(false); } + + if (delayedPressTimer && state == Gesture) { + killTimer(delayedPressTimer); + delayedPressTimer = 0; + } } bool QGestureManager::sendGestureEvent(QWidget *receiver, QGestureEvent *event) diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index 2500ecf..ef3cdaf 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -94,6 +94,9 @@ private: QWidget *targetWidget; QPoint lastPos; + int delayedPressTimer; + QMouseEvent lastMousePressEvent; + enum State { Gesture, NotGesture, |