summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/jsruntime/qv4internalclass_p.h2
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp1
-rw-r--r--src/qml/types/qqmlmodelsmodule.cpp2
-rw-r--r--src/quick/handlers/qquickdraghandler.cpp7
-rw-r--r--src/quick/items/qquickwindow.cpp4
-rw-r--r--src/quick/scenegraph/qsgdefaultcontext.cpp10
-rw-r--r--tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp17
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragMargin.qml36
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp33
-rw-r--r--tests/auto/quick/qquicklistview/data/delegateWithMouseArea.qml29
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp34
11 files changed, 163 insertions, 12 deletions
diff --git a/src/qml/jsruntime/qv4internalclass_p.h b/src/qml/jsruntime/qv4internalclass_p.h
index 42b61218a5..7bb10f47a3 100644
--- a/src/qml/jsruntime/qv4internalclass_p.h
+++ b/src/qml/jsruntime/qv4internalclass_p.h
@@ -457,7 +457,7 @@ private:
InternalClass *addMemberImpl(PropertyKey identifier, PropertyAttributes data, InternalClassEntry *entry);
void removeChildEntry(InternalClass *child);
- friend struct ExecutionEngine;
+ friend struct ::QV4::ExecutionEngine;
};
inline
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index 3e9e972d77..f7c339dc26 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -1990,6 +1990,7 @@ ReturnedValue Runtime::method_div(const Value &left, const Value &right)
int lval = left.integerValue();
int rval = right.integerValue();
if (rval != 0 // division by zero should result in a NaN
+ && !(lval == std::numeric_limits<int>::min() && rval == -1) // doesn't fit in int
&& (lval % rval == 0) // fractions can't be stored in an int
&& !(lval == 0 && rval < 0)) // 0 / -something results in -0.0
return Encode(int(lval / rval));
diff --git a/src/qml/types/qqmlmodelsmodule.cpp b/src/qml/types/qqmlmodelsmodule.cpp
index 30915d96fd..bb72771cd9 100644
--- a/src/qml/types/qqmlmodelsmodule.cpp
+++ b/src/qml/types/qqmlmodelsmodule.cpp
@@ -72,9 +72,11 @@ void QQmlModelsModule::defineLabsModule()
{
const char uri[] = "Qt.labs.qmlmodels";
+#if QT_CONFIG(qml_delegate_model)
qmlRegisterUncreatableType<QQmlAbstractDelegateComponent>(uri, 1, 0, "AbstractDelegateComponent", QQmlAbstractDelegateComponent::tr("Cannot create instance of abstract class AbstractDelegateComponent."));
qmlRegisterType<QQmlDelegateChooser>(uri, 1, 0, "DelegateChooser");
qmlRegisterType<QQmlDelegateChoice>(uri, 1, 0, "DelegateChoice");
+#endif
}
QT_END_NAMESPACE
diff --git a/src/quick/handlers/qquickdraghandler.cpp b/src/quick/handlers/qquickdraghandler.cpp
index 48f0599284..e5531369cf 100644
--- a/src/quick/handlers/qquickdraghandler.cpp
+++ b/src/quick/handlers/qquickdraghandler.cpp
@@ -112,14 +112,13 @@ QPointF QQuickDragHandler::targetCentroidPosition()
void QQuickDragHandler::onGrabChanged(QQuickPointerHandler *grabber, QQuickEventPoint::GrabTransition transition, QQuickEventPoint *point)
{
QQuickMultiPointHandler::onGrabChanged(grabber, transition, point);
- if (grabber == this && transition == QQuickEventPoint::GrabExclusive) {
+ if (grabber == this && transition == QQuickEventPoint::GrabExclusive && target()) {
// In case the grab got handed over from another grabber, we might not get the Press.
if (!m_pressedInsideTarget) {
- if (target())
+ if (target() != parentItem())
m_pressTargetPos = QPointF(target()->width(), target()->height()) / 2;
} else if (m_pressTargetPos.isNull()) {
- if (target())
- m_pressTargetPos = targetCentroidPosition();
+ m_pressTargetPos = targetCentroidPosition();
}
}
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index d448d74b99..88d419e2b3 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2025,8 +2025,8 @@ bool QQuickWindowPrivate::deliverTouchCancelEvent(QTouchEvent *event)
qCDebug(DBG_TOUCH) << event;
Q_Q(QQuickWindow);
- if (q->mouseGrabberItem())
- q->mouseGrabberItem()->ungrabMouse();
+ if (QQuickItem *grabber = q->mouseGrabberItem())
+ sendUngrabEvent(grabber, true);
cancelTouchMouseSynthesis();
// A TouchCancel event will typically not contain any points.
diff --git a/src/quick/scenegraph/qsgdefaultcontext.cpp b/src/quick/scenegraph/qsgdefaultcontext.cpp
index af0589e5d3..70b74b8877 100644
--- a/src/quick/scenegraph/qsgdefaultcontext.cpp
+++ b/src/quick/scenegraph/qsgdefaultcontext.cpp
@@ -62,6 +62,8 @@
#include <private/qqmlglobal_p.h>
+#include <algorithm>
+
QT_BEGIN_NAMESPACE
namespace QSGMultisampleAntialiasing {
@@ -158,11 +160,9 @@ void QSGDefaultContext::renderContextInitialized(QSGRenderContext *renderContext
qCDebug(QSG_LOG_INFO, "GL_RENDERER: %s",
(const char*)funcs->glGetString(GL_RENDERER));
qCDebug(QSG_LOG_INFO, "GL_VERSION: %s", (const char*)funcs->glGetString(GL_VERSION));
- QSet<QByteArray> exts = openglRenderContext->openglContext()->extensions();
- QByteArray all;
- for (const QByteArray &e : qAsConst(exts))
- all += ' ' + e;
- qCDebug(QSG_LOG_INFO, "GL_EXTENSIONS: %s", all.constData());
+ QByteArrayList exts = openglRenderContext->openglContext()->extensions().toList();
+ std::sort(exts.begin(), exts.end());
+ qCDebug(QSG_LOG_INFO, "GL_EXTENSIONS: %s", exts.join(' ').constData());
qCDebug(QSG_LOG_INFO, "Max Texture Size: %d", openglRenderContext->maxTextureSize());
qCDebug(QSG_LOG_INFO, "Debug context: %s",
format.testOption(QSurfaceFormat::DebugContext) ? "true" : "false");
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
index 3cd70a0d1b..90ff6f24fa 100644
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
@@ -366,6 +366,7 @@ private slots:
void tailCallWithArguments();
void deleteSparseInIteration();
void saveAccumulatorBeforeToInt32();
+ void intMinDividedByMinusOne();
private:
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
@@ -8948,6 +8949,22 @@ void tst_qqmlecmascript::saveAccumulatorBeforeToInt32()
QCOMPARE(value.toString(), QLatin1String("RangeError: Maximum call stack size exceeded."));
}
+void tst_qqmlecmascript::intMinDividedByMinusOne()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData(QByteArray("import QtQml 2.2\n"
+ "QtObject {\n"
+ " property int intMin: -2147483648\n"
+ " property int minusOne: -1\n"
+ " property double doesNotFitInInt: intMin / minusOne\n"
+ "}"), QUrl());
+ QVERIFY(component.isReady());
+ QScopedPointer<QObject> object(component.create());
+ QVERIFY(!object.isNull());
+ QCOMPARE(object->property("doesNotFitInInt").toUInt(), 2147483648u);
+}
+
QTEST_MAIN(tst_qqmlecmascript)
#include "tst_qqmlecmascript.moc"
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragMargin.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragMargin.qml
new file mode 100644
index 0000000000..e5ca681bd5
--- /dev/null
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/dragMargin.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.12
+
+Rectangle {
+ color: "#333"
+ width: 480; height: 480
+
+ Rectangle {
+ color: "#112"
+ width: 100
+ height: 100
+ x: 50; y: 50
+
+ DragHandler {
+ id: dragHandler
+ margin: 20
+ }
+
+ Rectangle {
+ id: rect
+ anchors.fill: parent
+ anchors.margins: -dragHandler.margin
+ color: "transparent"
+ border.color: "cyan"
+ border.width: 2
+ radius: 10
+ antialiasing: true
+
+ Text {
+ color: "cyan"
+ text: "drag this margin area"
+ font.pixelSize: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index eb210c2112..cc8c567e5c 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -55,6 +55,7 @@ private slots:
void defaultPropertyValues();
void touchDrag();
void mouseDrag();
+ void dragFromMargin();
void touchDragMulti();
void touchDragMultiSliders_data();
void touchDragMultiSliders();
@@ -251,6 +252,38 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(centroidChangedSpy.count(), 5);
}
+void tst_DragHandler::dragFromMargin() // QTBUG-74966
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "dragMargin.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *draggableItem = window->rootObject()->childItems().first();
+ QVERIFY(draggableItem);
+ QQuickDragHandler *dragHandler = draggableItem->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+
+ QPointF originalPos = draggableItem->position();
+ QPointF scenePressPos = originalPos - QPointF(10, 0);
+ QPoint p1 = scenePressPos.toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ p1 += QPoint(dragThreshold * 2, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), p1);
+ QCOMPARE(dragHandler->translation().x(), 0.0); // hmm that's odd
+ QCOMPARE(dragHandler->translation().y(), 0.0);
+ QCOMPARE(draggableItem->position(), originalPos + QPointF(dragThreshold * 2, 0));
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
+}
+
void tst_DragHandler::touchDragMulti()
{
const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
diff --git a/tests/auto/quick/qquicklistview/data/delegateWithMouseArea.qml b/tests/auto/quick/qquicklistview/data/delegateWithMouseArea.qml
new file mode 100644
index 0000000000..e0b8222bfb
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/delegateWithMouseArea.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.12
+
+ListView {
+ id: root
+ objectName: "view"
+ width: 600
+ height: 600
+ model: 3
+ snapMode: ListView.SnapOneItem
+ boundsBehavior: Flickable.StopAtBounds
+ highlightRangeMode: ListView.StrictlyEnforceRange
+ preferredHighlightBegin: 0
+ preferredHighlightEnd: 0
+ highlightMoveDuration: 100
+ delegate: Rectangle {
+ id: delegateRect
+ width: 500
+ height: 500
+ color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
+ Text {
+ text: index
+ font.pixelSize: 128
+ anchors.centerIn: parent
+ }
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index d96590bdae..2ea8a477a8 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -38,6 +38,7 @@
#include <QtQml/qqmlincubator.h>
#include <QtQuick/private/qquickitemview_p_p.h>
#include <QtQuick/private/qquicklistview_p.h>
+#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQml/private/qqmlobjectmodel_p.h>
#include <QtQml/private/qqmllistmodel_p.h>
@@ -275,6 +276,7 @@ private slots:
void addOnCompleted();
void setPositionOnLayout();
+ void touchCancel();
private:
template <class T> void items(const QUrl &source);
@@ -330,6 +332,7 @@ private:
QQuickView *m_view;
QString testForView;
+ QTouchDevice *touchDevice = QTest::createTouchDevice();
};
class TestObject : public QObject
@@ -8968,6 +8971,37 @@ void tst_QQuickListView::useDelegateChooserWithoutDefault()
window->show();
};
+void tst_QQuickListView::touchCancel() // QTBUG-74679
+{
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegateWithMouseArea.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject());
+ QVERIFY(listview);
+ QQuickMouseArea *mouseArea = listview->currentItem()->findChild<QQuickMouseArea *>();
+ QVERIFY(mouseArea);
+
+ QPoint p1(300, 300);
+ QTest::touchEvent(window.data(), touchDevice).press(0, p1, window.data());
+ QQuickTouchUtils::flush(window.data());
+ QTRY_VERIFY(mouseArea->pressed());
+ // and because Flickable filtered it, QQuickFlickablePrivate::pressed
+ // should be true, but it's not easily tested here
+
+ QTouchEvent cancelEvent(QEvent::TouchCancel);
+ cancelEvent.setDevice(touchDevice);
+ QCoreApplication::sendEvent(window.data(), &cancelEvent);
+ // now QQuickWindowPrivate::sendUngrabEvent() will be called, Flickable will filter it,
+ // QQuickFlickablePrivate::pressed will be set to false, and that will allow setCurrentIndex() to make it move
+ QQuickTouchUtils::flush(window.data());
+
+ listview->setCurrentIndex(1);
+ // ensure that it actually moves (animates) to the second delegate
+ QTRY_COMPARE(listview->contentY(), 500.0);
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"