aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-29 01:00:05 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-11-29 01:00:06 +0100
commit2a809ef65797e42eac608cdd69a63e37d63521ae (patch)
tree823d035b758e43d9befc50d26d24a8b738b14e6d
parentc8b731829948c620e207e82b5fe106034dff4ede (diff)
parentfcf7b513d9e5b04213fbe5254f10af0f694ea8aa (diff)
Merge remote-tracking branch 'origin/5.14' into 5.15
-rw-r--r--src/3rdparty/masm/assembler/LinkBuffer.h5
-rw-r--r--src/3rdparty/masm/disassembler/Disassembler.cpp2
-rw-r--r--src/qml/qml/qqmldata_p.h2
-rw-r--r--src/quick/items/qquickmultipointtoucharea.cpp48
-rw-r--r--src/quick/items/qquickmultipointtoucharea_p.h4
-rw-r--r--src/quick/items/qquicktableview.cpp35
-rw-r--r--src/quick/scenegraph/coreapi/qsgtexture.cpp3
-rw-r--r--tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp66
-rw-r--r--tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp1
9 files changed, 140 insertions, 26 deletions
diff --git a/src/3rdparty/masm/assembler/LinkBuffer.h b/src/3rdparty/masm/assembler/LinkBuffer.h
index 8e9a3d9c7a..632d1fdbc4 100644
--- a/src/3rdparty/masm/assembler/LinkBuffer.h
+++ b/src/3rdparty/masm/assembler/LinkBuffer.h
@@ -315,13 +315,12 @@ inline typename LinkBufferBase<MacroAssembler, ExecutableOffsetCalculator>::Code
va_start(argList, format);
WTF::dataLogFV(format, argList);
va_end(argList);
- dataLogF(":\n");
dataLogF(
#if OS(WINDOWS)
- " Code at [0x%p, 0x%p):\n",
+ ": Code at [0x%p, 0x%p):",
#else
- " Code at [%p, %p):\n",
+ ": Code at [%p, %p):",
#endif
result.code().executableAddress(), static_cast<char*>(result.code().executableAddress()) + result.size());
disassemble(result.code(), m_size, " ", WTF::dataFile());
diff --git a/src/3rdparty/masm/disassembler/Disassembler.cpp b/src/3rdparty/masm/disassembler/Disassembler.cpp
index 3fed2cdab8..50fe2e23d5 100644
--- a/src/3rdparty/masm/disassembler/Disassembler.cpp
+++ b/src/3rdparty/masm/disassembler/Disassembler.cpp
@@ -36,7 +36,7 @@ void disassemble(const MacroAssemblerCodePtr& codePtr, size_t size, const char*
if (tryToDisassemble(codePtr, size, prefix, out))
return;
- out.printf("%sdisassembly not available for range %p...%p\n", prefix, codePtr.executableAddress(), static_cast<char*>(codePtr.executableAddress()) + size);
+ out.printf("%sdisassembly not available for range %p...%p", prefix, codePtr.executableAddress(), static_cast<char*>(codePtr.executableAddress()) + size);
}
} // namespace JSC
diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h
index 299476f5c8..ee31cb38d9 100644
--- a/src/qml/qml/qqmldata_p.h
+++ b/src/qml/qml/qqmldata_p.h
@@ -335,7 +335,7 @@ bool QQmlData::wasDeleted(const QObject *object)
return true;
const QObjectPrivate *priv = QObjectPrivate::get(object);
- if (!priv || priv->wasDeleted)
+ if (!priv || priv->wasDeleted || priv->isDeletingChildren)
return true;
const QQmlData *ddata = QQmlData::get(object);
diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp
index b02e58fae4..9a371207ce 100644
--- a/src/quick/items/qquickmultipointtoucharea.cpp
+++ b/src/quick/items/qquickmultipointtoucharea.cpp
@@ -42,6 +42,7 @@
#include <private/qsgadaptationlayer_p.h>
#include <private/qevent_p.h>
#include <private/qquickitem_p.h>
+#include <private/qquickwindow_p.h>
#include <private/qguiapplication_p.h>
#include <QEvent>
#include <QMouseEvent>
@@ -448,6 +449,7 @@ QQuickMultiPointTouchArea::QQuickMultiPointTouchArea(QQuickItem *parent)
: QQuickItem(parent),
_minimumTouchPoints(0),
_maximumTouchPoints(INT_MAX),
+ _touchMouseDevice(nullptr),
_stealMouse(false),
_mouseEnabled(true)
{
@@ -586,10 +588,10 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
bool ended = false;
bool moved = false;
bool started = false;
- bool isMouseEvent = false;
clearTouchLists();
QList<QTouchEvent::TouchPoint> touchPoints;
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window());
switch (event->type()) {
case QEvent::TouchBegin:
@@ -598,6 +600,9 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
touchPoints = static_cast<QTouchEvent*>(event)->touchPoints();
break;
case QEvent::MouseButtonPress:
+ _mouseQpaTouchPoint = QTouchEvent::TouchPoint(windowPriv->touchMouseId);
+ _touchMouseDevice = windowPriv->touchMouseDevice->qTouchDevice();
+ Q_FALLTHROUGH();
case QEvent::MouseMove:
case QEvent::MouseButtonRelease: {
QMouseEvent *me = static_cast<QMouseEvent*>(event);
@@ -617,7 +622,6 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
_mouseQpaTouchPoint.setState(Qt::TouchPointPressed);
}
touchPoints << _mouseQpaTouchPoint;
- isMouseEvent = true;
break;
}
default:
@@ -625,11 +629,6 @@ void QQuickMultiPointTouchArea::updateTouchData(QEvent *event)
break;
}
- if (!isMouseEvent && _mouseTouchPoint) {
- QQuickWindow *c = window();
- if (c && c->mouseGrabberItem() == this)
- touchPoints << _mouseQpaTouchPoint;
- }
int numTouchPoints = touchPoints.count();
//always remove released touches, and make sure we handle all releases before adds.
for (const QTouchEvent::TouchPoint &p : qAsConst(touchPoints)) {
@@ -756,7 +755,7 @@ void QQuickMultiPointTouchArea::addTouchPoint(const QMouseEvent *e)
dtp = new QQuickTouchPoint(false);
updateTouchPoint(dtp, e);
dtp->setPressed(true);
- _touchPoints.insert(-1, dtp);
+ _touchPoints.insert(_touchMouseDevice && _mouseQpaTouchPoint.id() > 0 ? _mouseQpaTouchPoint.id() : -1, dtp);
_pressedTouchPoints.append(dtp);
_mouseTouchPoint = dtp;
}
@@ -839,8 +838,7 @@ void QQuickMultiPointTouchArea::mousePressEvent(QMouseEvent *event)
setKeepMouseGrab(false);
event->setAccepted(true);
_mousePos = event->localPos();
-
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
if (_touchPoints.count() >= _minimumTouchPoints - 1 && _touchPoints.count() < _maximumTouchPoints) {
@@ -855,7 +853,7 @@ void QQuickMultiPointTouchArea::mouseMoveEvent(QMouseEvent *event)
return;
}
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
_movedTouchPoints.clear();
@@ -870,7 +868,7 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
return;
}
- if (event->source() != Qt::MouseEventNotSynthesized)
+ if (event->source() != Qt::MouseEventNotSynthesized && event->source() != Qt::MouseEventSynthesizedByQt)
return;
if (_mouseTouchPoint) {
@@ -880,18 +878,16 @@ void QQuickMultiPointTouchArea::mouseReleaseEvent(QMouseEvent *event)
_mouseTouchPoint = nullptr;
}
- QQuickWindow *c = window();
- if (c && c->mouseGrabberItem() == this)
- ungrabMouse();
setKeepMouseGrab(false);
}
-void QQuickMultiPointTouchArea::ungrab()
+void QQuickMultiPointTouchArea::ungrab(bool normalRelease)
{
_stealMouse = false;
setKeepMouseGrab(false);
setKeepTouchGrab(false);
- ungrabTouchPoints();
+ if (!normalRelease)
+ ungrabTouchPoints();
if (_touchPoints.count()) {
for (QObject *obj : qAsConst(_touchPoints))
@@ -969,13 +965,25 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve
if (!isEnabled() || !isVisible())
return QQuickItem::childMouseEventFilter(receiver, event);
switch (event->type()) {
- case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonPress: {
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window());
+ // If we already got a chance to filter the touchpoint that generated this synth-mouse-press,
+ // and chose not to filter it, ignore it now, too.
+ if (static_cast<QMouseEvent *>(event)->source() == Qt::MouseEventSynthesizedByQt &&
+ _lastFilterableTouchPointIds.contains(windowPriv->touchMouseId))
+ return false;
+ } Q_FALLTHROUGH();
case QEvent::MouseMove:
case QEvent::MouseButtonRelease:
return sendMouseEvent(static_cast<QMouseEvent *>(event));
- break;
case QEvent::TouchBegin:
+ _lastFilterableTouchPointIds.clear();
+ Q_FALLTHROUGH();
case QEvent::TouchUpdate:
+ for (auto tp : static_cast<QTouchEvent*>(event)->touchPoints()) {
+ if (tp.state() == Qt::TouchPointPressed)
+ _lastFilterableTouchPointIds << tp.id();
+ }
if (!shouldFilter(event))
return false;
updateTouchData(event);
@@ -984,7 +992,7 @@ bool QQuickMultiPointTouchArea::childMouseEventFilter(QQuickItem *receiver, QEve
if (!shouldFilter(event))
return false;
updateTouchData(event);
- ungrab();
+ ungrab(true);
}
break;
default:
diff --git a/src/quick/items/qquickmultipointtoucharea_p.h b/src/quick/items/qquickmultipointtoucharea_p.h
index 7506be10a1..42b42a45c5 100644
--- a/src/quick/items/qquickmultipointtoucharea_p.h
+++ b/src/quick/items/qquickmultipointtoucharea_p.h
@@ -289,7 +289,7 @@ protected:
#endif
private:
- void ungrab();
+ void ungrab(bool normalRelease = false);
QMap<int,QQuickTouchPoint*> _touchPrototypes; //TouchPoints defined in QML
QMap<int,QObject*> _touchPoints; //All current touch points
QList<QObject*> _releasedTouchPoints;
@@ -297,8 +297,10 @@ private:
QList<QObject*> _movedTouchPoints;
int _minimumTouchPoints;
int _maximumTouchPoints;
+ QVector<int> _lastFilterableTouchPointIds;
QPointer<QQuickTouchPoint> _mouseTouchPoint; // exists when mouse button is down and _mouseEnabled is true; null otherwise
QTouchEvent::TouchPoint _mouseQpaTouchPoint; // synthetic QPA touch point to hold state and position of the mouse
+ const QTouchDevice *_touchMouseDevice;
QPointF _mousePos;
bool _stealMouse;
bool _mouseEnabled;
diff --git a/src/quick/items/qquicktableview.cpp b/src/quick/items/qquicktableview.cpp
index 5550ed0a78..ec2fe75d9b 100644
--- a/src/quick/items/qquicktableview.cpp
+++ b/src/quick/items/qquicktableview.cpp
@@ -2711,6 +2711,23 @@ void QQuickTableView::setContentHeight(qreal height)
QQuickFlickable::setContentHeight(height);
}
+/*!
+ \qmlproperty TableView QtQuick::TableView::syncView
+
+ If this property of a TableView is set to another TableView, both the
+ tables will synchronize with regard to flicking, column widths/row heights,
+ and spacing according to \l syncDirection.
+
+ If \l syncDirection contains \l Qt.Horizontal, current tableView's column
+ widths, column spacing, and horizontal flicking movement synchronizes with
+ syncView's.
+
+ If \l syncDirection contains \l Qt.Vertical, current tableView's row
+ heights, row spacing, and vertical flicking movement synchronizes with
+ syncView's.
+
+ \sa syncDirection
+*/
QQuickTableView *QQuickTableView::syncView() const
{
return d_func()->assignedSyncView;
@@ -2728,6 +2745,24 @@ void QQuickTableView::setSyncView(QQuickTableView *view)
emit syncViewChanged();
}
+/*!
+ \qmlproperty Qt::Orientations QtQuick::TableView::syncDirection
+
+ If the \l syncView is set on a TableView, this property controls
+ synchronization of flicking direction(s) for both tables. The default is \c
+ {Qt.Horizontal | Qt.Vertical}, which means that if you flick either table
+ in either direction, the other table is flicked the same amount in the
+ same direction.
+
+ This property and \l syncView can be used to make two tableViews
+ synchronize with each other smoothly in flicking regardless of the different
+ overshoot/undershoot, velocity, acceleration/deceleration or rebound
+ animation, and so on.
+
+ A typical use case is to make several headers flick along with the table.
+
+ \sa syncView, headerView
+*/
Qt::Orientations QQuickTableView::syncDirection() const
{
return d_func()->assignedSyncDirection;
diff --git a/src/quick/scenegraph/coreapi/qsgtexture.cpp b/src/quick/scenegraph/coreapi/qsgtexture.cpp
index dfbe4d3ffd..58b42e4094 100644
--- a/src/quick/scenegraph/coreapi/qsgtexture.cpp
+++ b/src/quick/scenegraph/coreapi/qsgtexture.cpp
@@ -395,6 +395,9 @@ QSGTexture::~QSGTexture()
Binding a texture may also include uploading the texture data from
a previously set QImage.
+ \warning This function should only be called when running with the
+ direct OpenGL rendering path.
+
\warning This function can only be called from the rendering thread.
*/
diff --git a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
index e96b892b54..c18a220996 100644
--- a/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
+++ b/tests/auto/quick/qquickmultipointtoucharea/tst_qquickmultipointtoucharea.cpp
@@ -31,12 +31,15 @@
#include <private/qquickmultipointtoucharea_p.h>
#include <private/qquickflickable_p.h>
#include <private/qquickmousearea_p.h>
+#include <private/qquickwindow_p.h>
#include <qpa/qwindowsysteminterface.h>
#include <QtQuick/qquickview.h>
#include <QtGui/QScreen>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
+Q_LOGGING_CATEGORY(lcTests, "qt.quick.tests")
+
class tst_QQuickMultiPointTouchArea : public QQmlDataTest
{
Q_OBJECT
@@ -62,6 +65,7 @@ private slots:
void nested();
void inFlickable();
void inFlickable2();
+ void inFlickableWithPressDelay();
void inMouseArea();
void mouseAsTouchpoint();
void invisible();
@@ -812,6 +816,68 @@ void tst_QQuickMultiPointTouchArea::inFlickable2()
QTRY_VERIFY(!flickable->isMoving());
}
+void tst_QQuickMultiPointTouchArea::inFlickableWithPressDelay() // QTBUG-78818
+{
+ const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QScopedPointer<QQuickView> window(createAndShowView("inFlickable.qml"));
+ QVERIFY(window->rootObject() != nullptr);
+ QQuickWindowPrivate *windowPriv = QQuickWindowPrivate::get(window.data());
+
+ QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(window->rootObject());
+ QVERIFY(flickable != nullptr);
+ flickable->setPressDelay(50);
+
+ QQuickMultiPointTouchArea *mpta = window->rootObject()->findChild<QQuickMultiPointTouchArea*>();
+ QVERIFY(mpta != nullptr);
+ mpta->setMinimumTouchPoints(1);
+ QQuickTouchPoint *point11 = window->rootObject()->findChild<QQuickTouchPoint*>("point1");
+ QPoint p1(20,100);
+
+ // press: Flickable prevents delivery of TouchBegin, but sends mouse press instead, after the delay.
+ // MPTA handles the mouse press, and its first declared touchpoint is pressed.
+ QTest::touchEvent(window.data(), device).press(0, p1);
+ QQuickTouchUtils::flush(window.data());
+ QTRY_COMPARE(point11->pressed(), true);
+ auto pointerEvent = windowPriv->pointerEventInstance(QQuickPointerDevice::touchDevices().at(0));
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
+
+ // release: MPTA receives TouchEnd (which is asymmetric with mouse press); does NOT emit canceled.
+ QTest::touchEvent(window.data(), device).release(0, p1);
+ QQuickTouchUtils::flush(window.data());
+ QCOMPARE(flickable->property("cancelCount").toInt(), 0);
+
+ // press again
+ QTest::touchEvent(window.data(), device).press(0, p1);
+ QQuickTouchUtils::flush(window.data());
+ QTRY_COMPARE(point11->pressed(), true); // wait until pressDelay exceeded
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), mpta);
+
+ // drag past the threshold: Flickable takes over the grab, MPTA gets touchUngrab and is no longer pressed
+ int i = 0;
+ for (; i < 10 && window->mouseGrabberItem() != flickable; ++i) {
+ p1 += QPoint(0,dragThreshold);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
+ }
+ QCOMPARE(window->mouseGrabberItem(), flickable);
+ qCDebug(lcTests, "Flickable stole grab from MPTA after %d moves", i);
+ QCOMPARE(pointerEvent->point(0)->exclusiveGrabber(), flickable);
+ QCOMPARE(point11->pressed(), false);
+ QVERIFY(flickable->property("cancelCount").toInt() > 0); // actually 2 because 2 touchPoints are declared... but only one was really cancelled
+
+ // drag a little more and the Flickable moves
+ p1 += QPoint(0,1);
+ QTest::touchEvent(window.data(), device).move(0, p1);
+ QQuickTouchUtils::flush(window.data());
+ QVERIFY(flickable->contentY() < 0);
+ QVERIFY(flickable->isMoving());
+
+ QTest::touchEvent(window.data(), device).release(0, p1);
+ QQuickTouchUtils::flush(window.data());
+
+ QTRY_VERIFY(!flickable->isMoving());
+}
+
// QTBUG-31047
void tst_QQuickMultiPointTouchArea::inMouseArea()
{
diff --git a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
index 465e2a7d54..86945e71a4 100644
--- a/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
+++ b/tests/manual/scenegraph_lancelot/scenegraph/tst_scenegraph.cpp
@@ -212,6 +212,7 @@ bool tst_Scenegraph::renderAndGrab(const QString& qmlFile, const QStringList& ex
{
bool usePipe = true; // Whether to transport the grabbed image using temp. file or pipe. TBD: cmdline option
QProcess grabber;
+ grabber.setProcessChannelMode(QProcess::ForwardedErrorChannel);
QStringList args = extraArgs;
QString tmpfile = usePipe ? QString("-") : QString("/tmp/qmlscenegrabber-%1-out.ppm").arg(QCoreApplication::applicationPid());
args << qmlFile << "-o" << tmpfile;