aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-12-12 10:35:21 +0100
committerShawn Rutledge <shawn.rutledge@qt.io>2018-01-04 14:41:16 +0100
commit2bee46e3f10e2c44d185d7a51a06830b68529676 (patch)
treeb65ac19203edfc2972b6020dd040e46c43b5d1fb /src/quick/items
parent52f7ab28172cea3710a16775b7a512fce821fc77 (diff)
parent41293196b4db1aa7a0c616af312875c484639644 (diff)
Merge remote-tracking branch 'origin/5.9' into 5.10
Conflicts: src/qml/memory/qv4mm.cpp src/qml/memory/qv4mmdefs_p.h src/quick/items/qquickwindow.cpp src/quick/items/qquickwindow_p.h tests/auto/qml/debugger/qqmlprofilerservice/qqmlprofilerservice.pro tests/auto/qml/debugger/qqmlprofilerservice/tst_qqmlprofilerservice.cpp Change-Id: I7021fa1edf076627a67048f41f7b201220262b09
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickgridview.cpp10
-rw-r--r--src/quick/items/qquickitem.cpp14
-rw-r--r--src/quick/items/qquickitemsmodule.cpp3
-rw-r--r--src/quick/items/qquickitemview.cpp20
-rw-r--r--src/quick/items/qquickitemview_p_p.h2
-rw-r--r--src/quick/items/qquicklistview.cpp10
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp37
-rw-r--r--src/quick/items/qquickpathview.cpp2
-rw-r--r--src/quick/items/qquickrepeater.cpp17
-rw-r--r--src/quick/items/qquickwindow.cpp65
-rw-r--r--src/quick/items/qquickwindow_p.h3
11 files changed, 114 insertions, 69 deletions
diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp
index c570b95a21..c56cfd3005 100644
--- a/src/quick/items/qquickgridview.cpp
+++ b/src/quick/items/qquickgridview.cpp
@@ -511,9 +511,11 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
FxGridItemSG *item = 0;
bool changed = false;
+ QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested;
+
while (modelIndex < model->count() && rowPos <= fillTo + rowSize()*(columns - colNum)/(columns+1)) {
qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << colPos << rowPos;
- if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, doBuffer))))
+ if (!(item = static_cast<FxGridItemSG*>(createItem(modelIndex, incubationMode))))
break;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
item->setPosition(colPos, rowPos, true);
@@ -548,7 +550,7 @@ bool QQuickGridViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
colPos = colNum * colSize();
while (visibleIndex > 0 && rowPos + rowSize() - 1 >= fillFrom - rowSize()*(colNum+1)/(columns+1)){
qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "top pos" << rowPos << colPos;
- if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, doBuffer))))
+ if (!(item = static_cast<FxGridItemSG*>(createItem(visibleIndex-1, incubationMode))))
break;
--visibleIndex;
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
@@ -2415,7 +2417,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
item->index = modelIndex + i;
if (!item)
- item = createItem(modelIndex + i);
+ item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
if (!item)
return false;
@@ -2468,7 +2470,7 @@ bool QQuickGridViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
item->index = modelIndex + i;
bool newItem = !item;
if (!item)
- item = createItem(modelIndex + i);
+ item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
if (!item)
return false;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 54fcbfbbf2..6b123d1dfe 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -7409,10 +7409,18 @@ void QQuickItem::unsetCursor()
void QQuickItem::grabMouse()
{
Q_D(QQuickItem);
- if (!d->window)
+ if (!d->window || d->window->mouseGrabberItem() == this)
return;
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
- windowPriv->setMouseGrabber(this);
+ bool fromTouch = windowPriv->isDeliveringTouchAsMouse();
+ auto point = fromTouch ?
+ windowPriv->pointerEventInstance(windowPriv->touchMouseDevice)->pointById(windowPriv->touchMouseId) :
+ windowPriv->pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0);
+ if (point) {
+ QQuickItem *oldGrabber = point->grabberItem();
+ point->setGrabberItem(this);
+ windowPriv->sendUngrabEvent(oldGrabber, fromTouch);
+ }
}
/*!
@@ -7430,7 +7438,7 @@ void QQuickItem::ungrabMouse()
if (!d->window)
return;
QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(d->window);
- windowPriv->removeGrabber(this, true, false);
+ windowPriv->removeGrabber(this, true, windowPriv->isDeliveringTouchAsMouse());
}
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 1406e5b547..fcf6e49135 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -287,7 +287,8 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickMultiPointTouchArea>("QtQuick", 2, 0, "MultiPointTouchArea");
qmlRegisterType<QQuickTouchPoint>("QtQuick", 2, 0, "TouchPoint");
- qmlRegisterType<QQuickGrabGestureEvent>();
+ qmlRegisterUncreatableType<QQuickGrabGestureEvent>(uri,major,minor, "GestureEvent",
+ QQuickMouseEvent::tr("GestureEvent is only available in the context of handling the gestureStarted signal from MultiPointTouchArea"));
#if QT_CONFIG(accessibility)
qmlRegisterUncreatableType<QQuickAccessibleAttached>("QtQuick", 2, 0, "Accessible",QQuickAccessibleAttached::tr("Accessible is only available via attached properties"));
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index c203f389ae..10f6c63170 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -1729,7 +1729,7 @@ void QQuickItemViewPrivate::updateCurrent(int modelIndex)
FxViewItem *oldCurrentItem = currentItem;
int oldCurrentIndex = currentIndex;
currentIndex = modelIndex;
- currentItem = createItem(modelIndex, false);
+ currentItem = createItem(modelIndex, QQmlIncubator::AsynchronousIfNested);
if (oldCurrentItem && oldCurrentItem->attached && (!currentItem || oldCurrentItem->item != currentItem->item))
oldCurrentItem->attached->setIsCurrentItem(false);
if (currentItem) {
@@ -2325,11 +2325,11 @@ void QQuickItemViewPrivate::viewItemTransitionFinished(QQuickItemViewTransitiona
When the item becomes available, refill() will be called and the item
will be returned on the next call to createItem().
*/
-FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
+FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, QQmlIncubator::IncubationMode incubationMode)
{
Q_Q(QQuickItemView);
- if (requestedIndex == modelIndex && asynchronous)
+ if (requestedIndex == modelIndex && incubationMode == QQmlIncubator::Asynchronous)
return 0;
for (int i=0; i<releasePendingTransition.count(); i++) {
@@ -2340,14 +2340,20 @@ FxViewItem *QQuickItemViewPrivate::createItem(int modelIndex, bool asynchronous)
}
}
- if (asynchronous)
- requestedIndex = modelIndex;
inRequest = true;
- QObject* object = model->object(modelIndex, asynchronous);
+ QObject* object = model->object(modelIndex, incubationMode);
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
+
if (!item) {
- if (object) {
+ if (!object) {
+ if (requestedIndex == -1 && model->incubationStatus(modelIndex) == QQmlIncubator::Loading) {
+ // The reason we didn't receive an item is because it's incubating async. We keep track
+ // of this by assigning the index we're waiting for to 'requestedIndex'. This will e.g. let
+ // the view avoid unnecessary layout calls until the item has been loaded.
+ requestedIndex = modelIndex;
+ }
+ } else {
model->release(object);
if (!delegateValidated) {
delegateValidated = true;
diff --git a/src/quick/items/qquickitemview_p_p.h b/src/quick/items/qquickitemview_p_p.h
index 2c04022cde..622ebb430f 100644
--- a/src/quick/items/qquickitemview_p_p.h
+++ b/src/quick/items/qquickitemview_p_p.h
@@ -206,7 +206,7 @@ public:
void refill(qreal from, qreal to);
void mirrorChange() override;
- FxViewItem *createItem(int modelIndex, bool asynchronous = false);
+ FxViewItem *createItem(int modelIndex,QQmlIncubator::IncubationMode incubationMode = QQmlIncubator::AsynchronousIfNested);
virtual bool releaseItem(FxViewItem *item);
QQuickItem *createHighlightItem() const;
diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp
index a6236d9801..11eaf393ea 100644
--- a/src/quick/items/qquicklistview.cpp
+++ b/src/quick/items/qquicklistview.cpp
@@ -669,11 +669,13 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
}
}
+ QQmlIncubator::IncubationMode incubationMode = doBuffer ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested;
+
bool changed = false;
FxListItemSG *item = 0;
qreal pos = itemEnd;
while (modelIndex < model->count() && pos <= fillTo) {
- if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, doBuffer))))
+ if (!(item = static_cast<FxListItemSG*>(createItem(modelIndex, incubationMode))))
break;
qCDebug(lcItemViewDelegateLifecycle) << "refill: append item" << modelIndex << "pos" << pos << "buffer" << doBuffer << "item" << (QObject *)(item->item);
if (!transitioner || !transitioner->canTransition(QQuickItemViewTransitioner::PopulateTransition, true)) // pos will be set by layoutVisibleItems()
@@ -690,7 +692,7 @@ bool QQuickListViewPrivate::addVisibleItems(qreal fillFrom, qreal fillTo, qreal
return changed;
while (visibleIndex > 0 && visibleIndex <= model->count() && visiblePos > fillFrom) {
- if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, doBuffer))))
+ if (!(item = static_cast<FxListItemSG*>(createItem(visibleIndex-1, incubationMode))))
break;
qCDebug(lcItemViewDelegateLifecycle) << "refill: prepend item" << visibleIndex-1 << "current top pos" << visiblePos << "buffer" << doBuffer << "item" << (QObject *)(item->item);
--visibleIndex;
@@ -3271,7 +3273,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
if (change.isMove() && (item = currentChanges.removedItems.take(change.moveKey(modelIndex + i))))
item->index = modelIndex + i;
if (!item)
- item = createItem(modelIndex + i);
+ item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
if (!item)
return false;
@@ -3313,7 +3315,7 @@ bool QQuickListViewPrivate::applyInsertionChange(const QQmlChangeSet::Change &ch
item->index = modelIndex + i;
bool newItem = !item;
if (!item)
- item = createItem(modelIndex + i);
+ item = createItem(modelIndex + i, QQmlIncubator::Synchronous);
if (!item)
return false;
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index 54136b1bbf..4f62d021a4 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -285,6 +285,43 @@ void QQuickTouchPoint::setUniqueId(const QPointingDeviceUniqueId &id)
emit uniqueIdChanged();
}
+
+/*!
+ \qmltype GestureEvent
+ \instantiates QQuickGrabGestureEvent
+ \inqmlmodule QtQuick
+ \ingroup qtquick-input-events
+ \brief The parameter given with the gestureStarted signal
+
+ The GestureEvent object has the current touch points, which you may choose
+ to interpret as a gesture, and an invokable method to grab the involved
+ points exclusively.
+*/
+
+/*!
+ \qmlproperty real QtQuick::GestureEvent::dragThreshold
+
+ This property holds the system setting for the distance a finger must move
+ before it is interpreted as a drag. It comes from
+ QStyleHints::startDragDistance().
+*/
+
+/*!
+ \qmlproperty list<TouchPoint> QtQuick::GestureEvent::touchPoints
+
+ This property holds the set of current touch points.
+*/
+
+/*!
+ \qmlmethod QtQuick::GestureEvent::grab()
+
+ Acquires an exclusive grab of the mouse and all the \l touchPoints, and
+ calls \l {QQuickItem::setKeepTouchGrab()}{setKeepTouchGrab()} and
+ \l {QQuickItem::setKeepMouseGrab()}{setKeepMouseGrab()} so that any
+ parent Item that \l {QQuickItem::filtersChildMouseEvents()}{filters} its
+ children's events will not be allowed to take over the grabs.
+*/
+
/*!
\qmltype MultiPointTouchArea
\instantiates QQuickMultiPointTouchArea
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index aac2b0296a..b9fea974ce 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -129,7 +129,7 @@ QQuickItem *QQuickPathViewPrivate::getItem(int modelIndex, qreal z, bool async)
requestedIndex = modelIndex;
requestedZ = z;
inRequest = true;
- QObject *object = model->object(modelIndex, async);
+ QObject *object = model->object(modelIndex, async ? QQmlIncubator::Asynchronous : QQmlIncubator::AsynchronousIfNested);
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
if (!item) {
if (object) {
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 6fc4c0553a..658a7de3d4 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -401,7 +401,7 @@ void QQuickRepeater::regenerate()
void QQuickRepeaterPrivate::requestItems()
{
for (int i = 0; i < itemCount; i++) {
- QObject *object = model->object(i, false);
+ QObject *object = model->object(i, QQmlIncubator::AsynchronousIfNested);
if (object)
model->release(object);
}
@@ -410,7 +410,7 @@ void QQuickRepeaterPrivate::requestItems()
void QQuickRepeater::createdItem(int index, QObject *)
{
Q_D(QQuickRepeater);
- QObject *object = d->model->object(index, false);
+ QObject *object = d->model->object(index, QQmlIncubator::AsynchronousIfNested);
QQuickItem *item = qmlobject_cast<QQuickItem*>(object);
emit itemAdded(index, item);
}
@@ -495,13 +495,20 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset)
QQuickItem *stackBefore = index + items.count() < d->deletables.count()
? d->deletables.at(index + items.count())
: this;
- for (int i = index; i < index + items.count(); ++i)
- d->deletables.at(i)->stackBefore(stackBefore);
+ if (stackBefore) {
+ for (int i = index; i < index + items.count(); ++i) {
+ if (i < d->deletables.count()) {
+ QPointer<QQuickItem> item = d->deletables.at(i);
+ if (item)
+ item->stackBefore(stackBefore);
+ }
+ }
+ }
} else for (int i = 0; i < insert.count; ++i) {
int modelIndex = index + i;
++d->itemCount;
d->deletables.insert(modelIndex, 0);
- QObject *object = d->model->object(modelIndex, false);
+ QObject *object = d->model->object(modelIndex, QQmlIncubator::AsynchronousIfNested);
if (object)
d->model->release(object);
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index 530d165850..a056575f41 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -747,44 +747,6 @@ bool QQuickWindowPrivate::deliverTouchAsMouse(QQuickItem *item, QQuickPointerEve
return false;
}
-void QQuickWindowPrivate::setMouseGrabber(QQuickItem *grabber)
-{
- Q_Q(QQuickWindow);
- if (q->mouseGrabberItem() == grabber)
- return;
-
- QQuickItem *oldGrabber = q->mouseGrabberItem();
- qCDebug(DBG_MOUSE_TARGET) << "grabber" << oldGrabber << "->" << grabber;
-
- if (grabber && touchMouseId != -1 && touchMouseDevice) {
- // update the touch item for mouse touch id to the new grabber
- qCDebug(DBG_TOUCH_TARGET) << "TP (mouse)" << hex << touchMouseId << "->" << q->mouseGrabberItem();
- auto point = pointerEventInstance(touchMouseDevice)->pointById(touchMouseId);
- if (point) {
- auto originalEvent = pointerEventInstance(point->pointerEvent()->device());
- for (int i = 0; i < originalEvent->pointCount(); ++i) {
- QQuickEventPoint *pt = originalEvent->point(i);
- if (pt->exclusiveGrabber())
- pt->cancelExclusiveGrab();
- }
- point->setGrabberItem(grabber);
- }
- } else {
- QQuickPointerEvent *event = pointerEventInstance(QQuickPointerDevice::genericMouseDevice());
- Q_ASSERT(event->pointCount() == 1);
- auto point = event->point(0);
- point->setGrabberItem(grabber);
- }
-
-
- if (oldGrabber) {
- QEvent e(QEvent::UngrabMouse);
- hasFiltered.clear();
- if (!sendFilteredMouseEvent(&e, oldGrabber, oldGrabber->parentItem()))
- oldGrabber->mouseUngrabEvent();
- }
-}
-
void QQuickWindowPrivate::grabTouchPoints(QObject *grabber, const QVector<int> &ids)
{
for (int i = 0; i < ids.count(); ++i) {
@@ -832,8 +794,14 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to
{
Q_Q(QQuickWindow);
if (Q_LIKELY(mouse) && q->mouseGrabberItem() == grabber) {
- qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << q->mouseGrabberItem() << "-> null";
- setMouseGrabber(nullptr);
+ bool fromTouch = isDeliveringTouchAsMouse();
+ auto point = fromTouch ?
+ pointerEventInstance(touchMouseDevice)->pointById(touchMouseId) :
+ pointerEventInstance(QQuickPointerDevice::genericMouseDevice())->point(0);
+ QQuickItem *oldGrabber = point->grabberItem();
+ qCDebug(DBG_MOUSE_TARGET) << "removeGrabber" << oldGrabber << "-> null";
+ point->setGrabberItem(nullptr);
+ sendUngrabEvent(oldGrabber, fromTouch);
}
if (Q_LIKELY(touch)) {
bool ungrab = false;
@@ -853,6 +821,19 @@ void QQuickWindowPrivate::removeGrabber(QQuickItem *grabber, bool mouse, bool to
}
}
+void QQuickWindowPrivate::sendUngrabEvent(QQuickItem *grabber, bool touch)
+{
+ if (!grabber)
+ return;
+ QEvent e(QEvent::UngrabMouse);
+ hasFiltered.clear();
+ if (!sendFilteredMouseEvent(&e, grabber, grabber->parentItem())) {
+ grabber->mouseUngrabEvent();
+ if (touch)
+ grabber->touchUngrabEvent();
+ }
+}
+
/*!
Translates the data in \a touchEvent to this window. This method leaves the item local positions in
\a touchEvent untouched (these are filled in later).
@@ -1511,7 +1492,7 @@ QQuickItem *QQuickWindow::mouseGrabberItem() const
{
Q_D(const QQuickWindow);
- if (d->touchMouseId != -1 && d->touchMouseDevice) {
+ if (d->isDeliveringTouchAsMouse()) {
if (QQuickPointerEvent *event = d->queryPointerEventInstance(d->touchMouseDevice)) {
auto point = event->pointById(d->touchMouseId);
return point ? point->grabberItem() : nullptr;
@@ -1736,7 +1717,7 @@ void QQuickWindowPrivate::deliverMouseEvent(QQuickPointerMouseEvent *pointerEven
// release event: ungrab if no buttons are pressed anymore
if (mouseIsReleased)
- setMouseGrabber(nullptr);
+ removeGrabber(grabber, true, isDeliveringTouchAsMouse());
} else {
// if the grabber is not an Item, it must be a PointerHandler
auto handler = point->grabberPointerHandler();
diff --git a/src/quick/items/qquickwindow_p.h b/src/quick/items/qquickwindow_p.h
index b17fdf7a49..b2a6c2c2ac 100644
--- a/src/quick/items/qquickwindow_p.h
+++ b/src/quick/items/qquickwindow_p.h
@@ -141,10 +141,11 @@ public:
// Mouse positions are saved in widget coordinates
QPointF lastMousePosition;
bool deliverTouchAsMouse(QQuickItem *item, QQuickPointerEvent *pointerEvent);
+ bool isDeliveringTouchAsMouse() const { return touchMouseId != -1 && touchMouseDevice; }
void translateTouchEvent(QTouchEvent *touchEvent);
- void setMouseGrabber(QQuickItem *grabber);
void grabTouchPoints(QObject *grabber, const QVector<int> &ids);
void removeGrabber(QQuickItem *grabber, bool mouse = true, bool touch = true);
+ void sendUngrabEvent(QQuickItem *grabber, bool touch);
static QMouseEvent *cloneMouseEvent(QMouseEvent *event, QPointF *transformedLocalPos = 0);
void deliverToPassiveGrabbers(const QVector<QPointer <QQuickPointerHandler> > &passiveGrabbers, QQuickPointerEvent *pointerEvent);
void deliverMouseEvent(QQuickPointerMouseEvent *pointerEvent);