summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorJan-Arve Sæther <jan-arve.saether@nokia.com>2009-10-28 06:53:39 (GMT)
committerJan-Arve Sæther <jan-arve.saether@nokia.com>2009-10-28 06:53:39 (GMT)
commit262d0df3b166fecb3502e81b2ab85cadd71ae70f (patch)
tree17f8cba9c8f1ff4f46b45386c79ff9ebb3f998be /src/gui/kernel
parentdf0001a3d62938c713b351c7e59228b803ec5670 (diff)
parent1607216cc6292ef9a4af68ce6d29dc79fffea92c (diff)
downloadQt-262d0df3b166fecb3502e81b2ab85cadd71ae70f.zip
Qt-262d0df3b166fecb3502e81b2ab85cadd71ae70f.tar.gz
Qt-262d0df3b166fecb3502e81b2ab85cadd71ae70f.tar.bz2
Merge branch 'fixes' of git://gitorious.org/~fleury/qt/fleury-openbossa-clone into openbossa-fleury-fixes3
Conflicts: src/gui/graphicsview/qgraphicsanchorlayout_p.cpp src/gui/graphicsview/qgraphicsanchorlayout_p.h
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qapplication.cpp40
-rw-r--r--src/gui/kernel/qapplication_win.cpp2
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm7
-rw-r--r--src/gui/kernel/qevent.cpp78
-rw-r--r--src/gui/kernel/qevent.h13
-rw-r--r--src/gui/kernel/qevent_p.h14
-rw-r--r--src/gui/kernel/qgesture.cpp26
-rw-r--r--src/gui/kernel/qgesture.h22
-rw-r--r--src/gui/kernel/qgesture_p.h9
-rw-r--r--src/gui/kernel/qgesturemanager.cpp414
-rw-r--r--src/gui/kernel/qgesturemanager_p.h18
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp2
-rw-r--r--src/gui/kernel/qmacgesturerecognizer_mac.mm8
-rw-r--r--src/gui/kernel/qstandardgestures.cpp12
-rw-r--r--src/gui/kernel/qwidget.cpp24
-rw-r--r--src/gui/kernel/qwidget_mac.mm2
-rw-r--r--src/gui/kernel/qwidget_p.h13
-rw-r--r--src/gui/kernel/qwidget_win.cpp4
-rw-r--r--src/gui/kernel/qwidget_x11.cpp2
-rw-r--r--src/gui/kernel/qwinnativepangesturerecognizer_win.cpp8
20 files changed, 464 insertions, 254 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index c4249d9..7c38d4b 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -3639,8 +3639,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
// walk through parents and check for gestures
if (d->gestureManager) {
- if (d->gestureManager->filterEvent(receiver, e))
- return true;
+ if (receiver->isWidgetType()) {
+ if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else if (QGesture *gesture = qobject_cast<QGesture *>(receiver)) {
+ if (d->gestureManager->filterEvent(gesture, e))
+ return true;
+ }
}
@@ -4165,40 +4170,41 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
if (wd->gestureContext.contains(type)) {
allGestures.removeAt(i);
gestures.append(g);
- gestureEvent->setAccepted(g, false);
} else {
++i;
}
}
- if (!gestures.isEmpty()) {
+ if (!gestures.isEmpty()) { // we have gestures for this w
QGestureEvent ge(gestures);
ge.t = gestureEvent->t;
ge.spont = gestureEvent->spont;
ge.m_accept = wasAccepted;
+ ge.d_func()->accepted = gestureEvent->d_func()->accepted;
res = d->notify_helper(w, &ge);
gestureEvent->spont = false;
eventAccepted = ge.isAccepted();
- if (res && eventAccepted)
- break;
- if (!eventAccepted) {
- // ### two ways to ignore the event/gesture
-
- // if the whole event wasn't accepted, put back those
- // gestures that were not accepted.
- for (int i = 0; i < gestures.size(); ++i) {
- QGesture *g = gestures.at(i);
- if (!ge.isAccepted(g))
- allGestures.append(g);
+ for (int i = 0; i < gestures.size(); ++i) {
+ QGesture *g = gestures.at(i);
+ if ((res && eventAccepted) || (!eventAccepted && ge.isAccepted(g))) {
+ // if the gesture was accepted, mark the target widget for it
+ gestureEvent->d_func()->targetWidgets[g->gestureType()] = w;
+ gestureEvent->setAccepted(g, true);
+ } else if (!eventAccepted && !ge.isAccepted(g)) {
+ // if the gesture was explicitly ignored by the application,
+ // put it back so a parent can get it
+ allGestures.append(g);
}
}
}
- if (allGestures.isEmpty())
+ if (allGestures.isEmpty()) // everything delivered
break;
if (w->isWindow())
break;
w = w->parentWidget();
}
- gestureEvent->m_accept = eventAccepted;
+ foreach (QGesture *g, allGestures)
+ gestureEvent->setAccepted(g, false);
+ gestureEvent->m_accept = false; // to make sure we check individual gestures
} else {
res = d->notify_helper(receiver, e);
}
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 5bb25fa..e84985e 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -615,6 +615,8 @@ static void qt_set_windows_font_resources()
if (qt_wince_is_mobile()) {
smallerFont.setPointSize(systemFont.pointSize()-1);
QApplication::setFont(smallerFont, "QTabBar");
+ smallerFont.setBold(true);
+ QApplication::setFont(smallerFont, "QAbstractButton");
}
#endif// Q_WS_WINCE
}
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index 4c2a14a..d49c150 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -51,6 +51,7 @@
#include <private/qmacinputcontext_p.h>
#include <private/qmultitouch_mac_p.h>
#include <private/qevent_p.h>
+#include <private/qbackingstore_p.h>
#include <qscrollarea.h>
#include <qhash.h>
@@ -503,6 +504,12 @@ extern "C" {
- (void)drawRect:(NSRect)aRect
{
+ if (QApplicationPrivate::graphicsSystem() != 0) {
+ if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore())
+ bs->markDirty(qwidget->rect(), qwidget);
+ qwidgetprivate->syncBackingStore(qwidget->rect());
+ return;
+ }
CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
qwidgetprivate->hd = cg;
CGContextSaveGState(cg);
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 2ff6d65..065bd09 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -45,6 +45,7 @@
#include "private/qapplication_p.h"
#include "private/qkeysequence_p.h"
#include "qwidget.h"
+#include "qgraphicsview.h"
#include "qdebug.h"
#include "qmime.h"
#include "qdnd_p.h"
@@ -4223,8 +4224,17 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T
Creates new QGestureEvent containing a list of \a gestures.
*/
QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
- : QEvent(QEvent::Gesture), gestures_(gestures)
+ : QEvent(QEvent::Gesture)
{
+ d = reinterpret_cast<QEventPrivate *>(new QGestureEventPrivate(gestures));
+}
+
+/*!
+ Destroys QGestureEvent.
+*/
+QGestureEvent::~QGestureEvent()
+{
+ delete reinterpret_cast<QGestureEventPrivate *>(d);
}
/*!
@@ -4232,7 +4242,7 @@ QGestureEvent::QGestureEvent(const QList<QGesture *> &gestures)
*/
QList<QGesture *> QGestureEvent::allGestures() const
{
- return gestures_;
+ return d_func()->gestures;
}
/*!
@@ -4240,9 +4250,10 @@ QList<QGesture *> QGestureEvent::allGestures() const
*/
QGesture *QGestureEvent::gesture(Qt::GestureType type) const
{
- for(int i = 0; i < gestures_.size(); ++i)
- if (gestures_.at(i)->gestureType() == type)
- return gestures_.at(i);
+ const QGestureEventPrivate *d = d_func();
+ for(int i = 0; i < d->gestures.size(); ++i)
+ if (d->gestures.at(i)->gestureType() == type)
+ return d->gestures.at(i);
return 0;
}
@@ -4251,7 +4262,7 @@ QGesture *QGestureEvent::gesture(Qt::GestureType type) const
*/
QList<QGesture *> QGestureEvent::activeGestures() const
{
- return gestures_;
+ return d_func()->gestures;
}
/*!
@@ -4259,7 +4270,7 @@ QList<QGesture *> QGestureEvent::activeGestures() const
*/
QList<QGesture *> QGestureEvent::canceledGestures() const
{
- return gestures_;
+ return d_func()->gestures;
}
/*!
@@ -4279,7 +4290,7 @@ void QGestureEvent::setAccepted(QGesture *gesture, bool value)
{
setAccepted(false);
if (gesture)
- gesture->d_func()->accept = value;
+ d_func()->accepted[gesture->gestureType()] = value;
}
/*!
@@ -4315,7 +4326,56 @@ void QGestureEvent::ignore(QGesture *gesture)
*/
bool QGestureEvent::isAccepted(QGesture *gesture) const
{
- return gesture ? gesture->d_func()->accept : false;
+ return gesture ? d_func()->accepted.value(gesture->gestureType(), true) : false;
+}
+
+/*!
+ Sets the widget for this event.
+*/
+void QGestureEvent::setWidget(QWidget *widget)
+{
+ d_func()->widget = widget;
+}
+
+/*!
+ Returns the widget on which the event occurred.
+*/
+QWidget *QGestureEvent::widget() const
+{
+ return d_func()->widget;
+}
+
+/*!
+ Returns the scene-local coordinates if the \a gesturePoint is inside a graphics view.
+
+ \sa QPointF::isNull().
+*/
+QPointF QGestureEvent::mapToScene(const QPointF &gesturePoint) const
+{
+ QWidget *w = widget();
+ if (w) // we get the viewport as widget, not the graphics view
+ w = w->parentWidget();
+ QGraphicsView *view = qobject_cast<QGraphicsView*>(w);
+ if (view) {
+ return view->mapToScene(view->mapFromGlobal(gesturePoint.toPoint()));
+ }
+ return QPointF();
+}
+
+/*!
+ \internal
+*/
+QGestureEventPrivate *QGestureEvent::d_func()
+{
+ return reinterpret_cast<QGestureEventPrivate *>(d);
+}
+
+/*!
+ \internal
+*/
+const QGestureEventPrivate *QGestureEvent::d_func() const
+{
+ return reinterpret_cast<const QGestureEventPrivate *>(d);
}
#ifdef Q_NO_USING_KEYWORD
diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h
index 3516222..b7370fd 100644
--- a/src/gui/kernel/qevent.h
+++ b/src/gui/kernel/qevent.h
@@ -820,10 +820,12 @@ protected:
};
class QGesture;
+class QGestureEventPrivate;
class Q_GUI_EXPORT QGestureEvent : public QEvent
{
public:
QGestureEvent(const QList<QGesture *> &gestures);
+ ~QGestureEvent();
QList<QGesture *> allGestures() const;
QGesture *gesture(Qt::GestureType type) const;
@@ -849,8 +851,17 @@ public:
void ignore(QGesture *);
bool isAccepted(QGesture *) const;
+ void setWidget(QWidget *widget);
+ QWidget *widget() const;
+
+ QPointF mapToScene(const QPointF &gesturePoint) const;
+
private:
- QList<QGesture *> gestures_;
+ QGestureEventPrivate *d_func();
+ const QGestureEventPrivate *d_func() const;
+
+ friend class QApplication;
+ friend class QGestureManager;
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h
index c7a4975..6e6ab01 100644
--- a/src/gui/kernel/qevent_p.h
+++ b/src/gui/kernel/qevent_p.h
@@ -150,6 +150,20 @@ public:
#endif
};
+class QGestureEventPrivate
+{
+public:
+ inline QGestureEventPrivate(const QList<QGesture *> &list)
+ : gestures(list), widget(0)
+ {
+ }
+
+ QList<QGesture *> gestures;
+ QWidget *widget;
+ QMap<Qt::GestureType, bool> accepted;
+ QMap<Qt::GestureType, QWidget *> targetWidgets;
+};
+
QT_END_NAMESPACE
#endif // QEVENT_P_H
diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp
index fc8df49..ecdd661 100644
--- a/src/gui/kernel/qgesture.cpp
+++ b/src/gui/kernel/qgesture.cpp
@@ -129,6 +129,10 @@ QGesture::~QGesture()
\brief The point that is used to find the receiver for the gesture event.
+ The hot-spot is a point in the global coordinate system, use
+ QWidget::mapFromGlobal() or QGestureEvent::mapToScene() to get a
+ local hot-spot.
+
If the hot-spot is not set, the targetObject is used as the receiver of the
gesture event.
*/
@@ -154,16 +158,6 @@ Qt::GestureState QGesture::state() const
return d_func()->state;
}
-QObject *QGesture::targetObject() const
-{
- return d_func()->targetObject;
-}
-
-void QGesture::setTargetObject(QObject *value)
-{
- d_func()->targetObject = value;
-}
-
QPointF QGesture::hotSpot() const
{
return d_func()->hotSpot;
@@ -241,17 +235,17 @@ QPanGesture::QPanGesture(QObject *parent)
d_func()->gestureType = Qt::PanGesture;
}
-QSizeF QPanGesture::totalOffset() const
+QPointF QPanGesture::totalOffset() const
{
return d_func()->totalOffset;
}
-QSizeF QPanGesture::lastOffset() const
+QPointF QPanGesture::lastOffset() const
{
return d_func()->lastOffset;
}
-QSizeF QPanGesture::offset() const
+QPointF QPanGesture::offset() const
{
return d_func()->offset;
}
@@ -262,17 +256,17 @@ qreal QPanGesture::acceleration() const
}
-void QPanGesture::setTotalOffset(const QSizeF &value)
+void QPanGesture::setTotalOffset(const QPointF &value)
{
d_func()->totalOffset = value;
}
-void QPanGesture::setLastOffset(const QSizeF &value)
+void QPanGesture::setLastOffset(const QPointF &value)
{
d_func()->lastOffset = value;
}
-void QPanGesture::setOffset(const QSizeF &value)
+void QPanGesture::setOffset(const QPointF &value)
{
d_func()->offset = value;
}
diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h
index 02eb526..6469959 100644
--- a/src/gui/kernel/qgesture.h
+++ b/src/gui/kernel/qgesture.h
@@ -67,7 +67,6 @@ class Q_GUI_EXPORT QGesture : public QObject
Q_PROPERTY(Qt::GestureType gestureType READ gestureType)
Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot)
Q_PROPERTY(bool hasHotSpot READ hasHotSpot)
- Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject)
public:
explicit QGesture(QObject *parent = 0);
@@ -77,9 +76,6 @@ public:
Qt::GestureState state() const;
- QObject *targetObject() const;
- void setTargetObject(QObject *value);
-
QPointF hotSpot() const;
void setHotSpot(const QPointF &value);
bool hasHotSpot() const;
@@ -100,22 +96,22 @@ class Q_GUI_EXPORT QPanGesture : public QGesture
Q_OBJECT
Q_DECLARE_PRIVATE(QPanGesture)
- Q_PROPERTY(QSizeF totalOffset READ totalOffset WRITE setTotalOffset)
- Q_PROPERTY(QSizeF lastOffset READ lastOffset WRITE setLastOffset)
- Q_PROPERTY(QSizeF offset READ offset WRITE setOffset)
+ Q_PROPERTY(QPointF totalOffset READ totalOffset WRITE setTotalOffset)
+ Q_PROPERTY(QPointF lastOffset READ lastOffset WRITE setLastOffset)
+ Q_PROPERTY(QPointF offset READ offset WRITE setOffset)
Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration)
public:
QPanGesture(QObject *parent = 0);
- QSizeF totalOffset() const;
- QSizeF lastOffset() const;
- QSizeF offset() const;
+ QPointF totalOffset() const;
+ QPointF lastOffset() const;
+ QPointF offset() const;
qreal acceleration() const;
- void setTotalOffset(const QSizeF &value);
- void setLastOffset(const QSizeF &value);
- void setOffset(const QSizeF &value);
+ void setTotalOffset(const QPointF &value);
+ void setLastOffset(const QPointF &value);
+ void setOffset(const QPointF &value);
void setAcceleration(qreal value);
friend class QPanGestureRecognizer;
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index 7f69a4e..975c0c9 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -68,7 +68,7 @@ class QGesturePrivate : public QObjectPrivate
public:
QGesturePrivate()
: gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false),
- targetObject(0), accept(true)
+ targetObject(0)
{
}
@@ -77,7 +77,6 @@ public:
QPointF hotSpot;
bool isHotSpotSet;
QObject *targetObject;
- bool accept;
};
class QPanGesturePrivate : public QGesturePrivate
@@ -90,9 +89,9 @@ public:
{
}
- QSizeF totalOffset;
- QSizeF lastOffset;
- QSizeF offset;
+ QPointF totalOffset;
+ QPointF lastOffset;
+ QPointF offset;
QPoint lastPosition;
qreal acceleration;
};
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index 0f0aef2..ed8e744 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -44,6 +44,7 @@
#include "private/qwidget_p.h"
#include "private/qgesture_p.h"
#include "private/qgraphicsitem_p.h"
+#include "private/qevent_p.h"
#include "qgesture.h"
#include "qevent.h"
#include "qgraphicsitem.h"
@@ -88,7 +89,8 @@ Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *r
{
QGesture *dummy = recognizer->createGesture(0);
if (!dummy) {
- qWarning("QGestureManager::registerGestureRecognizer: the recognizer doesn't provide gesture object");
+ qWarning("QGestureManager::registerGestureRecognizer: "
+ "the recognizer fails to create a gesture object, skipping registration.");
return Qt::GestureType(0);
}
Qt::GestureType type = dummy->gestureType();
@@ -107,7 +109,7 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType)
}
-QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type)
+QGesture *QGestureManager::getState(QObject *object, Qt::GestureType type)
{
// if the widget is being deleted we should be carefull and not to
// create a new state, as it will create QWeakPointer which doesnt work
@@ -115,28 +117,39 @@ QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type)
if (object->isWidgetType()) {
if (static_cast<QWidget *>(object)->d_func()->data.in_destructor)
return 0;
+ } else if (QGesture *g = qobject_cast<QGesture *>(object)) {
+ return g;
+ } else {
+ Q_ASSERT(qobject_cast<QGraphicsObject *>(object));
}
- QWeakPointer<QGesture> state = objectGestures.value(QGestureManager::ObjectGesture(object, type));
+ QGesture *state =
+ objectGestures.value(QGestureManager::ObjectGesture(object, type));
if (!state) {
QGestureRecognizer *recognizer = recognizers.value(type);
if (recognizer) {
state = recognizer->createGesture(object);
if (!state)
return 0;
- if (state.data()->gestureType() == Qt::CustomGesture) {
+ if (state->gestureType() == Qt::CustomGesture) {
// if the recognizer didn't fill in the gesture type, then this
// is a custom gesture with autogenerated it and we fill it.
- state.data()->d_func()->gestureType = type;
+ state->d_func()->gestureType = type;
+#if defined(GESTURE_DEBUG)
+ state->setObjectName(QString::number((int)type));
+#endif
}
objectGestures.insert(QGestureManager::ObjectGesture(object, type), state);
- gestureToRecognizer[state.data()] = recognizer;
+ gestureToRecognizer[state] = recognizer;
+ gestureOwners[state] = object;
}
}
- return state.data();
+ return state;
}
-bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
+bool QGestureManager::filterEventThroughContexts(const QMap<QObject *,
+ Qt::GestureType> &contexts,
+ QEvent *event)
{
QSet<QGesture *> triggeredGestures;
QSet<QGesture *> finishedGestures;
@@ -144,93 +157,23 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
QSet<QGesture *> canceledGestures;
QSet<QGesture *> notGestures;
- QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(receiver);
- if (receiver->isWidgetType() || graphicsObject) {
- QMap<QObject *, Qt::GestureType> contexts;
- if (receiver->isWidgetType()) {
- QWidget *w = static_cast<QWidget *>(receiver);
- if (!w->d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for(ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- contexts.insertMulti(w, it.key());
- }
- }
- // find all gesture contexts for the widget tree
- w = w->parentWidget();
- while (w)
- {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for (ContextIterator it = w->d_func()->gestureContext.begin(),
- e = w->d_func()->gestureContext.end(); it != e; ++it) {
- if (it.value() == Qt::WidgetWithChildrenGesture)
- contexts.insertMulti(w, it.key());
- }
- w = w->parentWidget();
- }
- } else {
- QGraphicsObject *item = graphicsObject;
- if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
- e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- contexts.insertMulti(item, it.key());
- }
- }
- // find all gesture contexts for the widget tree
- item = item->parentObject();
- while (item)
- {
- typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
- for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
- e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
- if (it.value() == Qt::WidgetWithChildrenGesture)
- contexts.insertMulti(item, it.key());
- }
- item = item->parentObject();
- }
- }
- // filter the event through recognizers
- typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
- for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
- Qt::GestureType gestureType = cit.value();
- QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
- rit = recognizers.lowerBound(gestureType),
- re = recognizers.upperBound(gestureType);
- for (; rit != re; ++rit) {
- QGestureRecognizer *recognizer = rit.value();
- QObject *target = cit.key();
- QGesture *state = getState(target, gestureType);
- if (!state)
- continue;
- QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
- QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
- if (type == QGestureRecognizer::GestureTriggered) {
- DEBUG() << "QGestureManager: gesture triggered: " << state;
- triggeredGestures << state;
- } else if (type == QGestureRecognizer::GestureFinished) {
- DEBUG() << "QGestureManager: gesture finished: " << state;
- finishedGestures << state;
- } else if (type == QGestureRecognizer::MaybeGesture) {
- DEBUG() << "QGestureManager: maybe gesture: " << state;
- newMaybeGestures << state;
- } else if (type == QGestureRecognizer::NotGesture) {
- DEBUG() << "QGestureManager: not gesture: " << state;
- notGestures << state;
- } else if (type == QGestureRecognizer::Ignore) {
- DEBUG() << "QGestureManager: gesture ignored the event: " << state;
- } else {
- DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
- }
- if (result & QGestureRecognizer::ConsumeEventHint) {
- DEBUG() << "QGestureManager: we were asked to consume the event: " << state;
- //TODO: consume events if asked
- }
- }
- }
- } else if (QGesture *state = qobject_cast<QGesture*>(receiver)) {
- if (QGestureRecognizer *recognizer = gestureToRecognizer.value(state)) {
- QGestureRecognizer::Result result = recognizer->filterEvent(state, state, event);
+ // TODO: sort contexts by the gesture type and check if one of the contexts
+ // is already active.
+
+ // filter the event through recognizers
+ typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator;
+ for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) {
+ Qt::GestureType gestureType = cit.value();
+ QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator
+ rit = recognizers.lowerBound(gestureType),
+ re = recognizers.upperBound(gestureType);
+ for (; rit != re; ++rit) {
+ QGestureRecognizer *recognizer = rit.value();
+ QObject *target = cit.key();
+ QGesture *state = getState(target, gestureType);
+ if (!state)
+ continue;
+ QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event);
QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask;
if (type == QGestureRecognizer::GestureTriggered) {
DEBUG() << "QGestureManager: gesture triggered: " << state;
@@ -247,11 +190,15 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
} else if (type == QGestureRecognizer::Ignore) {
DEBUG() << "QGestureManager: gesture ignored the event: " << state;
} else {
- DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state;
+ DEBUG() << "QGestureManager: hm, lets assume the recognizer"
+ << "ignored the event: " << state;
+ }
+ if (result & QGestureRecognizer::ConsumeEventHint) {
+ DEBUG() << "QGestureManager: we were asked to consume the event: "
+ << state;
+ //TODO: consume events if asked
}
}
- } else {
- return false;
}
QSet<QGesture *> startedGestures = triggeredGestures - activeGestures;
@@ -260,7 +207,8 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
// check if a running gesture switched back to maybe state
QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures;
- // check if a running gesture switched back to not gesture state, i.e. were canceled
+ // check if a running gesture switched back to not gesture state,
+ // i.e. were canceled
QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures;
canceledGestures += activeToCancelGestures;
@@ -271,7 +219,9 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
timer.start(3000, this);
}
// kill timers for gestures that were in maybe state
- QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures | finishedGestures | canceledGestures | notGestures);
+ QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures
+ | finishedGestures | canceledGestures
+ | notGestures);
foreach(QGesture *gesture, notMaybeGestures) {
QMap<QGesture *, QBasicTimer>::iterator it =
maybeGestures.find(gesture);
@@ -294,7 +244,9 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
// probably those are "singleshot" gestures so we'll fake the started state.
foreach (QGesture *gesture, notStarted)
gesture->d_func()->state = Qt::GestureStarted;
- deliverEvents(notStarted, receiver);
+ QSet<QGesture *> undeliveredGestures;
+ deliverEvents(notStarted, &undeliveredGestures);
+ finishedGestures -= undeliveredGestures;
}
activeGestures += startedGestures;
@@ -328,10 +280,15 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
<< "\n\tcanceled:" << canceledGestures;
}
- deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, receiver);
+ QSet<QGesture *> undeliveredGestures;
+ deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures,
+ &undeliveredGestures);
+
+ activeGestures -= undeliveredGestures;
// reset gestures that ended
- QSet<QGesture *> endedGestures = finishedGestures + canceledGestures;
+ QSet<QGesture *> endedGestures =
+ finishedGestures + canceledGestures + undeliveredGestures;
foreach (QGesture *gesture, endedGestures) {
if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) {
recognizer->reset(gesture);
@@ -341,100 +298,218 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event)
return false;
}
-void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures, QObject *lastReceiver)
+bool QGestureManager::filterEvent(QWidget *receiver, QEvent *event)
+{
+ QSet<Qt::GestureType> types;
+ QMap<QObject *, Qt::GestureType> contexts;
+ QWidget *w = receiver;
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ if (!w->d_func()->gestureContext.isEmpty()) {
+ for(ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ types.insert(it.key());
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ // find all gesture contexts for the widget tree
+ w = w->isWindow() ? 0 : w->parentWidget();
+ while (w)
+ {
+ for (ContextIterator it = w->d_func()->gestureContext.begin(),
+ e = w->d_func()->gestureContext.end(); it != e; ++it) {
+ if (it.value() == Qt::WidgetWithChildrenGesture) {
+ if (!types.contains(it.key())) {
+ types.insert(it.key());
+ contexts.insertMulti(w, it.key());
+ }
+ }
+ }
+ if (w->isWindow())
+ break;
+ w = w->parentWidget();
+ }
+ return filterEventThroughContexts(contexts, event);
+}
+
+bool QGestureManager::filterEvent(QGraphicsObject *receiver, QEvent *event)
+{
+ QSet<Qt::GestureType> types;
+ QMap<QObject *, Qt::GestureType> contexts;
+ QGraphicsObject *item = receiver;
+ if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
+ e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
+ types.insert(it.key());
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ // find all gesture contexts for the graphics object tree
+ item = item->parentObject();
+ while (item)
+ {
+ typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator;
+ for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(),
+ e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) {
+ if (it.value() == Qt::ItemWithChildrenGesture) {
+ if (!types.contains(it.key()))
+ contexts.insertMulti(item, it.key());
+ }
+ }
+ item = item->parentObject();
+ }
+ return filterEventThroughContexts(contexts, event);
+}
+
+bool QGestureManager::filterEvent(QGesture *state, QEvent *event)
+{
+ QMap<QObject *, Qt::GestureType> contexts;
+ contexts.insert(state, state->gestureType());
+ return filterEventThroughContexts(contexts, event);
+}
+
+void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures,
+ QMap<QWidget *, QList<QGesture *> > *conflicts,
+ QMap<QWidget *, QList<QGesture *> > *normal)
+{
+ typedef QHash<Qt::GestureType, QHash<QWidget *, QGesture *> > GestureByTypes;
+ GestureByTypes gestureByTypes;
+
+ // sort gestures by types
+ foreach (QGesture *gesture, gestures) {
+ QWidget *receiver = gestureTargets.value(gesture, 0);
+ Q_ASSERT(receiver);
+ gestureByTypes[gesture->gestureType()].insert(receiver, gesture);
+ }
+
+ // for each gesture type
+ foreach (Qt::GestureType type, gestureByTypes.keys()) {
+ QHash<QWidget *, QGesture *> gestures = gestureByTypes.value(type);
+ foreach (QWidget *widget, gestures.keys()) {
+ QWidget *w = widget->parentWidget();
+ while (w) {
+ QMap<Qt::GestureType, Qt::GestureContext>::const_iterator it
+ = w->d_func()->gestureContext.find(type);
+ if (it != w->d_func()->gestureContext.end()) {
+ // i.e. 'w' listens to gesture 'type'
+ Qt::GestureContext context = it.value();
+ if (context == Qt::WidgetWithChildrenGesture && w != widget) {
+ // conflicting gesture!
+ (*conflicts)[widget].append(gestures[widget]);
+ break;
+ }
+ }
+ if (w->isWindow()) {
+ w = 0;
+ break;
+ }
+ w = w->parentWidget();
+ }
+ if (!w)
+ (*normal)[widget].append(gestures[widget]);
+ }
+ }
+}
+
+void QGestureManager::deliverEvents(const QSet<QGesture *> &gestures,
+ QSet<QGesture *> *undeliveredGestures)
{
if (gestures.isEmpty())
return;
- // group gestures by widgets
- typedef QMap<QObject *, QList<QGesture *> > GesturesPerReceiver;
- GesturesPerReceiver groupedGestures;
- // for conflicted gestures the key is always the innermost widget (i.e. the child)
- GesturesPerReceiver conflictedGestures;
- QMultiHash<QObject *, QGesture *> objectGestures;
+ typedef QMap<QWidget *, QList<QGesture *> > GesturesPerWidget;
+ GesturesPerWidget conflictedGestures;
+ GesturesPerWidget normalStartedGestures;
- foreach (QGesture *gesture, gestures) {
- QObject *target = gestureTargets.value(gesture, 0);
+ QSet<QGesture *> startedGestures;
+ // first figure out the initial receivers of gestures
+ for (QSet<QGesture *>::const_iterator it = gestures.begin(),
+ e = gestures.end(); it != e; ++it) {
+ QGesture *gesture = *it;
+ QWidget *target = gestureTargets.value(gesture, 0);
if (!target) {
+ // the gesture has just started and doesn't have a target yet.
Q_ASSERT(gesture->state() == Qt::GestureStarted);
if (gesture->hasHotSpot()) {
- // guess the target using the hotspot of the gesture
+ // guess the target widget using the hotspot of the gesture
QPoint pt = gesture->hotSpot().toPoint();
- if (!pt.isNull()) {
- if (QWidget *w = qApp->topLevelAt(pt))
- target = w->childAt(w->mapFromGlobal(pt));
+ if (QWidget *w = qApp->topLevelAt(pt)) {
+ target = w->childAt(w->mapFromGlobal(pt));
}
+ } else {
+ // or use the context of the gesture
+ QObject *context = gestureOwners.value(gesture, 0);
+ if (context->isWidgetType())
+ target = static_cast<QWidget *>(context);
}
- if (!target) {
- target = gesture->targetObject();
- if (!target)
- target = lastReceiver;
- }
+ if (target)
+ gestureTargets.insert(gesture, target);
}
+
+ Qt::GestureType gestureType = gesture->gestureType();
+ Q_ASSERT(gestureType != Qt::CustomGesture);
+
if (target) {
- gestureTargets.insert(gesture, target);
- if (target->isWidgetType())
- objectGestures.insert(target, gesture);
- groupedGestures[target].append(gesture);
+ if (gesture->state() == Qt::GestureStarted) {
+ startedGestures.insert(gesture);
+ } else {
+ normalStartedGestures[target].append(gesture);
+ }
} else {
- qWarning() << "QGestureManager::deliverEvent: could not find the target for gesture"
+ DEBUG() << "QGestureManager::deliverEvent: could not find the target for gesture"
<< gesture->gestureType();
+ qWarning("QGestureManager::deliverEvent: could not find the target for gesture");
+ undeliveredGestures->insert(gesture);
}
}
- typedef QMultiHash<QObject *, QGesture *>::const_iterator ObjectGesturesIterator;
- for (ObjectGesturesIterator it = objectGestures.begin(), e = objectGestures.end(); it != e; ++it) {
- QObject *object1 = it.key();
- QWidget *widget1 = qobject_cast<QWidget *>(object1);
- QGraphicsObject *item1 = qobject_cast<QGraphicsObject *>(object1);
- QGesture *gesture1 = it.value();
- ObjectGesturesIterator cit = it;
- for (++cit; cit != e; ++cit) {
- QObject *object2 = cit.key();
- QWidget *widget2 = qobject_cast<QWidget *>(object2);
- QGraphicsObject *item2 = qobject_cast<QGraphicsObject *>(object2);
- QGesture *gesture2 = cit.value();
- // TODO: ugly, rewrite this.
- if ((widget1 && widget2 && widget2->isAncestorOf(widget1)) ||
- (item1 && item2 && item2->isAncestorOf(item1))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object1].append(gesture1);
- } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2)) ||
- (item1 && item2 && item1->isAncestorOf(item2))) {
- groupedGestures[object2].removeOne(gesture2);
- groupedGestures[object1].removeOne(gesture1);
- conflictedGestures[object2].append(gesture2);
- }
- }
- }
-
- DEBUG() << "deliverEvents: conflicted =" << conflictedGestures.values()
- << " grouped =" << groupedGestures.values();
+ getGestureTargets(startedGestures, &conflictedGestures, &normalStartedGestures);
+ DEBUG() << "QGestureManager::deliverEvents:"
+ << "\nstarted: " << startedGestures
+ << "\nconflicted: " << conflictedGestures
+ << "\nnormal: " << normalStartedGestures
+ << "\n";
// if there are conflicting gestures, send the GestureOverride event
- for (GesturesPerReceiver::const_iterator it = conflictedGestures.begin(),
+ for (GesturesPerWidget::const_iterator it = conflictedGestures.begin(),
e = conflictedGestures.end(); it != e; ++it) {
+ QWidget *receiver = it.key();
+ QList<QGesture *> gestures = it.value();
DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to"
- << it.key()
- << " gestures:" << it.value();
- QGestureEvent event(it.value());
+ << receiver
+ << "gestures:" << gestures;
+ QGestureEvent event(gestures);
event.t = QEvent::GestureOverride;
+ // mark event and individual gestures as ignored
event.ignore();
- QApplication::sendEvent(it.key(), &event);
- if (!event.isAccepted()) {
- // nobody accepted the GestureOverride, put it back to deliver to
- // the closest context (i.e. to the inner-most widget).
- DEBUG() <<" override was not accepted";
- groupedGestures[it.key()].append(it.value());
+ foreach(QGesture *g, gestures)
+ event.setAccepted(g, false);
+
+ QApplication::sendEvent(receiver, &event);
+ bool eventAccepted = event.isAccepted();
+ foreach(QGesture *gesture, event.allGestures()) {
+ if (eventAccepted || event.isAccepted(gesture)) {
+ QWidget *w = event.d_func()->targetWidgets.value(gesture->gestureType(), 0);
+ Q_ASSERT(w);
+ DEBUG() << "override event: gesture was accepted:" << gesture << w;
+ QList<QGesture *> &gestures = normalStartedGestures[w];
+ gestures.append(gesture);
+ // override the target
+ gestureTargets[gesture] = w;
+ } else {
+ DEBUG() << "override event: gesture wasn't accepted. putting back:" << gesture;
+ QList<QGesture *> &gestures = normalStartedGestures[receiver];
+ gestures.append(gesture);
+ }
}
}
- for (GesturesPerReceiver::const_iterator it = groupedGestures.begin(),
- e = groupedGestures.end(); it != e; ++it) {
+ // delivering gestures that are not in conflicted state
+ for (GesturesPerWidget::const_iterator it = normalStartedGestures.begin(),
+ e = normalStartedGestures.end(); it != e; ++it) {
if (!it.value().isEmpty()) {
DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key()
- << " gestures:" << it.value();
+ << "gestures:" << it.value();
QGestureEvent event(it.value());
QApplication::sendEvent(it.key(), &event);
}
@@ -452,7 +527,8 @@ void QGestureManager::timerEvent(QTimerEvent *event)
timer.stop();
QGesture *gesture = it.key();
it = maybeGestures.erase(it);
- DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture;
+ DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:"
+ << gesture;
QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0);
if (recognizer)
recognizer->reset(gesture);
diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h
index c61819f..f0e7225 100644
--- a/src/gui/kernel/qgesturemanager_p.h
+++ b/src/gui/kernel/qgesturemanager_p.h
@@ -61,6 +61,7 @@
QT_BEGIN_NAMESPACE
class QBasicTimer;
+class QGraphicsObject;
class QGestureManager : public QObject
{
Q_OBJECT
@@ -71,13 +72,17 @@ public:
Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer);
void unregisterGestureRecognizer(Qt::GestureType type);
- bool filterEvent(QObject *receiver, QEvent *event);
+ bool filterEvent(QWidget *receiver, QEvent *event);
+ bool filterEvent(QGesture *receiver, QEvent *event);
+ bool filterEvent(QGraphicsObject *receiver, QEvent *event);
// declared in qapplication.cpp
static QGestureManager* instance();
protected:
void timerEvent(QTimerEvent *event);
+ bool filterEventThroughContexts(const QMap<QObject *, Qt::GestureType> &contexts,
+ QEvent *event);
private:
QMultiMap<Qt::GestureType, QGestureRecognizer *> recognizers;
@@ -109,15 +114,20 @@ private:
}
};
- QMap<ObjectGesture, QWeakPointer<QGesture> > objectGestures;
+ QMap<ObjectGesture, QGesture *> objectGestures;
QMap<QGesture *, QGestureRecognizer *> gestureToRecognizer;
+ QHash<QGesture *, QObject *> gestureOwners;
- QHash<QGesture *, QObject *> gestureTargets;
+ QHash<QGesture *, QWidget *> gestureTargets;
int lastCustomGestureId;
QGesture *getState(QObject *widget, Qt::GestureType gesture);
- void deliverEvents(const QSet<QGesture *> &gestures, QObject *lastReceiver);
+ void deliverEvents(const QSet<QGesture *> &gestures,
+ QSet<QGesture *> *undeliveredGestures);
+ void getGestureTargets(const QSet<QGesture*> &gestures,
+ QMap<QWidget *, QList<QGesture *> > *conflicts,
+ QMap<QWidget *, QList<QGesture *> > *normal);
};
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index 9de3bcc..ba3a750 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -186,7 +186,7 @@ void QGestureRecognizer::reset(QGesture *gesture)
\fn QGestureRecognizer::filterEvent(QGesture *gesture, QObject *watched, QEvent *event)
Handles the given \a event for the \a watched object, updating the state of the \a gesture
- object as required, and returns a suitable Result for the current recognition step.
+ object as required, and returns a suitable result for the current recognition step.
This function is called by the framework to allow the recognizer to filter input events
dispatched to QWidget or QGraphicsObject instances that it is monitoring.
diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm
index 7b19a54..7019580 100644
--- a/src/gui/kernel/qmacgesturerecognizer_mac.mm
+++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm
@@ -218,7 +218,7 @@ QMacPanGestureRecognizer::filterEvent(QGesture *gesture, QObject *target, QEvent
const QPointF p = QCursor::pos();
const QPointF posOffset = p - _lastPos;
g->setLastOffset(g->offset());
- g->setOffset(QSizeF(posOffset.x(), posOffset.y()));
+ g->setOffset(QPointF(posOffset.x(), posOffset.y()));
g->setTotalOffset(g->lastOffset() + g->offset());
_lastPos = p;
return QGestureRecognizer::GestureTriggered;
@@ -256,9 +256,9 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture)
_startPos = QPointF();
_lastPos = QPointF();
_panCanceled = true;
- g->setOffset(QSizeF(0, 0));
- g->setLastOffset(QSizeF(0, 0));
- g->setTotalOffset(QSizeF(0, 0));
+ g->setOffset(QPointF(0, 0));
+ g->setLastOffset(QPointF(0, 0));
+ g->setTotalOffset(QPointF(0, 0));
g->setAcceleration(qreal(1));
QGestureRecognizer::reset(gesture);
}
diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp
index dfc3499..a136379 100644
--- a/src/gui/kernel/qstandardgestures.cpp
+++ b/src/gui/kernel/qstandardgestures.cpp
@@ -73,7 +73,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
result = QGestureRecognizer::MaybeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
d->lastPosition = p.pos().toPoint();
- d->lastOffset = d->totalOffset = d->offset = QSize();
+ d->lastOffset = d->totalOffset = d->offset = QPointF();
break;
}
case QEvent::TouchEnd: {
@@ -83,7 +83,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
+ QPointF(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
d->totalOffset += d->offset;
}
@@ -99,11 +99,11 @@ QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, Q
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
d->lastOffset = d->offset;
d->offset =
- QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
+ QPointF(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(),
p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2;
d->totalOffset += d->offset;
- if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 ||
- d->totalOffset.width() < -10 || d->totalOffset.height() < -10) {
+ if (d->totalOffset.x() > 10 || d->totalOffset.y() > 10 ||
+ d->totalOffset.x() < -10 || d->totalOffset.y() < -10) {
result = QGestureRecognizer::GestureTriggered;
} else {
result = QGestureRecognizer::MaybeGesture;
@@ -128,7 +128,7 @@ void QPanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QSizeF();
+ d->totalOffset = d->lastOffset = d->offset = QPointF();
d->lastPosition = QPoint();
d->acceleration = 0;
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index c36c68a..5fa9a92 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -93,6 +93,7 @@
# include "qx11info_x11.h"
#endif
+#include <private/qgraphicseffect_p.h>
#include <private/qwindowsurface_p.h>
#include <private/qbackingstore_p.h>
#ifdef Q_WS_MAC
@@ -1788,12 +1789,29 @@ QRegion QWidgetPrivate::clipRegion() const
return r;
}
+void QWidgetPrivate::invalidateGraphicsEffectsRecursively()
+{
+ Q_Q(QWidget);
+ QWidget *w = q;
+ do {
+ if (w->graphicsEffect()) {
+ QWidgetEffectSourcePrivate *sourced =
+ static_cast<QWidgetEffectSourcePrivate *>(w->graphicsEffect()->source()->d_func());
+ if (!sourced->updateDueToGraphicsEffect)
+ w->graphicsEffect()->source()->d_func()->invalidateCache();
+ }
+ w = w->parentWidget();
+ } while (w);
+}
+
void QWidgetPrivate::setDirtyOpaqueRegion()
{
Q_Q(QWidget);
dirtyOpaqueChildren = true;
+ invalidateGraphicsEffectsRecursively();
+
if (q->isWindow())
return;
@@ -5197,6 +5215,10 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
paintEngine->d_func()->systemClip = QRegion();
} else {
context.painter = sharedPainter;
+ if (sharedPainter->worldTransform() != sourced->lastEffectTransform) {
+ sourced->invalidateCache();
+ sourced->lastEffectTransform = sharedPainter->worldTransform();
+ }
sharedPainter->save();
sharedPainter->translate(offset);
graphicsEffect->draw(sharedPainter, source);
@@ -7298,7 +7320,7 @@ void QWidget::setVisible(bool visible)
break;
parent = parent->parentWidget();
}
- if (parent && !d->getOpaqueRegion().isEmpty())
+ if (parent)
parent->d_func()->setDirtyOpaqueRegion();
}
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index 05c6a5b..d08f8a9 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -3048,6 +3048,7 @@ void QWidget::grabMouse()
}
}
+#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &)
{
if(isVisible() && !qt_nograb()) {
@@ -3056,6 +3057,7 @@ void QWidget::grabMouse(const QCursor &)
mac_mouse_grabber=this;
}
}
+#endif
void QWidget::releaseMouse()
{
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 24699c4..159a3f2 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -384,6 +384,7 @@ public:
void setOpaque(bool opaque);
void updateIsTranslucent();
bool paintOnScreen() const;
+ void invalidateGraphicsEffectsRecursively();
QRegion getOpaqueRegion() const;
const QRegion &getOpaqueChildren() const;
@@ -778,7 +779,7 @@ class QWidgetEffectSourcePrivate : public QGraphicsEffectSourcePrivate
{
public:
QWidgetEffectSourcePrivate(QWidget *widget)
- : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0)
+ : QGraphicsEffectSourcePrivate(), m_widget(widget), context(0), updateDueToGraphicsEffect(false)
{}
inline void detach()
@@ -791,7 +792,11 @@ public:
{ return m_widget; }
inline void update()
- { m_widget->update(); }
+ {
+ updateDueToGraphicsEffect = true;
+ m_widget->update();
+ updateDueToGraphicsEffect = false;
+ }
inline bool isPixmap() const
{ return false; }
@@ -803,7 +808,7 @@ public:
if (QWidget *parent = m_widget->parentWidget())
parent->update();
else
- m_widget->update();
+ update();
}
inline const QStyleOption *styleOption() const
@@ -818,6 +823,8 @@ public:
QWidget *m_widget;
QWidgetPaintContext *context;
+ QTransform lastEffectTransform;
+ bool updateDueToGraphicsEffect;
};
inline QWExtra *QWidgetPrivate::extraData() const
diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp
index 2b11bec..fa12b0d 100644
--- a/src/gui/kernel/qwidget_win.cpp
+++ b/src/gui/kernel/qwidget_win.cpp
@@ -851,10 +851,13 @@ void QWidget::grabMouse()
Q_ASSERT(testAttribute(Qt::WA_WState_Created));
SetCapture(effectiveWinId());
mouseGrb = this;
+#ifndef QT_NO_CURSOR
mouseGrbCur = new QCursor(mouseGrb->cursor());
+#endif
}
}
+#ifndef QT_NO_CURSOR
void QWidget::grabMouse(const QCursor &cursor)
{
if (!qt_nograb()) {
@@ -868,6 +871,7 @@ void QWidget::grabMouse(const QCursor &cursor)
mouseGrb = this;
}
}
+#endif
void QWidget::releaseMouse()
{
diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp
index 663178f..28676da 100644
--- a/src/gui/kernel/qwidget_x11.cpp
+++ b/src/gui/kernel/qwidget_x11.cpp
@@ -950,7 +950,7 @@ static void qt_x11_recreateWidget(QWidget *widget)
static void qt_x11_recreateNativeWidgetsRecursive(QWidget *widget)
{
- if (widget->testAttribute(Qt::WA_NativeWindow))
+ if (widget->internalWinId())
qt_x11_recreateWidget(widget);
const QObjectList &children = widget->children();
diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
index 4619594..12d3058 100644
--- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
+++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp
@@ -97,11 +97,11 @@ QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture
return QGestureRecognizer::Ignore;
}
if (q->state() == Qt::NoGesture) {
- d->lastOffset = d->totalOffset = d->offset = QSize();
+ d->lastOffset = d->totalOffset = d->offset = QPointF();
} else {
d->lastOffset = d->offset;
- d->offset = QSize(ev->position.x() - d->lastPosition.x(),
- ev->position.y() - d->lastPosition.y());
+ d->offset = QPointF(ev->position.x() - d->lastPosition.x(),
+ ev->position.y() - d->lastPosition.y());
d->totalOffset += d->offset;
}
d->lastPosition = ev->position;
@@ -114,7 +114,7 @@ void QWinNativePanGestureRecognizer::reset(QGesture *state)
QPanGesture *pan = static_cast<QPanGesture*>(state);
QPanGesturePrivate *d = pan->d_func();
- d->totalOffset = d->lastOffset = d->offset = QSizeF();
+ d->totalOffset = d->lastOffset = d->offset = QPointF();
d->lastPosition = QPoint();
d->acceleration = 0;