diff options
-rw-r--r-- | src/qml/compiler/qqmltypecompiler.cpp | 4 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 27 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 1 | ||||
-rw-r--r-- | src/quick/items/qquickflickable.cpp | 41 | ||||
-rw-r--r-- | src/quick/items/qquickflickable_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickmousearea_p.h | 34 | ||||
-rw-r--r-- | src/quick/items/qquickscreen_p.h | 18 | ||||
-rw-r--r-- | src/quick/items/qquickshadereffectsource.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.cpp | 60 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/testtypes.h | 45 | ||||
-rw-r--r-- | tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp | 28 | ||||
-rw-r--r-- | tests/auto/qmltest/listview/tst_listview.qml | 41 |
13 files changed, 248 insertions, 57 deletions
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index e2636a57c3..b8ada7ceaf 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -277,12 +277,12 @@ bool QQmlTypeCompiler::compile() if (qmlType->parserStatusCast() != -1) ++parserStatusCount; } + ++objectCount; if (typeRef->component) { bindingCount += typeRef->component->totalBindingsCount; parserStatusCount += typeRef->component->totalParserStatusCount; objectCount += typeRef->component->totalObjectCount; - } else - ++objectCount; + } } } diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 93060e97fb..e3e1434746 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -239,7 +239,7 @@ bool QQmlData::wasDeleted(QObject *object) return true; QObjectPrivate *priv = QObjectPrivate::get(object); - if (priv->wasDeleted) + if (!priv || priv->wasDeleted) return true; return priv->declarativeData && diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 9501b705ba..72920f1ae2 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -96,6 +96,7 @@ QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompile sharedState->allCreatedBindings.allocate(compiledData->totalBindingsCount); sharedState->allParserStatusCallbacks.allocate(compiledData->totalParserStatusCount); sharedState->allCreatedObjects.allocate(compiledData->totalObjectCount); + sharedState->allJavaScriptObjects = 0; sharedState->creationContext = creationContext; sharedState->rootContext = 0; @@ -195,6 +196,13 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI sharedState->rootContext->isRootObjectInCreation = true; } + QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + QV4::Scope scope(v4); + + Q_ASSERT(sharedState->allJavaScriptObjects || topLevelCreator); + if (topLevelCreator) + sharedState->allJavaScriptObjects = scope.alloc(compiledData->totalObjectCount); + QVector<QQmlContextData::ObjectIdMapping> mapping(objectIndexToId.count()); for (QHash<int, int>::ConstIterator it = objectIndexToId.constBegin(), end = objectIndexToId.constEnd(); it != end; ++it) { @@ -208,8 +216,6 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI context->setIdPropertyData(mapping); if (subComponentIndex == -1) { - QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); - QV4::Scope scope(v4); QV4::ScopedObject scripts(scope, v4->newArrayObject(compiledData->scripts.count())); context->importedScripts = scripts; for (int i = 0; i < compiledData->scripts.count(); ++i) { @@ -230,6 +236,9 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI ddata->compiledData->addref(); } + if (topLevelCreator) + sharedState->allJavaScriptObjects = 0; + phase = CreatingObjectsPhase2; if (interrupt && interrupt->shouldInterrupt()) @@ -258,8 +267,11 @@ bool QQmlObjectCreator::populateDeferredProperties(QObject *instance) QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); QV4::Scope valueScope(v4); - QV4::ScopedValue scopeObjectProtector(valueScope, declarativeData->jsWrapper.value()); - Q_UNUSED(scopeObjectProtector); + + Q_ASSERT(topLevelCreator); + Q_ASSERT(!sharedState->allJavaScriptObjects); + sharedState->allJavaScriptObjects = valueScope.alloc(compiledData->totalObjectCount); + QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject)); QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(v4->rootContext, qmlScope)); QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context(); @@ -1159,9 +1171,12 @@ QObject *QQmlObjectCreator::createInstance(int index, QObject *parent, bool isCo qSwap(_scopeObject, scopeObject); QV4::ExecutionEngine *v4 = QV8Engine::getV4(engine); + + Q_ASSERT(sharedState->allJavaScriptObjects); + QV4::ValueRef ref = QV4::ValueRef::fromRawValue(sharedState->allJavaScriptObjects++); + ref = QV4::QObjectWrapper::wrap(v4, instance); + QV4::Scope valueScope(v4); - QV4::ScopedValue scopeObjectProtector(valueScope, ddata ? ddata->jsWrapper.value() : 0); - Q_UNUSED(scopeObjectProtector); QV4::ScopedObject qmlScope(valueScope, QV4::QmlContextWrapper::qmlScope(QV8Engine::get(engine), context, _scopeObject)); QV4::Scoped<QV4::QmlBindingWrapper> qmlBindingWrapper(valueScope, v4->memoryManager->alloc<QV4::QmlBindingWrapper>(v4->rootContext, qmlScope)); QV4::ExecutionContext *qmlContext = qmlBindingWrapper->context(); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index ad2d67624f..fb4d71d054 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -64,6 +64,7 @@ struct QQmlObjectCreatorSharedState : public QSharedData QFiniteStack<QQmlAbstractBinding*> allCreatedBindings; QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks; QFiniteStack<QObject*> allCreatedObjects; + QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase. QQmlComponentAttached *componentAttached; QList<QQmlEnginePrivate::FinalizeCallback> finalizeCallbacks; QQmlVmeProfiler profiler; diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 3f072359d2..ce2cedb7fc 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -763,15 +763,8 @@ void QQuickFlickable::setInteractive(bool interactive) Q_D(QQuickFlickable); if (interactive != d->interactive) { d->interactive = interactive; - if (!interactive && (d->hData.flicking || d->vData.flicking)) { - d->clearTimeline(); - d->hData.vTime = d->vData.vTime = d->timeline.time(); - d->hData.flicking = false; - d->vData.flicking = false; - emit flickingChanged(); - emit flickingHorizontallyChanged(); - emit flickingVerticallyChanged(); - emit flickEnded(); + if (!interactive) { + d->cancelInteraction(); } emit interactiveChanged(); } @@ -2015,18 +2008,24 @@ bool QQuickFlickable::yflick() const void QQuickFlickable::mouseUngrabEvent() { Q_D(QQuickFlickable); - if (d->pressed) { - // if our mouse grab has been removed (probably by another Flickable), - // fix our state - d->clearDelayedPress(); - d->pressed = false; - d->draggingEnding(); - d->stealMouse = false; - setKeepMouseGrab(false); - d->fixupX(); - d->fixupY(); - if (!d->isViewMoving()) - movementEnding(); + // if our mouse grab has been removed (probably by another Flickable), + // fix our state + d->cancelInteraction(); +} + +void QQuickFlickablePrivate::cancelInteraction() +{ + Q_Q(QQuickFlickable); + if (pressed) { + clearDelayedPress(); + pressed = false; + draggingEnding(); + stealMouse = false; + q->setKeepMouseGrab(false); + fixupX(); + fixupY(); + if (!isViewMoving()) + q->movementEnding(); } } diff --git a/src/quick/items/qquickflickable_p_p.h b/src/quick/items/qquickflickable_p_p.h index 33a642eb69..13af2e055c 100644 --- a/src/quick/items/qquickflickable_p_p.h +++ b/src/quick/items/qquickflickable_p_p.h @@ -200,6 +200,8 @@ public: bool isViewMoving() const; + void cancelInteraction(); + public: QQuickItem *contentItem; diff --git a/src/quick/items/qquickmousearea_p.h b/src/quick/items/qquickmousearea_p.h index d303852311..5dcb6b46a4 100644 --- a/src/quick/items/qquickmousearea_p.h +++ b/src/quick/items/qquickmousearea_p.h @@ -144,25 +144,25 @@ protected: bool setPressed(Qt::MouseButton button, bool); bool sendMouseEvent(QMouseEvent *event); - virtual void mousePressEvent(QMouseEvent *event); - virtual void mouseReleaseEvent(QMouseEvent *event); - virtual void mouseDoubleClickEvent(QMouseEvent *event); - virtual void mouseMoveEvent(QMouseEvent *event); - virtual void mouseUngrabEvent(); - virtual void hoverEnterEvent(QHoverEvent *event); - virtual void hoverMoveEvent(QHoverEvent *event); - virtual void hoverLeaveEvent(QHoverEvent *event); + void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseDoubleClickEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE; + void mouseUngrabEvent() Q_DECL_OVERRIDE; + void hoverEnterEvent(QHoverEvent *event) Q_DECL_OVERRIDE; + void hoverMoveEvent(QHoverEvent *event) Q_DECL_OVERRIDE; + void hoverLeaveEvent(QHoverEvent *event) Q_DECL_OVERRIDE; #ifndef QT_NO_WHEELEVENT - virtual void wheelEvent(QWheelEvent *event); + void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE; #endif - virtual bool childMouseEventFilter(QQuickItem *i, QEvent *e); - virtual void timerEvent(QTimerEvent *event); - virtual void windowDeactivateEvent(); - - virtual void geometryChanged(const QRectF &newGeometry, - const QRectF &oldGeometry); - virtual void itemChange(ItemChange change, const ItemChangeData& value); - virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); + bool childMouseEventFilter(QQuickItem *i, QEvent *e) Q_DECL_OVERRIDE; + void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE; + void windowDeactivateEvent() Q_DECL_OVERRIDE; + + void geometryChanged(const QRectF &newGeometry, + const QRectF &oldGeometry) Q_DECL_OVERRIDE; + void itemChange(ItemChange change, const ItemChangeData& value) Q_DECL_OVERRIDE; + QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; private: void handlePress(); diff --git a/src/quick/items/qquickscreen_p.h b/src/quick/items/qquickscreen_p.h index a155ff1843..25a1805a44 100644 --- a/src/quick/items/qquickscreen_p.h +++ b/src/quick/items/qquickscreen_p.h @@ -58,13 +58,13 @@ class Q_AUTOTEST_EXPORT QQuickScreenAttached : public QObject { Q_OBJECT - Q_PROPERTY(QString name READ name NOTIFY nameChanged REVISION 1); + Q_PROPERTY(QString name READ name NOTIFY nameChanged); Q_PROPERTY(int width READ width NOTIFY widthChanged) Q_PROPERTY(int height READ height NOTIFY heightChanged) - Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged REVISION 1) - Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged REVISION 1) - Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged REVISION 1) - Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged REVISION 2) + Q_PROPERTY(int desktopAvailableWidth READ desktopAvailableWidth NOTIFY desktopGeometryChanged) + Q_PROPERTY(int desktopAvailableHeight READ desktopAvailableHeight NOTIFY desktopGeometryChanged) + Q_PROPERTY(qreal logicalPixelDensity READ logicalPixelDensity NOTIFY logicalPixelDensityChanged) + Q_PROPERTY(qreal pixelDensity READ pixelDensity NOTIFY pixelDensityChanged) Q_PROPERTY(Qt::ScreenOrientation primaryOrientation READ primaryOrientation NOTIFY primaryOrientationChanged) Q_PROPERTY(Qt::ScreenOrientation orientation READ orientation NOTIFY orientationChanged) @@ -87,12 +87,12 @@ public: void windowChanged(QQuickWindow*); Q_SIGNALS: - Q_REVISION(1) void nameChanged(); + void nameChanged(); void widthChanged(); void heightChanged(); - Q_REVISION(1) void desktopGeometryChanged(); - Q_REVISION(1) void logicalPixelDensityChanged(); - Q_REVISION(2) void pixelDensityChanged(); + void desktopGeometryChanged(); + void logicalPixelDensityChanged(); + void pixelDensityChanged(); void primaryOrientationChanged(); void orientationChanged(); diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index 163ee3eada..7603495e1b 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -1037,7 +1037,7 @@ QSGNode *QQuickShaderEffectSource::updatePaintNode(QSGNode *oldNode, UpdatePaint } // Don't create the paint node if we're not spanning any area - if (width() == 0 || height() == 0) { + if (width() <= 0 || height() <= 0) { delete oldNode; return 0; } diff --git a/tests/auto/qml/qqmlecmascript/testtypes.cpp b/tests/auto/qml/qqmlecmascript/testtypes.cpp index 56e733a423..c4e6709958 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.cpp +++ b/tests/auto/qml/qqmlecmascript/testtypes.cpp @@ -338,6 +338,62 @@ static QObject *create_singletonWithEnum(QQmlEngine *, QJSEngine *) return new SingletonWithEnum; } +QObjectContainer::QObjectContainer() + : widgetParent(0) + , gcOnAppend(false) +{} + +QQmlListProperty<QObject> QObjectContainer::data() +{ + return QQmlListProperty<QObject>(this, 0, children_append, children_count, children_at, children_clear); +} + +void QObjectContainer::children_append(QQmlListProperty<QObject> *prop, QObject *o) +{ + QObjectContainer *that = static_cast<QObjectContainer*>(prop->object); + that->dataChildren.append(o); + QObject::connect(o, SIGNAL(destroyed(QObject*)), prop->object, SLOT(childDestroyed(QObject*))); + + if (that->gcOnAppend) { + QQmlEngine *engine = qmlEngine(that); + engine->collectGarbage(); + QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); + QCoreApplication::processEvents(); + } +} + +int QObjectContainer::children_count(QQmlListProperty<QObject> *prop) +{ + return static_cast<QObjectContainer*>(prop->object)->dataChildren.count(); +} + +QObject *QObjectContainer::children_at(QQmlListProperty<QObject> *prop, int index) +{ + return static_cast<QObjectContainer*>(prop->object)->dataChildren.at(index); +} + +void QObjectContainer::children_clear(QQmlListProperty<QObject> *prop) +{ + QObjectContainer *that = static_cast<QObjectContainer*>(prop->object); + foreach (QObject *c, that->dataChildren) + QObject::disconnect(c, SIGNAL(destroyed(QObject*)), that, SLOT(childDestroyed(QObject*))); + that->dataChildren.clear(); +} + +void QObjectContainer::childDestroyed(QObject *child) { + dataChildren.removeAll(child); +} + +void FloatingQObject::classBegin() +{ + setParent(0); +} + +void FloatingQObject::componentComplete() +{ + Q_ASSERT(!parent()); +} + void registerTypes() { qmlRegisterType<MyQmlObject>("Qt.test", 1,0, "MyQmlObjectAlias"); @@ -422,6 +478,10 @@ void registerTypes() qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi2",1,0,"Data",testImportOrder_api2); qmlRegisterSingletonType<SingletonWithEnum>("Qt.test.singletonWithEnum", 1, 0, "SingletonWithEnum", create_singletonWithEnum); + + qmlRegisterType<QObjectContainer>("Qt.test", 1, 0, "QObjectContainer"); + qmlRegisterType<QObjectContainerWithGCOnAppend>("Qt.test", 1, 0, "QObjectContainerWithGCOnAppend"); + qmlRegisterType<FloatingQObject>("Qt.test", 1, 0, "FloatingQObject"); } #include "testtypes.moc" diff --git a/tests/auto/qml/qqmlecmascript/testtypes.h b/tests/auto/qml/qqmlecmascript/testtypes.h index 928d594f62..d5a1220f23 100644 --- a/tests/auto/qml/qqmlecmascript/testtypes.h +++ b/tests/auto/qml/qqmlecmascript/testtypes.h @@ -1661,6 +1661,51 @@ public: }; }; +// Like QtObject, but with default property +class QObjectContainer : public QObject +{ + Q_OBJECT + Q_CLASSINFO("DefaultProperty", "data") + Q_PROPERTY(QQmlListProperty<QObject> data READ data DESIGNABLE false) +public: + QObjectContainer(); + + QQmlListProperty<QObject> data(); + + static void children_append(QQmlListProperty<QObject> *prop, QObject *o); + static int children_count(QQmlListProperty<QObject> *prop); + static QObject *children_at(QQmlListProperty<QObject> *prop, int index); + static void children_clear(QQmlListProperty<QObject> *prop); + + QList<QObject*> dataChildren; + QWidget *widgetParent; + bool gcOnAppend; + +protected slots: + void childDestroyed(QObject *child); +}; + +class QObjectContainerWithGCOnAppend : public QObjectContainer +{ + Q_OBJECT +public: + QObjectContainerWithGCOnAppend() + { + gcOnAppend = true; + } +}; + +class FloatingQObject : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_INTERFACES(QQmlParserStatus) +public: + FloatingQObject() {} + + virtual void classBegin(); + virtual void componentComplete(); +}; + void registerTypes(); #endif // TESTTYPES_H diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index d068584797..6b37163b40 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -324,6 +324,7 @@ private slots: void varPropertyAccessOnObjectWithInvalidContext(); void importedScriptsAccessOnObjectWithInvalidContext(); void contextObjectOnLazyBindings(); + void garbageCollectionDuringCreation(); private: // static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter); @@ -7637,6 +7638,33 @@ void tst_qqmlecmascript::contextObjectOnLazyBindings() QCOMPARE(subObject->property("testValue").toInt(), int(42)); } +void tst_qqmlecmascript::garbageCollectionDuringCreation() +{ + QQmlComponent component(&engine); + component.setData("import Qt.test 1.0\n" + "QObjectContainerWithGCOnAppend {\n" + " objectName: \"root\"\n" + " FloatingQObject {\n" + " objectName: \"parentLessChild\"\n" + " property var blah;\n" // Ensure we have JS wrapper + " }\n" + "}\n", + QUrl()); + + QScopedPointer<QObject> object(component.create()); + QVERIFY(!object.isNull()); + + QObjectContainer *container = qobject_cast<QObjectContainer*>(object.data()); + QCOMPARE(container->dataChildren.count(), 1); + + QObject *child = container->dataChildren.first(); + QQmlData *ddata = QQmlData::get(child); + QVERIFY(!ddata->jsWrapper.isNullOrUndefined()); + + gc(engine); + QCOMPARE(container->dataChildren.count(), 0); +} + QTEST_MAIN(tst_qqmlecmascript) #include "tst_qqmlecmascript.moc" diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml index 03be57909f..069b62a726 100644 --- a/tests/auto/qmltest/listview/tst_listview.qml +++ b/tests/auto/qmltest/listview/tst_listview.qml @@ -108,6 +108,33 @@ Item { property int createdDelegates: 0 } + ListView + { + id: listInteractiveCurrentIndexEnforce + width: 600 + height: 600 + + snapMode: ListView.SnapOneItem + orientation: ListView.Horizontal + interactive: !currentItem.moving + highlightRangeMode: ListView.StrictlyEnforceRange + + model: 4 + + focus: true + Keys.onPressed: if (event.key == Qt.Key_K) currentIndex = currentIndex + 1; + + delegate: Flickable { + width: 600 + height: 600 + contentWidth: 600 + contentHeight: 1200 + + MouseArea { anchors.fill: parent } + Rectangle { anchors.fill: parent; color: index == 0 ? "red" : index == 1 ? "green" : index == 2 ? "blue" : "white" } + } + } + Component { id: delegateModelAfterCreateComponent Rectangle { @@ -272,5 +299,19 @@ Item { listViewDelegateModelAfterCreate.model = 40; verify(listViewDelegateModelAfterCreate.createdDelegates > 0); } + + function test_listInteractiveCurrentIndexEnforce() { + mousePress(listInteractiveCurrentIndexEnforce, 10, 50); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 40); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 30); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 20); + mouseMove(listInteractiveCurrentIndexEnforce, 10, 10); + compare(listInteractiveCurrentIndexEnforce.interactive, false); + mouseRelease(listInteractiveCurrentIndexEnforce, 10, 10); + tryCompare(listInteractiveCurrentIndexEnforce, "interactive", true); + keyClick("k"); + compare(listInteractiveCurrentIndexEnforce.currentIndex, 1); + tryCompare(listInteractiveCurrentIndexEnforce, "contentX", listInteractiveCurrentIndexEnforce.width); + } } } |