summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qapplication.cpp31
-rw-r--r--src/gui/kernel/qevent.cpp51
-rw-r--r--src/gui/kernel/qevent.h11
-rw-r--r--src/gui/kernel/qgesture.cpp2
-rw-r--r--src/gui/kernel/qgesture.h8
-rw-r--r--src/gui/kernel/qgesture_p.h3
-rw-r--r--src/gui/kernel/qgesturemanager.cpp120
-rw-r--r--src/gui/kernel/qgesturemanager_p.h3
8 files changed, 167 insertions, 62 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index 9772e0f..ba105e0 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -4019,37 +4019,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
}
break;
#endif
-
- case QEvent::Gesture: {
- QWidget *w = static_cast<QWidget*>(receiver);
- QGestureEvent *ge = static_cast<QGestureEvent*>(e);
- QSet<QString> eventGestures;
- foreach(const QString &gesture, ge->gestureTypes())
- eventGestures << gesture;
- bool eventAccepted = ge->isAccepted();
-
- QPoint offset;
- while (w) {
- QSet<int> widgetGestures = w->d_func()->gestures;
- foreach(int gestureId, widgetGestures) {
- if (eventGestures.contains(QGestureManager::instance()->gestureNameFromId(gestureId))) {
- foreach(QGesture *gesture, ge->gestures())
- gesture->translate(offset);
- offset = QPoint();
- res = d->notify_helper(w, ge);
- ge->spont = false;
- eventAccepted = ge->isAccepted();
- if (res && eventAccepted)
- break;
- }
- }
- if (w->isWindow())
- break;
- offset += w->pos();
- w = w->parentWidget();
- }
- break;
- }
case QEvent::TouchBegin:
// Note: TouchUpdate and TouchEnd events are sent to d->currentMultitouchWidget and never propagated
{
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index f24f186..fa85bf2 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -3532,10 +3532,11 @@ QMenubarUpdatedEvent::QMenubarUpdatedEvent(QMenuBar * const menuBar)
are being executed and a list of gesture that were cancelled (\a
cancelledGestures).
*/
-QGestureEvent::QGestureEvent(const QList<QGesture*> &gestures,
+QGestureEvent::QGestureEvent(const QSet<QGesture*> &gestures,
const QSet<QString> &cancelledGestures)
: QEvent(QEvent::Gesture), m_cancelledGestures(cancelledGestures)
{
+ setAccepted(false);
foreach(QGesture *r, gestures)
m_gestures.insert(r->type(), r);
}
@@ -3606,6 +3607,54 @@ QSet<QString> QGestureEvent::cancelledGestures() const
return m_cancelledGestures;
}
+/*!
+ Sets the accept flag of the all gestures inside the event object,
+ the equivalent of calling \l{QEvent::accept()}{accept()} or
+ \l{QEvent::setAccepted()}{setAccepted(true)}.
+
+ Setting the accept parameter indicates that the event receiver
+ wants the gesture. Unwanted gestures might be propagated to the parent
+ widget.
+*/
+void QGestureEvent::acceptAll()
+{
+ QHash<QString, QGesture*>::iterator it = m_gestures.begin(),
+ e = m_gestures.end();
+ for(; it != e; ++it)
+ it.value()->accept();
+ setAccepted(true);
+}
+
+/*!
+ Sets the accept flag of the specified gesture inside the event
+ object, the equivalent of calling
+ \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()}
+
+ Setting the accept parameter indicates that the event receiver
+ wants the gesture. Unwanted gestures might be propagated to the parent
+ widget.
+*/
+void QGestureEvent::accept(Qt::GestureType type)
+{
+ if (QGesture *g = m_gestures.value(qt_getStandardGestureTypeName(type), 0))
+ g->accept();
+}
+
+/*!
+ Sets the accept flag of the specified gesture inside the event
+ object, the equivalent of calling
+ \l{QGestureEvent::gesture()}{gesture(type)}->\l{QGesture::accept()}{accept()}
+
+ Setting the accept parameter indicates that the event receiver
+ wants the gesture. Unwanted gestures might be propagated to the parent
+ widget.
+*/
+void QGestureEvent::accept(const QString &type)
+{
+ if (QGesture *g = m_gestures.value(type, 0))
+ g->accept();
+}
+
/*! \class QTouchEvent
\brief The QTouchEvent class contains parameters that describe a touch event
.
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 666cd3f..ea4f577 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -716,7 +716,7 @@ private:
class Q_GUI_EXPORT QGestureEvent : public QEvent
{
public:
- QGestureEvent(const QList<QGesture*> &gestures,
+ QGestureEvent(const QSet<QGesture*> &gestures,
const QSet<QString> &cancelledGestures = QSet<QString>());
~QGestureEvent();
@@ -731,6 +731,15 @@ public:
QSet<QString> cancelledGestures() const;
+ void acceptAll();
+#ifndef Q_NO_USING_KEYWORD
+ using QEvent::accept;
+#else
+ inline void accept() { QEvent::accept(); }
+#endif
+ void accept(Qt::GestureType type);
+ void accept(const QString &type);
+
protected:
QHash<QString, QGesture*> m_gestures;
QSet<QString> m_cancelledGestures;
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index 4d492f8..7437ed3 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -79,7 +79,7 @@ QString qt_getStandardGestureTypeName(Qt::GestureType type);
QGestureRecognizer classes.
*/
QGesture::QGesture(QObject *parent, const QString &type, Qt::GestureState state)
- : QObject(*new QGesturePrivate, parent)
+ : QObject(*new QGesturePrivate, parent), m_accept(0)
{
Q_D(QGesture);
d->type = type;
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index da1bc90..d220232 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -82,6 +82,12 @@ public:
uint duration, Qt::GestureState state);
virtual ~QGesture();
+ inline void setAccepted(bool accepted) { m_accept = accepted; }
+ inline bool isAccepted() const { return m_accept; }
+
+ inline void accept() { m_accept = true; }
+ inline void ignore() { m_accept = false; }
+
QString type() const;
Qt::GestureState state() const;
@@ -100,6 +106,8 @@ protected:
virtual void translate(const QPoint &offset);
private:
+ ushort m_accept : 1;
+
friend class QGestureManager;
friend class QApplication;
friend class QGestureRecognizerPan;
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 22d6d7f..d2d77cc 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -66,7 +66,7 @@ class QGesturePrivate : public QObjectPrivate
public:
QGesturePrivate()
- : duration(0) { }
+ : state(Qt::NoGesture), singleshot(0), duration(0) { }
void init(const QPoint &startPos, const QPoint &lastPos,
const QPoint &pos, const QRect &rect,
@@ -86,6 +86,7 @@ public:
Qt::GestureState state;
QPointer<QWidget> widget;
+ uint singleshot:1;
QRect rect;
QPoint hotSpot;
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index a93248a..c7341f2 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -166,14 +166,18 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
DEBUG() << "QGestureManager: sending gesture event for: "
<< activeGestures << " and " << finishedGestures;
- QList<QGesture*> gestures;
+ QSet<QGesture*> gestures;
foreach(QGestureRecognizer *r, finishedGestures) {
- if (QGesture *gesture = r->getGesture())
+ if (QGesture *gesture = r->getGesture()) {
gestures << gesture;
+ gesture->d_func()->singleshot = true;
+ }
}
foreach(QGestureRecognizer *r, activeGestures) {
- if (QGesture *gesture = r->getGesture())
+ if (QGesture *gesture = r->getGesture()) {
gestures << gesture;
+ gesture->d_func()->singleshot = false;
+ }
}
Q_ASSERT(!gestures.isEmpty());
ret = sendGestureEvent(receiver, gestures);
@@ -243,7 +247,6 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
activeGestures -= newMaybeGestures;
activeGestures -= cancelledGestures;
- activeGestures -= finishedGestures;
activeGestures += startedGestures;
foreach(QGestureRecognizer *r, startedGestures+finishedGestures+notGestures) {
QMap<QGestureRecognizer*, int>::iterator it = maybeGestures.find(r);
@@ -260,7 +263,7 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
maybeGestures.insert(r, timerId);
}
}
- QList<QGesture*> gestures;
+ QSet<QGesture*> gestures;
if (!finishedGestures.isEmpty() || !activeGestures.isEmpty()) {
// another gesture found!
ret = true;
@@ -268,12 +271,17 @@ bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
<< activeGestures << " and " << finishedGestures;
foreach(QGestureRecognizer *r, finishedGestures) {
- if (QGesture *gesture = r->getGesture())
+ if (QGesture *gesture = r->getGesture()) {
gestures << gesture;
+ gesture->d_func()->singleshot = activeGestures.contains(r);
+ }
}
+ activeGestures -= finishedGestures;
foreach(QGestureRecognizer *r, activeGestures) {
- if (QGesture *gesture = r->getGesture())
+ if (QGesture *gesture = r->getGesture()) {
gestures << gesture;
+ gesture->d_func()->singleshot = false;
+ }
}
}
QSet<QString> cancelledGestureNames;
@@ -439,7 +447,7 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result)
killTimer(maybeGestures.value(recognizer));
maybeGestures.remove(recognizer);
}
- QList<QGesture*> gestures;
+ QSet<QGesture*> gestures;
if (QGesture *gesture = recognizer->getGesture())
gestures << gesture;
if(!gestures.isEmpty()) {
@@ -452,7 +460,7 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result)
case QGestureRecognizer::MaybeGesture: {
DEBUG() << "QGestureManager: maybe gesture: " << recognizer;
if (activeGestures.contains(recognizer)) {
- //FIXME: sendGestureEvent(targetWidget, QList<QGesture*>(), QSet<QString>() << recognizer->gestureType());
+ //FIXME: sendGestureEvent(targetWidget, QSet<QGesture*>(), QSet<QString>() << recognizer->gestureType());
}
if (!maybeGestures.contains(recognizer)) {
int timerId = startTimer(MaximumGestureRecognitionTimeout);
@@ -480,43 +488,63 @@ void QGestureManager::recognizerStateChanged(QGestureRecognizer::Result result)
}
}
-bool QGestureManager::sendGestureEvent(QWidget *receiver, const QList<QGesture*> &gestures,
+bool QGestureManager::widgetHasGesture(QWidget *widget, QGesture *gesture) const
+{
+ const QString gestureName = gesture->type();
+ QSet<int>::iterator it = widget->d_func()->gestures.begin(),
+ e = widget->d_func()->gestures.end();
+ for (; it != e; ++it) {
+ if (gestureNameFromId(*it) == gestureName)
+ return true;
+ }
+ return false;
+}
+
+bool QGestureManager::sendGestureEvent(QWidget *receiver, const QSet<QGesture*> &gestures,
const QSet<QString> &cancelled)
{
- typedef QMap<QWidget*, QList<QGesture*> > WidgetGesturesMap;
+ if (gestures.isEmpty())
+ return false;
+ DEBUG() << "QGestureManager::sendGestureEvent: sending to" << receiver
+ << "gestures:" << gestures << "; cancelled:" << cancelled;
+ QSet<QGesture*> startedGestures;
+ // grouping gesture objects by receiver widgets.
+ typedef QMap<QWidget*, QSet<QGesture*> > WidgetGesturesMap;
WidgetGesturesMap widgetGestures;
- for(QList<QGesture*>::const_iterator it = gestures.begin(), e = gestures.end();
+ for(QSet<QGesture*>::const_iterator it = gestures.begin(), e = gestures.end();
it != e; ++it) {
QGesture *g = *it;
QGesturePrivate *gd = g->d_func();
- if (g->state() == Qt::GestureStarted) {
+ if (!gd->widget && (g->state() == Qt::GestureStarted || g->state() == Qt::GestureFinished)) {
+ startedGestures.insert(g);
// find the target widget
QWidget *w = receiver;
+ QPoint offset;
while (w) {
- QSet<int>::iterator it = w->d_func()->gestures.begin(),
- e = w->d_func()->gestures.end();
- for (; it != e; ++it) {
- if (gestureNameFromId(*it) == g->type())
- break;
- }
- if (it != e)
+ if (widgetHasGesture(w, g))
break;
+ if (w->isWindow()) {
+ w = 0;
+ break;
+ }
+ offset += w->pos();
w = w->parentWidget();
}
if (!w) // no widget in the tree that accepts this gesture.
continue;
gd->widget = w;
+ g->translate(offset);
}
if (!gd->widget) {
DEBUG() << "QGestureManager: didn't find a widget to send gesture event ("
<< g->type() << ") for tree:" << receiver;
+ // TODO: maybe we should reset gesture recognizers when nobody interested in its gestures.
continue;
}
- widgetGestures[gd->widget].append(g);
+ widgetGestures[gd->widget].insert(g);
}
- // we return true and stop original from being delivered if any of
- // the gesture events were accepted by a receiver.
+ QSet<QGesture*> ignoredGestures;
bool ret = false;
for(WidgetGesturesMap::const_iterator it = widgetGestures.begin(), e = widgetGestures.end();
it != e; ++it) {
@@ -524,10 +552,50 @@ bool QGestureManager::sendGestureEvent(QWidget *receiver, const QList<QGesture*>
Q_ASSERT(receiver != 0 /*should be taken care above*/);
// TODO: send cancelled gesture event to the widget that received the original gesture!
QGestureEvent event(it.value(), cancelled);
- if (qt_sendSpontaneousEvent(receiver, &event) && event.isAccepted())
- ret = true;
+ bool processed = qt_sendSpontaneousEvent(receiver, &event);
+ QSet<QGesture*> started = startedGestures.intersect(it.value());
+ if (!started.isEmpty() && !(processed && event.isAccepted())) {
+ // there are started gestures event that weren't
+ // accepted, so propagating each gesture independently.
+ QSet<QGesture*>::const_iterator it = started.begin(),
+ e = started.end();
+ for(; it != e; ++it) {
+ QGesture *g = *it;
+ if (processed && g->isAccepted()) {
+ ret = true;
+ continue;
+ }
+ // if it wasn't accepted, find the first parent widget
+ // that is subscribed to the gesture.
+ QGesturePrivate *gd = g->d_func();
+ QWidget *w = gd->widget;
+ gd->widget = 0;
+
+ if (!w->isWindow()) {
+ g->translate(w->pos());
+ w = w->parentWidget();
+ QPoint offset;
+ while (w) {
+ if (widgetHasGesture(w, g)) {
+ DEBUG() << "QGestureManager: sendGestureEvent:" << w << "didn't accept gesture" << g;
+ ignoredGestures.insert(g);
+ break;
+ }
+ if (w->isWindow()) {
+ w = 0;
+ break;
+ }
+ offset += w->pos();
+ w = w->parentWidget();
+ }
+ if (w)
+ g->translate(offset);
+ }
+ }
+ }
}
- return ret;
+ // try to send all gestures that were ignored to the next parent
+ return sendGestureEvent(0, ignoredGestures, cancelled) || ret;
}
int QGestureManager::eventDeliveryDelay() const
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index beed323..963edf9 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -93,7 +93,8 @@ private slots:
void recognizerStateChanged(QGestureRecognizer::Result);
private:
- bool sendGestureEvent(QWidget *receiver, const QList<QGesture*> &gestures,
+ bool widgetHasGesture(QWidget *widget, QGesture *gesture) const;
+ bool sendGestureEvent(QWidget *receiver, const QSet<QGesture*> &gestures,
const QSet<QString> &cancelled = QSet<QString>());
QSet<QGestureRecognizer*> activeGestures;