summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorQt Continuous Integration System <qt-info@nokia.com>2010-02-26 09:40:11 (GMT)
committerQt Continuous Integration System <qt-info@nokia.com>2010-02-26 09:40:11 (GMT)
commit2a898e4736dcafbe95dca120b2365bc24b395302 (patch)
tree3031380514df8b82e423ded0401610bcbf89b6cf /src/gui
parent8b3fad1f7ac9bef0119fffc67feb5bb153abc647 (diff)
parentae13ad51dda7246e73d282165201f637d04a667e (diff)
downloadQt-2a898e4736dcafbe95dca120b2365bc24b395302.zip
Qt-2a898e4736dcafbe95dca120b2365bc24b395302.tar.gz
Qt-2a898e4736dcafbe95dca120b2365bc24b395302.tar.bz2
Merge remote branch 'qt/master' into qml-master
Conflicts: tools/qdoc3/cppcodeparser.cpp tools/qdoc3/htmlgenerator.cpp tools/qdoc3/htmlgenerator.h tools/qdoc3/node.cpp
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp452
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h15
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm52
-rw-r--r--src/gui/kernel/qcocoaview_mac_p.h1
-rw-r--r--src/gui/kernel/qgesture_p.h2
-rw-r--r--src/gui/kernel/qgesturerecognizer.cpp1
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm10
-rw-r--r--src/gui/kernel/qwidget.cpp9
-rw-r--r--src/gui/painting/qdrawhelper.cpp199
-rw-r--r--src/gui/painting/qdrawhelper_p.h9
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp3
11 files changed, 297 insertions, 456 deletions
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index aaae88e..40e1d2c 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -693,6 +693,18 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item)
--selectionChanging;
if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize)
emit q->selectionChanged();
+
+ QHash<QGesture *, QGraphicsObject *>::iterator it;
+ for (it = gestureTargets.begin(); it != gestureTargets.end();) {
+ if (it.value() == item)
+ it = gestureTargets.erase(it);
+ else
+ ++it;
+ }
+ QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item);
+ cachedTargetItems.removeOne(dummy);
+ cachedItemGestures.remove(dummy);
+ cachedAlreadyDeliveredGestures.remove(dummy);
}
/*!
@@ -5900,45 +5912,51 @@ void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel)
dispatchHoverEvent(&hoverEvent);
}
-void QGraphicsScenePrivate::getGestureTargets(const QSet<QGesture *> &gestures,
- QWidget *viewport,
- QMap<Qt::GestureType, QGesture *> *conflictedGestures,
- QList<QList<QGraphicsObject *> > *conflictedItems,
- QHash<QGesture *, QGraphicsObject *> *normalGestures)
+void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
+ Qt::GestureFlag flag,
+ QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
+ QSet<QGraphicsObject *> *itemsSet,
+ QSet<QGesture *> *normal,
+ QSet<QGesture *> *conflicts)
{
+ QSet<QGesture *> normalGestures; // that are not in conflicted state.
foreach (QGesture *gesture, gestures) {
- Qt::GestureType gestureType = gesture->gestureType();
- if (gesture->hasHotSpot()) {
- QPoint screenPos = gesture->hotSpot().toPoint();
- QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
- QList<QGraphicsObject *> result;
- for (int j = 0; j < items.size(); ++j) {
- QGraphicsItem *item = items.at(j);
+ if (!gesture->hasHotSpot())
+ continue;
+ const Qt::GestureType gestureType = gesture->gestureType();
+ QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), gesture->d_func()->sceneHotSpot, 0);
+ for (int j = 0; j < items.size(); ++j) {
+ QGraphicsItem *item = items.at(j);
- // Check if the item is blocked by a modal panel and use it as
- // a target instead of this item.
- (void) item->isBlockedByModalPanel(&item);
+ // Check if the item is blocked by a modal panel and use it as
+ // a target instead of this item.
+ (void) item->isBlockedByModalPanel(&item);
- if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
- QGraphicsItemPrivate *d = item->d_func();
- if (d->gestureContext.contains(gestureType)) {
- result.append(itemobj);
+ if (QGraphicsObject *itemobj = item->toGraphicsObject()) {
+ QGraphicsItemPrivate *d = item->QGraphicsItem::d_func();
+ QMap<Qt::GestureType, Qt::GestureFlags>::const_iterator it =
+ d->gestureContext.find(gestureType);
+ if (it != d->gestureContext.end() && (!flag || (it.value() & flag))) {
+ if (normalGestures.contains(gesture)) {
+ normalGestures.remove(gesture);
+ if (conflicts)
+ conflicts->insert(gesture);
+ } else {
+ normalGestures.insert(gesture);
}
+ if (targets)
+ (*targets)[itemobj].insert(gesture);
+ if (itemsSet)
+ (*itemsSet).insert(itemobj);
}
- // Don't propagate through panels.
- if (item->isPanel())
- break;
- }
- DEBUG() << "QGraphicsScenePrivate::getGestureTargets:"
- << gesture << result;
- if (result.size() == 1) {
- normalGestures->insert(gesture, result.first());
- } else if (!result.isEmpty()) {
- conflictedGestures->insert(gestureType, gesture);
- conflictedItems->append(result);
}
+ // Don't propagate through panels.
+ if (item->isPanel())
+ break;
}
}
+ if (normal)
+ *normal = normalGestures;
}
void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
@@ -5946,266 +5964,215 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
QWidget *viewport = event->widget();
if (!viewport)
return;
+ QGraphicsView *graphicsView = qobject_cast<QGraphicsView *>(viewport->parent());
+ if (!graphicsView)
+ return;
+
QList<QGesture *> allGestures = event->gestures();
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
<< "Delivering gestures:" << allGestures;
- typedef QHash<QGraphicsObject *, QList<QGesture *> > GesturesPerItem;
- GesturesPerItem gesturesPerItem;
-
- // gestures that are only supposed to propagate to parent items.
- QSet<QGesture *> parentPropagatedGestures;
-
QSet<QGesture *> startedGestures;
+ QPoint delta = graphicsView->mapFromGlobal(QPoint());
+ QTransform toScene = QTransform::fromTranslate(delta.x(), delta.y())
+ * graphicsView->viewportTransform().inverted();
foreach (QGesture *gesture, allGestures) {
+ // cache scene coordinates of the hot spot
+ if (gesture->hasHotSpot()) {
+ gesture->d_func()->sceneHotSpot = toScene.map(gesture->hotSpot());
+ } else {
+ gesture->d_func()->sceneHotSpot = QPointF();
+ }
+
QGraphicsObject *target = gestureTargets.value(gesture, 0);
if (!target) {
// when we are not in started mode but don't have a target
// then the only one interested in gesture is the view/scene
if (gesture->state() == Qt::GestureStarted)
startedGestures.insert(gesture);
- } else {
- gesturesPerItem[target].append(gesture);
- Qt::GestureFlags flags =
- target->QGraphicsItem::d_func()->gestureContext.value(gesture->gestureType());
- if (flags & Qt::IgnoredGesturesPropagateToParent)
- parentPropagatedGestures.insert(gesture);
}
}
- QMap<Qt::GestureType, QGesture *> conflictedGestures;
- QList<QList<QGraphicsObject *> > conflictedItems;
- QHash<QGesture *, QGraphicsObject *> normalGestures;
- getGestureTargets(startedGestures, viewport, &conflictedGestures, &conflictedItems,
- &normalGestures);
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "Conflicting gestures:" << conflictedGestures.values() << conflictedItems;
- Q_ASSERT((conflictedGestures.isEmpty() && conflictedItems.isEmpty()) ||
- (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty()));
-
- // gestures that were sent as override events, but no one accepted them
- QHash<QGesture *, QGraphicsObject *> ignoredConflictedGestures;
-
- // deliver conflicted gestures as override events first
- while (!conflictedGestures.isEmpty() && !conflictedItems.isEmpty()) {
- // get the topmost item to deliver the override event
- Q_ASSERT(!conflictedItems.isEmpty());
- Q_ASSERT(!conflictedItems.first().isEmpty());
- QGraphicsObject *topmost = conflictedItems.first().first();
- for (int i = 1; i < conflictedItems.size(); ++i) {
- QGraphicsObject *item = conflictedItems.at(i).first();
- if (qt_closestItemFirst(item, topmost)) {
- topmost = item;
- }
- }
- // get a list of gestures to send to the item
- QList<Qt::GestureType> grabbedGestures =
- topmost->QGraphicsItem::d_func()->gestureContext.keys();
- QList<QGesture *> gestures;
- for (int i = 0; i < grabbedGestures.size(); ++i) {
- if (QGesture *g = conflictedGestures.value(grabbedGestures.at(i), 0)) {
- gestures.append(g);
- if (!ignoredConflictedGestures.contains(g))
- ignoredConflictedGestures.insert(g, topmost);
- }
- }
-
- // send gesture override to the topmost item
- QGestureEvent ev(gestures);
- ev.t = QEvent::GestureOverride;
- ev.setWidget(event->widget());
- // mark event and individual gestures as ignored
- ev.ignore();
- foreach(QGesture *g, gestures)
- ev.setAccepted(g, false);
+ if (!startedGestures.isEmpty()) {
+ QSet<QGesture *> normalGestures; // that have just one target
+ QSet<QGesture *> conflictedGestures; // that have multiple possible targets
+ gestureTargetsAtHotSpots(startedGestures, Qt::GestureFlag(0), &cachedItemGestures, 0,
+ &normalGestures, &conflictedGestures);
+ cachedTargetItems = cachedItemGestures.keys();
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "delivering override to"
- << topmost << gestures;
- sendEvent(topmost, &ev);
- // mark all accepted gestures to deliver them as normal gesture events
- foreach (QGesture *g, gestures) {
- if (ev.isAccepted() || ev.isAccepted(g)) {
- conflictedGestures.remove(g->gestureType());
- gestureTargets.remove(g);
- // add the gesture to the list of normal delivered gestures
- normalGestures.insert(g, topmost);
+ << "Conflicting gestures:" << conflictedGestures;
+
+ // deliver conflicted gestures as override events AND remember
+ // initial gesture targets
+ if (!conflictedGestures.isEmpty()) {
+ for (int i = 0; i < cachedTargetItems.size(); ++i) {
+ QWeakPointer<QGraphicsObject> item = cachedTargetItems.at(i);
+
+ // get gestures to deliver to the current item
+ QSet<QGesture *> gestures = conflictedGestures & cachedItemGestures.value(item.data());
+ if (gestures.isEmpty())
+ continue;
+
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "override was accepted:"
- << g << topmost;
- ignoredConflictedGestures.remove(g);
+ << "delivering override to"
+ << item.data() << gestures;
+ // send gesture override
+ QGestureEvent ev(gestures.toList());
+ ev.t = QEvent::GestureOverride;
+ ev.setWidget(event->widget());
+ // mark event and individual gestures as ignored
+ ev.ignore();
+ foreach(QGesture *g, gestures)
+ ev.setAccepted(g, false);
+ sendEvent(item.data(), &ev);
+ // mark all accepted gestures to deliver them as normal gesture events
+ foreach (QGesture *g, gestures) {
+ if (ev.isAccepted() || ev.isAccepted(g)) {
+ conflictedGestures.remove(g);
+ // mark the item as a gesture target
+ if (item)
+ gestureTargets.insert(g, item.data());
+ DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
+ << "override was accepted:"
+ << g << item.data();
+ }
+ // remember the first item that received the override event
+ // as it most likely become a target if noone else accepts
+ // the override event
+ if (!gestureTargets.contains(g) && item)
+ gestureTargets.insert(g, item.data());
+
+ }
+ if (conflictedGestures.isEmpty())
+ break;
}
}
- // remove the item that we've already delivered from the list
- for (int i = 0; i < conflictedItems.size(); ) {
- QList<QGraphicsObject *> &items = conflictedItems[i];
- if (items.first() == topmost) {
- items.removeFirst();
- if (items.isEmpty()) {
- conflictedItems.removeAt(i);
- continue;
+ // remember the initial target item for each gesture that was not in
+ // the conflicted state.
+ if (!normalGestures.isEmpty()) {
+ for (int i = 0; i < cachedTargetItems.size() && !normalGestures.isEmpty(); ++i) {
+ QGraphicsObject *item = cachedTargetItems.at(i);
+
+ // get gestures to deliver to the current item
+ foreach (QGesture *g, cachedItemGestures.value(item)) {
+ if (!gestureTargets.contains(g)) {
+ gestureTargets.insert(g, item);
+ normalGestures.remove(g);
+ }
}
}
- ++i;
}
}
- // put back those started gestures that are not in the conflicted state
- // and remember their targets
- QHash<QGesture *, QGraphicsObject *>::const_iterator it = normalGestures.begin(),
- e = normalGestures.end();
- for (; it != e; ++it) {
- QGesture *g = it.key();
- QGraphicsObject *receiver = it.value();
- Q_ASSERT(!gestureTargets.contains(g));
- gestureTargets.insert(g, receiver);
- gesturesPerItem[receiver].append(g);
- Qt::GestureFlags flags =
- receiver->QGraphicsItem::d_func()->gestureContext.value(g->gestureType());
- if (flags & Qt::IgnoredGesturesPropagateToParent)
- parentPropagatedGestures.insert(g);
- }
- it = ignoredConflictedGestures.begin();
- e = ignoredConflictedGestures.end();
- for (; it != e; ++it) {
- QGesture *g = it.key();
- QGraphicsObject *receiver = it.value();
- Q_ASSERT(!gestureTargets.contains(g));
- gestureTargets.insert(g, receiver);
- gesturesPerItem[receiver].append(g);
- Qt::GestureFlags flags =
- receiver->QGraphicsItem::d_func()->gestureContext.value(g->gestureType());
- if (flags & Qt::IgnoredGesturesPropagateToParent)
- parentPropagatedGestures.insert(g);
- }
-
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "Started gestures:" << normalGestures.keys()
- << "All gestures:" << gesturesPerItem.values();
// deliver all gesture events
- QList<QGesture *> alreadyIgnoredGestures;
- QHash<QGraphicsObject *, QSet<QGesture *> > itemIgnoredGestures;
- QList<QGraphicsObject *> targetItems = gesturesPerItem.keys();
- qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst);
- for (int i = 0; i < targetItems.size(); ++i) {
- QGraphicsObject *item = targetItems.at(i);
- QList<QGesture *> gestures = gesturesPerItem.value(item);
- // remove gestures that were already delivered once and were ignored
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "already ignored gestures for item"
- << item << ":" << itemIgnoredGestures.value(item);
-
- if (itemIgnoredGestures.contains(item)) // don't deliver twice to the same item
- continue;
-
- QGraphicsItemPrivate *gid = item->QGraphicsItem::d_func();
- foreach(QGesture *g, alreadyIgnoredGestures) {
- QMap<Qt::GestureType, Qt::GestureFlags>::iterator contextit =
- gid->gestureContext.find(g->gestureType());
- bool deliver = false;
- if (contextit != gid->gestureContext.end()) {
- if (g->state() == Qt::GestureStarted) {
- deliver = true;
- } else {
- const Qt::GestureFlags flags = contextit.value();
- if (flags & Qt::ReceivePartialGestures) {
- QGraphicsObject *originalTarget = gestureTargets.value(g);
- Q_ASSERT(originalTarget);
- QGraphicsItemPrivate *otd = originalTarget->QGraphicsItem::d_func();
- const Qt::GestureFlags originalTargetFlags = otd->gestureContext.value(g->gestureType());
- if (originalTargetFlags & Qt::IgnoredGesturesPropagateToParent) {
- // only deliver to parents of the original target item
- deliver = item->isAncestorOf(originalTarget);
- } else {
- deliver = true;
- }
- }
- }
- }
- if (deliver)
- gestures += g;
+ QSet<QGesture *> undeliveredGestures;
+ QSet<QGesture *> parentPropagatedGestures;
+ foreach (QGesture *gesture, allGestures) {
+ if (QGraphicsObject *target = gestureTargets.value(gesture, 0)) {
+ cachedItemGestures[target].insert(gesture);
+ cachedTargetItems.append(target);
+ undeliveredGestures.insert(gesture);
+ QGraphicsItemPrivate *d = target->QGraphicsItem::d_func();
+ const Qt::GestureFlags flags = d->gestureContext.value(gesture->gestureType());
+ if (flags & Qt::IgnoredGesturesPropagateToParent)
+ parentPropagatedGestures.insert(gesture);
}
+ }
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
+ for (int i = 0; i < cachedTargetItems.size(); ++i) {
+ QWeakPointer<QGraphicsObject> receiver = cachedTargetItems.at(i);
+ QSet<QGesture *> gestures =
+ undeliveredGestures & cachedItemGestures.value(receiver.data());
+ gestures -= cachedAlreadyDeliveredGestures.value(receiver.data());
+
if (gestures.isEmpty())
continue;
+
+ cachedAlreadyDeliveredGestures[receiver.data()] += gestures;
+ const bool isPanel = receiver.data()->isPanel();
+
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
<< "delivering to"
- << item << gestures;
- QGestureEvent ev(gestures);
+ << receiver.data() << gestures;
+ QGestureEvent ev(gestures.toList());
ev.setWidget(event->widget());
- sendEvent(item, &ev);
+ sendEvent(receiver.data(), &ev);
QSet<QGesture *> ignoredGestures;
foreach (QGesture *g, gestures) {
if (!ev.isAccepted() && !ev.isAccepted(g)) {
- ignoredGestures.insert(g);
+ // if the gesture was ignored by its target, we will update the
+ // targetItems list with a possible target items (items that
+ // want to receive partial gestures).
+ // ### wont' work if the target was destroyed in the event
+ // we will just stop delivering it.
+ if (receiver && receiver.data() == gestureTargets.value(g, 0))
+ ignoredGestures.insert(g);
} else {
- if (g->state() == Qt::GestureStarted)
- gestureTargets[g] = item;
- }
- }
- if (!ignoredGestures.isEmpty()) {
- // get a list of items under the (current) hotspot of each ignored
- // gesture and start delivery again from the beginning
- DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "item has ignored the event, will propagate."
- << item << ignoredGestures;
- itemIgnoredGestures[item] += ignoredGestures;
- alreadyIgnoredGestures = ignoredGestures.toList();
-
- // remove gestures that are supposed to be propagated to
- // parent items only.
- QSet<QGesture *> parentGestures;
- for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
- it != ignoredGestures.end();) {
- if (parentPropagatedGestures.contains(*it)) {
- parentGestures.insert(*it);
- it = ignoredGestures.erase(it);
- } else {
- ++it;
+ if (receiver && g->state() == Qt::GestureStarted) {
+ // someone accepted the propagated initial GestureStarted
+ // event, let it be the new target for all following events.
+ gestureTargets[g] = receiver.data();
}
+ undeliveredGestures.remove(g);
}
+ }
+ if (undeliveredGestures.isEmpty())
+ break;
- QSet<QGraphicsObject *> itemsSet = targetItems.toSet();
-
- foreach(QGesture *g, parentGestures) {
- // get the original target for the gesture
- QGraphicsItem *item = gestureTargets.value(g, 0);
- Q_ASSERT(item);
- const Qt::GestureType gestureType = g->gestureType();
- // iterate through parent items of the original gesture
- // target item and collect potential receivers
- do {
- if (QGraphicsObject *obj = item->toGraphicsObject()) {
- if (item->d_func()->gestureContext.contains(gestureType))
- itemsSet.insert(obj);
+ // ignoredGestures list is only filled when delivering to the gesture
+ // target item, so it is safe to assume item == target.
+ if (!ignoredGestures.isEmpty() && !isPanel) {
+ // look for new potential targets for gestures that were ignored
+ // and should be propagated.
+
+ QSet<QGraphicsObject *> targetsSet = cachedTargetItems.toSet();
+
+ if (receiver) {
+ // first if the gesture should be propagated to parents only
+ for (QSet<QGesture *>::iterator it = ignoredGestures.begin();
+ it != ignoredGestures.end();) {
+ if (parentPropagatedGestures.contains(*it)) {
+ QGesture *gesture = *it;
+ const Qt::GestureType gestureType = gesture->gestureType();
+ QGraphicsItem *item = receiver.data();
+ while (item) {
+ if (QGraphicsObject *obj = item->toGraphicsObject()) {
+ if (item->d_func()->gestureContext.contains(gestureType)) {
+ targetsSet.insert(obj);
+ cachedItemGestures[obj].insert(gesture);
+ }
+ }
+ if (item->isPanel())
+ break;
+ item = item->parentItem();
+ }
+
+ it = ignoredGestures.erase(it);
+ continue;
}
- if (item->isPanel())
- break;
- } while ((item = item->parentItem()));
+ ++it;
+ }
}
- QMap<Qt::GestureType, QGesture *> conflictedGestures;
- QList<QList<QGraphicsObject *> > itemsForConflictedGestures;
- QHash<QGesture *, QGraphicsObject *> normalGestures;
- getGestureTargets(ignoredGestures, viewport,
- &conflictedGestures, &itemsForConflictedGestures,
- &normalGestures);
- for (int k = 0; k < itemsForConflictedGestures.size(); ++k)
- itemsSet += itemsForConflictedGestures.at(k).toSet();
-
- targetItems = itemsSet.toList();
+ gestureTargetsAtHotSpots(ignoredGestures, Qt::ReceivePartialGestures,
+ &cachedItemGestures, &targetsSet, 0, 0);
- qSort(targetItems.begin(), targetItems.end(), qt_closestItemFirst);
+ cachedTargetItems = targetsSet.toList();
+ qSort(cachedTargetItems.begin(), cachedTargetItems.end(), qt_closestItemFirst);
DEBUG() << "QGraphicsScenePrivate::gestureEventHandler:"
- << "new targets:" << targetItems;
+ << "new targets:" << cachedTargetItems;
i = -1; // start delivery again
continue;
}
}
+
foreach (QGesture *g, startedGestures) {
if (g->gestureCancelPolicy() == QGesture::CancelAllInContext) {
DEBUG() << "lets try to cancel some";
// find gestures in context in Qt::GestureStarted or Qt::GestureUpdated state and cancel them
- cancelGesturesForChildren(g, event->widget());
+ cancelGesturesForChildren(g);
}
}
@@ -6220,9 +6187,13 @@ void QGraphicsScenePrivate::gestureEventHandler(QGestureEvent *event)
break;
}
}
+
+ cachedTargetItems.clear();
+ cachedItemGestures.clear();
+ cachedAlreadyDeliveredGestures.clear();
}
-void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidget *viewport)
+void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
{
Q_ASSERT(original);
QGraphicsItem *originalItem = gestureTargets.value(original);
@@ -6278,8 +6249,7 @@ void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original, QWidge
if (!g->hasHotSpot())
continue;
- QPoint screenPos = g->hotSpot().toPoint();
- QList<QGraphicsItem *> items = itemsAtPosition(screenPos, QPointF(), viewport);
+ QList<QGraphicsItem *> items = itemsAtPosition(QPoint(), g->d_func()->sceneHotSpot, 0);
for (int j = 0; j < items.size(); ++j) {
QGraphicsObject *item = items.at(j)->toGraphicsObject();
if (!item)
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 04ffe0f..ca8b829 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -294,13 +294,18 @@ public:
bool allItemsIgnoreTouchEvents;
void enableTouchEventsOnViews();
+ QList<QGraphicsObject *> cachedTargetItems;
+ QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures;
+ QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures;
QHash<QGesture *, QGraphicsObject *> gestureTargets;
void gestureEventHandler(QGestureEvent *event);
- void getGestureTargets(const QSet<QGesture *> &gestures, QWidget *viewport,
- QMap<Qt::GestureType, QGesture *> *conflictedGestures,
- QList<QList<QGraphicsObject *> > *conflictedItems,
- QHash<QGesture *, QGraphicsObject *> *normalGestures);
- void cancelGesturesForChildren(QGesture *original, QWidget *viewport);
+ void gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures,
+ Qt::GestureFlag flag,
+ QHash<QGraphicsObject *, QSet<QGesture *> > *targets,
+ QSet<QGraphicsObject *> *itemsSet = 0,
+ QSet<QGesture *> *normal = 0,
+ QSet<QGesture *> *conflicts = 0);
+ void cancelGesturesForChildren(QGesture *original);
void updateInputMethodSensitivityInViews();
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index c347410..6a16403 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -419,6 +419,8 @@ extern "C" {
- (BOOL)isOpaque;
{
+ if (!qwidgetprivate)
+ return [super isOpaque];
return qwidgetprivate->isOpaque;
}
@@ -450,7 +452,7 @@ extern "C" {
}
// Make sure the opengl context is updated on resize.
- if (qwidgetprivate->isGLWidget) {
+ if (qwidgetprivate && qwidgetprivate->isGLWidget) {
qwidgetprivate->needWindowChange = true;
QEvent event(QEvent::MacGLWindowChange);
qApp->sendEvent(qwidget, &event);
@@ -459,6 +461,9 @@ extern "C" {
- (void)drawRect:(NSRect)aRect
{
+ if (!qwidget)
+ return;
+
if (QApplicationPrivate::graphicsSystem() != 0) {
if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) {
// Drawing is handled on the window level
@@ -552,12 +557,18 @@ extern "C" {
- (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
{
+ if (!qwidget)
+ return NO;
+
Q_UNUSED(theEvent);
return !qwidget->testAttribute(Qt::WA_MacNoClickThrough);
}
- (NSView *)hitTest:(NSPoint)aPoint
{
+ if (!qwidget)
+ return [super hitTest:aPoint];
+
if (qwidget->testAttribute(Qt::WA_TransparentForMouseEvents))
return nil; // You cannot hit a transparent for mouse event widget.
return [super hitTest:aPoint];
@@ -565,6 +576,9 @@ extern "C" {
- (void)updateTrackingAreas
{
+ if (!qwidget)
+ return;
+
// [NSView addTrackingArea] is slow, so bail out early if we can:
if (NSIsEmptyRect([self visibleRect]))
return;
@@ -598,6 +612,9 @@ extern "C" {
- (void)mouseEntered:(NSEvent *)event
{
+ if (!qwidget)
+ return;
+
if (qwidgetprivate->data.in_destructor)
return;
QEvent enterEvent(QEvent::Enter);
@@ -620,6 +637,9 @@ extern "C" {
- (void)mouseExited:(NSEvent *)event
{
+ if (!qwidget)
+ return;
+
QEvent leaveEvent(QEvent::Leave);
NSPoint globalPoint = [[event window] convertBaseToScreen:[event locationInWindow]];
if (!qAppInstance()->activeModalWidget() || QApplicationPrivate::tryModalHelper(qwidget, 0)) {
@@ -638,6 +658,9 @@ extern "C" {
- (void)flagsChanged:(NSEvent *)theEvent
{
+ if (!qwidget)
+ return;
+
QWidget *widgetToGetKey = qwidget;
QWidget *popup = qAppInstance()->activePopupWidget();
@@ -649,6 +672,9 @@ extern "C" {
- (void)mouseMoved:(NSEvent *)theEvent
{
+ if (!qwidget)
+ return;
+
// We always enable mouse tracking for all QCocoaView-s. In cases where we have
// child views, we will receive mouseMoved for both parent & the child (if
// mouse is over the child). We need to ignore the parent mouseMoved in such
@@ -939,6 +965,8 @@ extern "C" {
- (void)frameDidChange:(NSNotification *)note
{
Q_UNUSED(note);
+ if (!qwidget)
+ return;
if (qwidget->isWindow())
return;
NSRect newFrame = [self frame];
@@ -962,7 +990,7 @@ extern "C" {
{
QMacCocoaAutoReleasePool pool;
[super setEnabled:flag];
- if (qwidget->isEnabled() != flag)
+ if (qwidget && qwidget->isEnabled() != flag)
qwidget->setEnabled(flag);
}
@@ -973,6 +1001,8 @@ extern "C" {
- (BOOL)acceptsFirstResponder
{
+ if (!qwidget)
+ return NO;
if (qwidget->isWindow())
return YES; // Always do it, so that windows can accept key press events.
return qwidget->focusPolicy() != Qt::NoFocus;
@@ -980,6 +1010,8 @@ extern "C" {
- (BOOL)resignFirstResponder
{
+ if (!qwidget)
+ return NO;
// Seems like the following test only triggers if this
// view is inside a QMacNativeWidget:
if (qwidget == QApplication::focusWidget())
@@ -1015,6 +1047,12 @@ extern "C" {
return qwidget;
}
+- (void) qt_clearQWidget
+{
+ qwidget = 0;
+ qwidgetprivate = 0;
+}
+
- (BOOL)qt_leftButtonIsRightButton
{
return leftButtonIsRightButton;
@@ -1068,9 +1106,11 @@ extern "C" {
- (void)viewWillMoveToWindow:(NSWindow *)window
{
+ if (qwidget == 0)
+ return;
+
if (qwidget->windowFlags() & Qt::MSWindowsOwnDC
&& (window != [self window])) { // OpenGL Widget
- // Create a stupid ClearDrawable Event
QEvent event(QEvent::MacGLClearDrawable);
qApp->sendEvent(qwidget, &event);
}
@@ -1078,6 +1118,9 @@ extern "C" {
- (void)viewDidMoveToWindow
{
+ if (qwidget == 0)
+ return;
+
if (qwidget->windowFlags() & Qt::MSWindowsOwnDC && [self window]) {
// call update paint event
qwidgetprivate->needWindowChange = true;
@@ -1273,6 +1316,9 @@ extern "C" {
- (NSArray*) validAttributesForMarkedText
{
+ if (qwidget == 0)
+ return nil;
+
if (!qwidget->testAttribute(Qt::WA_InputMethodEnabled))
return nil; // Not sure if that's correct, but it's saves a malloc.
diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h
index 4bb10c5..33aaa24 100644
--- a/src/gui/kernel/qcocoaview_mac_p.h
+++ b/src/gui/kernel/qcocoaview_mac_p.h
@@ -103,6 +103,7 @@ Q_GUI_EXPORT
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation;
- (BOOL)isComposing;
- (QWidget *)qt_qwidget;
+- (void) qt_clearQWidget;
- (BOOL)qt_leftButtonIsRightButton;
- (void)qt_setLeftButtonIsRightButton:(BOOL)isSwapped;
+ (DnDParams*)currentMouseEvent;
diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h
index dee5592..649a310 100644
--- a/src/gui/kernel/qgesture_p.h
+++ b/src/gui/kernel/qgesture_p.h
@@ -69,13 +69,13 @@ public:
QGesturePrivate()
: gestureType(Qt::CustomGesture), state(Qt::NoGesture),
isHotSpotSet(false), gestureCancelPolicy(0)
-
{
}
Qt::GestureType gestureType;
Qt::GestureState state;
QPointF hotSpot;
+ QPointF sceneHotSpot;
uint isHotSpotSet : 1;
uint gestureCancelPolicy : 2;
};
diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp
index 8735d27..c88a9a7 100644
--- a/src/gui/kernel/qgesturerecognizer.cpp
+++ b/src/gui/kernel/qgesturerecognizer.cpp
@@ -181,6 +181,7 @@ void QGestureRecognizer::reset(QGesture *gesture)
QGesturePrivate *d = gesture->d_func();
d->state = Qt::NoGesture;
d->hotSpot = QPointF();
+ d->sceneHotSpot = QPointF();
d->isHotSpotSet = false;
}
}
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index e9fdbda..9560952 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -369,6 +369,16 @@ QMacTabletHash *qt_mac_tablet_hash()
}
#ifdef QT_MAC_USE_COCOA
+
+// Clears the QWidget pointer that each QCocoaView holds.
+void qt_mac_clearCocoaViewQWidgetPointers(QWidget *widget)
+{
+ QCocoaView *cocoaView = reinterpret_cast<QCocoaView *>(qt_mac_nativeview_for(widget));
+ if (cocoaView && [cocoaView respondsToSelector:@selector(qt_qwidget)]) {
+ [cocoaView qt_clearQWidget];
+ }
+}
+
void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent)
{
NSEvent *proximityEvent = static_cast<NSEvent *>(tabletEvent);
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index d433048..1e9b1d9 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -1468,6 +1468,15 @@ QWidget::~QWidget()
d->declarativeData = 0; // don't activate again in ~QObject
}
+#ifdef QT_MAC_USE_COCOA
+ // QCocoaView holds a pointer back to this widget. Clear it now
+ // to make sure it's not followed later on. The lifetime of the
+ // QCocoaView might exceed the lifetime of this widget in cases
+ // where Cocoa itself holds references to it.
+ extern void qt_mac_clearCocoaViewQWidgetPointers(QWidget *);
+ qt_mac_clearCocoaViewQWidgetPointers(this);
+#endif
+
if (!d->children.isEmpty())
d->deleteChildren();
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index fae26e0..891f4c2 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -46,6 +46,7 @@
#include <private/qdrawhelper_armv6_p.h>
#include <private/qdrawhelper_neon_p.h>
#include <private/qmath_p.h>
+#include <private/qsimd_p.h>
#include <qmath.h>
QT_BEGIN_NAMESPACE
@@ -7720,199 +7721,6 @@ static void qt_memfill16_setup(quint16 *dest, quint16 value, int count);
qt_memfill32_func qt_memfill32 = qt_memfill32_setup;
qt_memfill16_func qt_memfill16 = qt_memfill16_setup;
-enum CPUFeatures {
- None = 0,
- MMX = 0x1,
- MMXEXT = 0x2,
- MMX3DNOW = 0x4,
- MMX3DNOWEXT = 0x8,
- SSE = 0x10,
- SSE2 = 0x20,
- CMOV = 0x40,
- IWMMXT = 0x80,
- NEON = 0x100
-};
-
-static uint detectCPUFeatures()
-{
-#if defined (Q_OS_WINCE)
-#if defined (ARM)
- if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX))
- return IWMMXT;
-#elif defined(_X86_)
- uint features = 0;
-#if defined QT_HAVE_MMX
- if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))
- features |= MMX;
-#endif
-#if defined QT_HAVE_3DNOW
- if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE))
- features |= MMX3DNOW;
-#endif
- return features;
-#endif
- return 0;
-#elif defined(QT_HAVE_IWMMXT)
- // runtime detection only available when running as a previlegied process
- static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
- return doIWMMXT ? IWMMXT : 0;
-#elif defined(QT_HAVE_NEON)
- static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
- return doNEON ? NEON : 0;
-#else
- uint features = 0;
-#if defined(__x86_64__) || defined(Q_OS_WIN64)
- features = MMX|SSE|SSE2|CMOV;
-#elif defined(__ia64__)
- features = MMX|SSE|SSE2;
-#elif defined(__i386__) || defined(_M_IX86)
- unsigned int extended_result = 0;
- uint result = 0;
- /* see p. 118 of amd64 instruction set manual Vol3 */
-#if defined(Q_CC_GNU)
- asm ("push %%ebx\n"
- "pushf\n"
- "pop %%eax\n"
- "mov %%eax, %%ebx\n"
- "xor $0x00200000, %%eax\n"
- "push %%eax\n"
- "popf\n"
- "pushf\n"
- "pop %%eax\n"
- "xor %%edx, %%edx\n"
- "xor %%ebx, %%eax\n"
- "jz 1f\n"
-
- "mov $0x00000001, %%eax\n"
- "cpuid\n"
- "1:\n"
- "pop %%ebx\n"
- "mov %%edx, %0\n"
- : "=r" (result)
- :
- : "%eax", "%ecx", "%edx"
- );
-
- asm ("push %%ebx\n"
- "pushf\n"
- "pop %%eax\n"
- "mov %%eax, %%ebx\n"
- "xor $0x00200000, %%eax\n"
- "push %%eax\n"
- "popf\n"
- "pushf\n"
- "pop %%eax\n"
- "xor %%edx, %%edx\n"
- "xor %%ebx, %%eax\n"
- "jz 2f\n"
-
- "mov $0x80000000, %%eax\n"
- "cpuid\n"
- "cmp $0x80000000, %%eax\n"
- "jbe 2f\n"
- "mov $0x80000001, %%eax\n"
- "cpuid\n"
- "2:\n"
- "pop %%ebx\n"
- "mov %%edx, %0\n"
- : "=r" (extended_result)
- :
- : "%eax", "%ecx", "%edx"
- );
-#elif defined (Q_OS_WIN)
- _asm {
- push eax
- push ebx
- push ecx
- push edx
- pushfd
- pop eax
- mov ebx, eax
- xor eax, 00200000h
- push eax
- popfd
- pushfd
- pop eax
- mov edx, 0
- xor eax, ebx
- jz skip
-
- mov eax, 1
- cpuid
- mov result, edx
- skip:
- pop edx
- pop ecx
- pop ebx
- pop eax
- }
-
- _asm {
- push eax
- push ebx
- push ecx
- push edx
- pushfd
- pop eax
- mov ebx, eax
- xor eax, 00200000h
- push eax
- popfd
- pushfd
- pop eax
- mov edx, 0
- xor eax, ebx
- jz skip2
-
- mov eax, 80000000h
- cpuid
- cmp eax, 80000000h
- jbe skip2
- mov eax, 80000001h
- cpuid
- mov extended_result, edx
- skip2:
- pop edx
- pop ecx
- pop ebx
- pop eax
- }
-#endif
-
- // result now contains the standard feature bits
- if (result & (1u << 15))
- features |= CMOV;
- if (result & (1u << 23))
- features |= MMX;
- if (extended_result & (1u << 22))
- features |= MMXEXT;
- if (extended_result & (1u << 31))
- features |= MMX3DNOW;
- if (extended_result & (1u << 30))
- features |= MMX3DNOWEXT;
- if (result & (1u << 25))
- features |= SSE;
- if (result & (1u << 26))
- features |= SSE2;
-#endif // i386
-
- if (qgetenv("QT_NO_MMX").toInt())
- features ^= MMX;
- if (qgetenv("QT_NO_MMXEXT").toInt())
- features ^= MMXEXT;
- if (qgetenv("QT_NO_3DNOW").toInt())
- features ^= MMX3DNOW;
- if (qgetenv("QT_NO_3DNOWEXT").toInt())
- features ^= MMX3DNOWEXT;
- if (qgetenv("QT_NO_SSE").toInt())
- features ^= SSE;
- if (qgetenv("QT_NO_SSE2").toInt())
- features ^= SSE2;
-
- return features;
-#endif
-}
-
#if defined(Q_CC_RVCT) && defined(QT_HAVE_ARMV6)
// Move these to qdrawhelper_arm.c when all
// functions are implemented using arm assembly.
@@ -8005,10 +7813,7 @@ static void qt_blend_color_argb_armv6(int count, const QSpan *spans, void *userD
void qInitDrawhelperAsm()
{
- static uint features = 0xffffffff;
- if (features != 0xffffffff)
- return;
- features = detectCPUFeatures();
+ const uint features = qDetectCPUFeatures();
qt_memfill32 = qt_memfill_template<quint32, quint32>;
qt_memfill16 = qt_memfill_quint16; //qt_memfill_template<quint16, quint16>;
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index 2f78b00..f5b17ea 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -67,15 +67,6 @@
#include "QtGui/qscreen_qws.h"
#endif
-// Disable MMX and SSE on Mac/PPC builds, or if the compiler
-// does not support -Xarch argument passing
-#if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))
-#undef QT_HAVE_SSE2
-#undef QT_HAVE_SSE
-#undef QT_HAVE_3DNOW
-#undef QT_HAVE_MMX
-#endif
-
QT_BEGIN_NAMESPACE
#if defined(Q_CC_MSVC) && _MSCVER <= 1300 && !defined(Q_CC_INTEL)
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 60265c5..a7c2a0b 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -3213,6 +3213,9 @@ QRasterPaintEnginePrivate::getPenFunc(const QRectF &rect,
return isUnclipped(rect, penWidth) ? data->unclipped_blend : data->blend;
}
+/*!
+ \reimp
+*/
void QRasterPaintEngine::drawStaticTextItem(QStaticTextItem *textItem)
{
ensurePen();