aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-01 01:00:14 +0100
committerQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2018-11-01 01:00:14 +0100
commit1a0b06bca7e6e23aede9dc624c7e4037cf486105 (patch)
tree199ea84d1c3410ef29414774dab1f07f099af6a3
parent3ed8744d24032fdaa9c84f32f918a3027cb0420f (diff)
parent2609429d7afc263ab8e44864b0f42f1c8356eda8 (diff)
Merge remote-tracking branch 'origin/5.12' into dev
-rw-r--r--src/imports/layouts/qquicklayout.cpp12
-rw-r--r--src/imports/settings/qqmlsettings.cpp22
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc2
-rw-r--r--src/qml/jsruntime/qv4promiseobject_p.h11
-rw-r--r--src/qml/qml/qqmlcomponent.cpp18
-rw-r--r--src/quick/accessible/qaccessiblequickitem.cpp10
-rw-r--r--src/quick/items/qquickevents_p_p.h2
-rw-r--r--src/quick/items/qquickflickable_p.h9
-rw-r--r--src/quick/items/qquicktext_p.h6
-rw-r--r--src/quick/items/qquickwindow.cpp8
-rw-r--r--src/quick/scenegraph/qsgbasicinternalimagenode.cpp3
-rw-r--r--src/quick/util/qquickstategroup.cpp5
-rw-r--r--tests/auto/qml/qqmlincubator/data/garbageCollection.qml19
-rw-r--r--tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp30
-rw-r--r--tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp34
-rw-r--r--tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp70
-rw-r--r--tests/auto/quick/qquickmousearea/data/nestedSendEvent.qml49
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp33
-rw-r--r--tests/auto/quick/qquickstates/data/duplicateStateName.qml13
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp12
-rw-r--r--tools/qmlplugindump/main.cpp25
21 files changed, 340 insertions, 53 deletions
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp
index cc206bcb95..d90eae5f80 100644
--- a/src/imports/layouts/qquicklayout.cpp
+++ b/src/imports/layouts/qquicklayout.cpp
@@ -74,10 +74,14 @@
false, the item's size will be fixed to its preferred size. Otherwise, it will grow or shrink
between its minimum and maximum size as the layout is resized.
- \note It is not recommended to have bindings to the x, y, width, or height properties of items
- in a layout, since this would conflict with the goals of Layout, and can also cause binding
- loops.
-
+ \note Do not bind to the x, y, width, or height properties of items in a layout,
+ as this would conflict with the goals of Layout, and can also cause binding loops.
+ The width and height properties are used by the layout engine to store the current
+ size of items as calculated from the minimum/preferred/maximum attached properties,
+ and can be ovewritten each time the items are laid out. Use
+ \l {Layout::preferredWidth}{Layout.preferredWidth} and
+ \l {Layout::preferredHeight}{Layout.preferredHeight}, or \l {Item::}{implicitWidth}
+ and \l {Item::}{implicitHeight} to specify the preferred size of items.
\sa GridLayout
\sa RowLayout
diff --git a/src/imports/settings/qqmlsettings.cpp b/src/imports/settings/qqmlsettings.cpp
index 6b3904909a..310ef62d9f 100644
--- a/src/imports/settings/qqmlsettings.cpp
+++ b/src/imports/settings/qqmlsettings.cpp
@@ -39,10 +39,12 @@
#include "qqmlsettings_p.h"
#include <qcoreevent.h>
+#include <qcoreapplication.h>
#include <qloggingcategory.h>
#include <qsettings.h>
#include <qpointer.h>
#include <qjsvalue.h>
+#include <qqmlinfo.h>
#include <qdebug.h>
#include <qhash.h>
@@ -271,6 +273,26 @@ QSettings *QQmlSettingsPrivate::instance() const
if (!settings) {
QQmlSettings *q = const_cast<QQmlSettings*>(q_func());
settings = fileName.isEmpty() ? new QSettings(q) : new QSettings(fileName, QSettings::IniFormat, q);
+ if (settings->status() != QSettings::NoError) {
+ // TODO: can't print out the enum due to the following error:
+ // error: C2666: 'QQmlInfo::operator <<': 15 overloads have similar conversions
+ qmlWarning(q) << "Failed to initialize QSettings instance. Status code is: " << int(settings->status());
+
+ if (settings->status() == QSettings::AccessError) {
+ QVector<QString> missingIdentifiers;
+ if (QCoreApplication::organizationName().isEmpty())
+ missingIdentifiers.append(QLatin1String("organizationName"));
+ if (QCoreApplication::organizationDomain().isEmpty())
+ missingIdentifiers.append(QLatin1String("organizationDomain"));
+ if (QCoreApplication::applicationName().isEmpty())
+ missingIdentifiers.append(QLatin1String("applicationName"));
+
+ if (!missingIdentifiers.isEmpty())
+ qmlWarning(q) << "The following application identifiers have not been set: " << missingIdentifiers;
+ }
+ return settings;
+ }
+
if (!category.isEmpty())
settings->beginGroup(category);
if (initialized)
diff --git a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
index 31650db7c0..2bb1fcac61 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc
@@ -462,6 +462,8 @@ Unlike an ordinary property, an alias has the following restrictions:
\li The \e {alias reference} is not optional,
unlike the optional default value for an ordinary property; the alias reference
must be provided when the alias is first declared.
+\li It cannot refer to \l {Attached Properties and Attached Signal Handlers}
+ {attached properties}.
\li It cannot refer to grouped properties; the following code will not work:
\code
property alias color: rectangle.border.color
diff --git a/src/qml/jsruntime/qv4promiseobject_p.h b/src/qml/jsruntime/qv4promiseobject_p.h
index 80f7183074..bce59b19a7 100644
--- a/src/qml/jsruntime/qv4promiseobject_p.h
+++ b/src/qml/jsruntime/qv4promiseobject_p.h
@@ -39,6 +39,17 @@
#ifndef QV4PROMISEOBJECT_H
#define QV4PROMISEOBJECT_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
#include "qv4object_p.h"
#include "qv4functionobject_p.h"
diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp
index a67c5c4a2b..5ed3cc5d6a 100644
--- a/src/qml/qml/qqmlcomponent.cpp
+++ b/src/qml/qml/qqmlcomponent.cpp
@@ -1132,22 +1132,23 @@ class QQmlComponentIncubator : public QQmlIncubator
public:
QQmlComponentIncubator(QV4::Heap::QmlIncubatorObject *inc, IncubationMode mode)
: QQmlIncubator(mode)
- , incubatorObject(inc)
- {}
+ {
+ incubatorObject.set(inc->internalClass->engine, inc);
+ }
void statusChanged(Status s) override {
- QV4::Scope scope(incubatorObject->internalClass->engine);
- QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject);
+ QV4::Scope scope(incubatorObject.engine());
+ QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject.as<QV4::QmlIncubatorObject>());
i->statusChanged(s);
}
void setInitialState(QObject *o) override {
- QV4::Scope scope(incubatorObject->internalClass->engine);
- QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject);
+ QV4::Scope scope(incubatorObject.engine());
+ QV4::Scoped<QV4::QmlIncubatorObject> i(scope, incubatorObject.as<QV4::QmlIncubatorObject>());
i->setInitialState(o);
}
- QV4::Heap::QmlIncubatorObject *incubatorObject;
+ QV4::PersistentValue incubatorObject; // keep a strong internal reference while incubating
};
@@ -1571,6 +1572,9 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s)
QQmlEnginePrivate::warning(QQmlEnginePrivate::get(scope.engine->qmlEngine()), error);
}
}
+
+ if (s != QQmlIncubator::Loading)
+ d()->incubator->incubatorObject.clear();
}
#undef INITIALPROPERTIES_SOURCE
diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp
index 87e581384b..98e7663c96 100644
--- a/src/quick/accessible/qaccessiblequickitem.cpp
+++ b/src/quick/accessible/qaccessiblequickitem.cpp
@@ -205,14 +205,16 @@ QAccessible::Role QAccessibleQuickItem::role() const
// Workaround for setAccessibleRole() not working for
// Text items. Text items are special since they are defined
// entirely from C++ (setting the role from QML works.)
- if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
- return QAccessible::StaticText;
QAccessible::Role role = QAccessible::NoRole;
if (item())
role = QQuickItemPrivate::get(item())->accessibleRole();
- if (role == QAccessible::NoRole)
- role = QAccessible::Client;
+ if (role == QAccessible::NoRole) {
+ if (qobject_cast<QQuickText*>(const_cast<QQuickItem *>(item())))
+ role = QAccessible::StaticText;
+ else
+ role = QAccessible::Client;
+ }
return role;
}
diff --git a/src/quick/items/qquickevents_p_p.h b/src/quick/items/qquickevents_p_p.h
index f3ce04d11e..d1a8bbd901 100644
--- a/src/quick/items/qquickevents_p_p.h
+++ b/src/quick/items/qquickevents_p_p.h
@@ -450,6 +450,8 @@ protected:
Qt::MouseButton m_button = Qt::NoButton;
Qt::MouseButtons m_pressedButtons;
+ friend class QQuickWindowPrivate;
+
Q_DISABLE_COPY(QQuickPointerEvent)
};
diff --git a/src/quick/items/qquickflickable_p.h b/src/quick/items/qquickflickable_p.h
index 57cc2533a0..7e9b18e101 100644
--- a/src/quick/items/qquickflickable_p.h
+++ b/src/quick/items/qquickflickable_p.h
@@ -267,10 +267,11 @@ Q_SIGNALS:
Q_REVISION(9) void horizontalOvershootChanged();
Q_REVISION(9) void verticalOvershootChanged();
- Q_REVISION(12) void atXEndChanged();
- Q_REVISION(12) void atYEndChanged();
- Q_REVISION(12) void atXBeginningChanged();
- Q_REVISION(12) void atYBeginningChanged();
+ // The next four signals should be marked as Q_REVISION(12). See QTBUG-71243
+ void atXEndChanged();
+ void atYEndChanged();
+ void atXBeginningChanged();
+ void atYBeginningChanged();
protected:
bool childMouseEventFilter(QQuickItem *, QEvent *) override;
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index f4e7fa7046..1af60051fb 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -272,8 +272,10 @@ Q_SIGNALS:
void textFormatChanged(QQuickText::TextFormat textFormat);
void elideModeChanged(QQuickText::TextElideMode mode);
void contentSizeChanged();
- Q_REVISION(12) void contentWidthChanged(qreal contentWidth);
- Q_REVISION(12) void contentHeightChanged(qreal contentHeight);
+ // The next two signals should be marked as Q_REVISION(12). See QTBUG-71247
+ void contentWidthChanged(qreal contentWidth);
+ void contentHeightChanged(qreal contentHeight);
+
void lineHeightChanged(qreal lineHeight);
void lineHeightModeChanged(LineHeightMode mode);
void fontSizeModeChanged();
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index d27ee54c89..4f14eedd39 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -2548,6 +2548,10 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
}
for (QQuickItem *item : targetItems) {
+ if (!event->m_event) {
+ qWarning("event went missing during delivery! (nested sendEvent() is not allowed)");
+ break;
+ }
hasFiltered.clear();
if (!handlersOnly && sendFilteredPointerEvent(event, item)) {
if (event->isAccepted()) {
@@ -2562,6 +2566,10 @@ bool QQuickWindowPrivate::deliverPressOrReleaseEvent(QQuickPointerEvent *event,
// nor to any item which already had a chance to filter.
if (skipDelivery.contains(item))
continue;
+ if (!event->m_event) {
+ qWarning("event went missing during delivery! (nested sendEvent() is not allowed)");
+ break;
+ }
deliverMatchingPointsToItem(item, event, handlersOnly);
if (event->allPointsAccepted())
handlersOnly = true;
diff --git a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp
index 53271af9ab..03b48b4b8a 100644
--- a/src/quick/scenegraph/qsgbasicinternalimagenode.cpp
+++ b/src/quick/scenegraph/qsgbasicinternalimagenode.cpp
@@ -230,6 +230,9 @@ QSGGeometry *QSGBasicInternalImageNode::updateGeometry(const QRectF &targetRect,
++vCells;
if (innerTargetRect.bottom() != targetRect.bottom())
++vCells;
+ if (hCells * vCells * 4 >= 0x10000)
+ qWarning("QTBUG-58924 - Too many tiles in QSGInternalImageNode, rendering will be partially missing.");
+
QVarLengthArray<X, 32> xData(2 * hCells);
QVarLengthArray<Y, 32> yData(2 * vCells);
X *xs = xData.data();
diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp
index 3d8c5e0507..d8daec2f07 100644
--- a/src/quick/util/qquickstategroup.cpp
+++ b/src/quick/util/qquickstategroup.cpp
@@ -302,7 +302,8 @@ void QQuickStateGroup::componentComplete()
Q_D(QQuickStateGroup);
d->componentComplete = true;
- QSet<QString> names;
+ QVarLengthArray<QString, 4> names;
+ names.reserve(d->states.count());
for (int ii = 0; ii < d->states.count(); ++ii) {
QQuickState *state = d->states.at(ii);
if (!state->isNamed())
@@ -312,7 +313,7 @@ void QQuickStateGroup::componentComplete()
if (names.contains(stateName)) {
qmlWarning(state->parent()) << "Found duplicate state name: " << stateName;
} else {
- names << stateName;
+ names.append(std::move(stateName));
}
}
diff --git a/tests/auto/qml/qqmlincubator/data/garbageCollection.qml b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml
new file mode 100644
index 0000000000..6866a02a00
--- /dev/null
+++ b/tests/auto/qml/qqmlincubator/data/garbageCollection.qml
@@ -0,0 +1,19 @@
+import QtQuick 2.0
+
+QtObject {
+ id: root
+
+ property var incubator
+
+ function getAndClearIncubator() {
+ var result = incubator
+ incubator = null
+ return result
+ }
+
+ Component.onCompleted: {
+ var c = Qt.createComponent("statusChanged.qml"); // use existing simple type for convenience
+ var incubator = c.incubateObject(root);
+ incubator.onStatusChanged = function(status) { if (status === 1) root.incubator = incubator }
+ }
+}
diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
index 8f0e04e12e..8e25079703 100644
--- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
+++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp
@@ -39,6 +39,7 @@
#include <QQmlComponent>
#include <QQmlIncubator>
#include "../../shared/util.h"
+#include <private/qjsvalue_p.h>
#include <private/qqmlincubator_p.h>
#include <private/qqmlobjectcreator_p.h>
@@ -68,6 +69,7 @@ private slots:
void chainedAsynchronousClear();
void selfDelete();
void contextDelete();
+ void garbageCollection();
private:
QQmlIncubationController controller;
@@ -1144,6 +1146,34 @@ void tst_qqmlincubator::contextDelete()
}
}
+// QTBUG-53111
+void tst_qqmlincubator::garbageCollection()
+{
+ QQmlComponent component(&engine, testFileUrl("garbageCollection.qml"));
+ QScopedPointer<QObject> obj(component.create());
+
+ engine.collectGarbage();
+
+ bool b = true;
+ controller.incubateWhile(&b);
+
+ // verify incubation completed (the incubator was not prematurely collected)
+ QVariant incubatorVariant;
+ QMetaObject::invokeMethod(obj.data(), "getAndClearIncubator", Q_RETURN_ARG(QVariant, incubatorVariant));
+ QJSValue strongRef = incubatorVariant.value<QJSValue>();
+ QVERIFY(!strongRef.isNull() && !strongRef.isUndefined());
+
+ // turn the last strong reference to the incubator into a weak one and collect
+ QV4::WeakValue weakIncubatorRef;
+ weakIncubatorRef.set(QQmlEnginePrivate::getV4Engine(&engine), *QJSValuePrivate::getValue(&strongRef));
+ strongRef = QJSValue();
+ incubatorVariant.clear();
+
+ // verify incubator is correctly collected now that incubation is complete and all references are gone
+ engine.collectGarbage();
+ QVERIFY(weakIncubatorRef.isNullOrUndefined());
+}
+
QTEST_MAIN(tst_qqmlincubator)
#include "tst_qqmlincubator.moc"
diff --git a/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp b/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp
index b353d23539..b0be799bd5 100644
--- a/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp
+++ b/tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp
@@ -53,6 +53,7 @@ private slots:
void categories();
void siblings();
void initial();
+ void noApplicationIdentifiersSet();
};
// ### Replace keyValueMap("foo", "bar") with QVariantMap({{"foo", "bar"}})
@@ -147,10 +148,6 @@ void tst_QQmlSettings::initTestCase()
{
QQmlDataTest::initTestCase();
- QCoreApplication::setApplicationName("tst_QQmlSettings");
- QCoreApplication::setOrganizationName("QtProject");
- QCoreApplication::setOrganizationDomain("qt-project.org");
-
qmlRegisterType<CppObject>("Qt.test", 1, 0, "CppObject");
}
@@ -158,6 +155,10 @@ void tst_QQmlSettings::init()
{
QSettings settings;
settings.clear();
+
+ QCoreApplication::setApplicationName("tst_QQmlSettings");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setOrganizationDomain("qt-project.org");
}
void tst_QQmlSettings::cleanup()
@@ -481,6 +482,31 @@ void tst_QQmlSettings::initial()
QCOMPARE(settings->property("value").toString(), QStringLiteral("initial"));
}
+void tst_QQmlSettings::noApplicationIdentifiersSet()
+{
+#ifdef Q_OS_MACOS
+ QSKIP("macOS doesn't complain about empty application identifiers");
+#endif
+
+ QCoreApplication::setApplicationName(QString());
+ QCoreApplication::setOrganizationName(QString());
+ QCoreApplication::setOrganizationDomain(QString());
+
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*QML Settings: Failed to initialize QSettings instance. Status code is: 1"));
+ // Can't set an empty applicationName because QCoreApplication won't allow it, which is why it's not listed here.
+ QTest::ignoreMessage(QtWarningMsg, QRegularExpression(".*QML Settings: The following application identifiers have not been set: QVector\\(\"organizationName\", \"organizationDomain\"\\)"));
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("basic.qml"));
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(root.data());
+ // The value of the QML property will be true because it defaults to it...
+ QVERIFY(root->property("success").toBool());
+ QSettings settings;
+ // ... but the settings' value should be false because it was never loaded.
+ QVERIFY(!settings.value("success").toBool());
+}
+
QTEST_MAIN(tst_QQmlSettings)
#include "tst_qqmlsettings.moc"
diff --git a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
index 0ee78fae54..1bfeb94161 100644
--- a/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
+++ b/tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp
@@ -42,9 +42,11 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlproperty.h>
#include <QtQuick/private/qquickaccessibleattached_p.h>
+#include <QtQuick/private/qquicklistview_p.h>
+#include <QtQuick/private/qquicktext_p.h>
#include "../../shared/util.h"
-
+#include "../shared/visualtestutil.h"
#define EXPECT(cond) \
do { \
@@ -224,6 +226,72 @@ void tst_QQuickAccessible::quickAttachedProperties()
}
delete object;
}
+
+ // Check overriding of attached role for Text
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nText {\n"
+ "Accessible.role: Accessible.Button\n"
+ "Accessible.name: \"TextButton\"\n"
+ "Accessible.description: \"Text Button\"\n"
+ "}", QUrl());
+ QObject *object = component.create();
+ QVERIFY(object != nullptr);
+
+ QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(object);
+ QVERIFY(attachedObject);
+ if (attachedObject) {
+ QVariant p = attachedObject->property("role");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toInt(), int(QAccessible::PushButton));
+ p = attachedObject->property("name");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toString(), QLatin1String("TextButton"));
+ p = attachedObject->property("description");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toString(), QLatin1String("Text Button"));
+ }
+ delete object;
+ }
+ // Check overriding of attached role for Text
+ {
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nListView {\n"
+ "id: list\n"
+ "model: 5\n"
+ "delegate: Text {\n"
+ "objectName: \"acc_text\"\n"
+ "Accessible.role: Accessible.Button\n"
+ "Accessible.name: \"TextButton\"\n"
+ "Accessible.description: \"Text Button\"\n"
+ "}\n"
+ "}", QUrl());
+ QObject *object = component.create();
+ QVERIFY(object != nullptr);
+
+ QQuickListView *listview = qobject_cast<QQuickListView *>(object);
+ QVERIFY(listview != nullptr);
+ QQuickItem *contentItem = listview->contentItem();
+ QQuickText *childItem = QQuickVisualTestUtil::findItem<QQuickText>(contentItem, "acc_text");
+ QVERIFY(childItem != nullptr);
+
+ QObject *attachedObject = QQuickAccessibleAttached::attachedProperties(childItem);
+ QVERIFY(attachedObject);
+ if (attachedObject) {
+ QVariant p = attachedObject->property("role");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toInt(), int(QAccessible::PushButton));
+ p = attachedObject->property("name");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toString(), QLatin1String("TextButton"));
+ p = attachedObject->property("description");
+ QCOMPARE(p.isNull(), false);
+ QCOMPARE(p.toString(), QLatin1String("Text Button"));
+ }
+ delete object;
+ }
QTestAccessibility::clearEvents();
}
diff --git a/tests/auto/quick/qquickmousearea/data/nestedSendEvent.qml b/tests/auto/quick/qquickmousearea/data/nestedSendEvent.qml
new file mode 100644
index 0000000000..908a43b04e
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/data/nestedSendEvent.qml
@@ -0,0 +1,49 @@
+import QtQuick 2.11
+import QtQuick.Window 2.11
+import Test 1.0
+
+Window {
+ id: window
+ visible: true
+ width: 200
+ height: 200
+
+ property EventSender sender: EventSender { }
+
+ Item {
+ width: 200
+ height: 200
+
+ MouseArea {
+ anchors.fill: parent
+ }
+
+ Item {
+ width: 200
+ height: 200
+
+ Rectangle {
+ width: 200
+ height: 100
+ color: "red"
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: sender.sendMouseClick(window, 50, 50)
+ }
+ }
+
+ Rectangle {
+ y: 100
+ width: 200
+ height: 100
+ color: "yellow"
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: sender.sendMouseClick(window, 50, 50)
+ }
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index aa379e834e..558ca2e759 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -98,6 +98,22 @@ private:
qreal m_radius;
};
+class EventSender : public QObject {
+ Q_OBJECT
+
+public:
+ Q_INVOKABLE void sendMouseClick(QObject* obj ,qreal x , qreal y) {
+ {
+ QMouseEvent event(QEvent::MouseButtonPress, QPointF(x , y), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ qApp->sendEvent(obj, &event);
+ }
+ {
+ QMouseEvent event(QEvent::MouseButtonRelease, QPointF(x , y), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ qApp->sendEvent(obj, &event);
+ }
+ }
+};
+
class tst_QQuickMouseArea: public QQmlDataTest
{
Q_OBJECT
@@ -106,6 +122,7 @@ public:
: device(nullptr)
{
qmlRegisterType<CircleMask>("Test", 1, 0, "CircleMask");
+ qmlRegisterType<EventSender>("Test", 1, 0, "EventSender");
}
private slots:
@@ -165,6 +182,7 @@ private slots:
void pressOneAndTapAnother_data();
void pressOneAndTapAnother();
void mask();
+ void nestedEventDelivery();
private:
int startDragDistance() const {
@@ -2298,6 +2316,21 @@ void tst_QQuickMouseArea::mask()
QCOMPARE(window.rootObject()->property("clicked").toInt(), 1);
}
+void tst_QQuickMouseArea::nestedEventDelivery() // QTBUG-70898
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("nestedSendEvent.qml"));
+ QScopedPointer<QQuickWindow> window(qmlobject_cast<QQuickWindow *>(c.create()));
+ QVERIFY(window.data());
+
+ // Click each MouseArea and verify that it doesn't crash
+ QByteArray message = "event went missing during delivery! (nested sendEvent() is not allowed)";
+ QTest::ignoreMessage(QtWarningMsg, message);
+ QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(50,50));
+ QTest::ignoreMessage(QtWarningMsg, message); // twice though, actually
+ QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(50,150));
+}
+
QTEST_MAIN(tst_QQuickMouseArea)
#include "tst_qquickmousearea.moc"
diff --git a/tests/auto/quick/qquickstates/data/duplicateStateName.qml b/tests/auto/quick/qquickstates/data/duplicateStateName.qml
new file mode 100644
index 0000000000..7bfafbef1b
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/duplicateStateName.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Rectangle {
+ property bool condition1: false
+ property bool condition2: false
+ property bool condition3: false
+
+ states: [
+ State { name: "state1"; when: condition1 },
+ State { name: "state2"; when: condition2 },
+ State { name: "state1"; when: condition3 }
+ ]
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index 073fe33e20..50554f6333 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -137,6 +137,7 @@ private slots:
void revertListBug();
void QTBUG_38492();
void revertListMemoryLeak();
+ void duplicateStateName();
};
void tst_qquickstates::initTestCase()
@@ -1654,6 +1655,17 @@ void tst_qquickstates::revertListMemoryLeak()
QVERIFY(bindingPtr->ref == 1);
}
+void tst_qquickstates::duplicateStateName()
+{
+ QQmlEngine engine;
+
+ QQmlComponent c(&engine, testFileUrl("duplicateStateName.qml"));
+ QTest::ignoreMessage(QtWarningMsg, fullDataPath("duplicateStateName.qml") + ":3:1: QML Rectangle: Found duplicate state name: state1");
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem *>(c.create()));
+ QVERIFY(!item.isNull());
+}
+
+
QTEST_MAIN(tst_qquickstates)
#include "tst_qquickstates.moc"
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index e7523ec269..7ab42e9a26 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -66,9 +66,6 @@
#include <QtGui/private/qsimulatorconnection_p.h>
#endif
-#ifdef Q_OS_UNIX
-#include <signal.h>
-#endif
#ifdef Q_OS_WIN
# if !defined(Q_CC_MINGW)
# include <crtdbg.h>
@@ -750,17 +747,6 @@ enum ExitCode {
EXIT_IMPORTERROR = 3
};
-#ifdef Q_OS_UNIX
-Q_NORETURN void sigSegvHandler(int) {
- fprintf(stderr, "Error: SEGV\n");
- if (!currentProperty.isEmpty())
- fprintf(stderr, "While processing the property '%s', which probably has uninitialized data.\n", currentProperty.toLatin1().constData());
- if (!inObjectInstantiation.isEmpty())
- fprintf(stderr, "While instantiating the object '%s'.\n", inObjectInstantiation.toLatin1().constData());
- exit(EXIT_SEGV);
-}
-#endif
-
void printUsage(const QString &appName)
{
std::cerr << qPrintable(QString(
@@ -985,17 +971,6 @@ int main(int argc, char *argv[])
#endif // Q_OS_WIN && !Q_CC_MINGW
// The default message handler might not print to console on some systems. Enforce this.
qInstallMessageHandler(printDebugMessage);
-#ifdef Q_OS_UNIX
- // qmldump may crash, but we don't want any crash handlers to pop up
- // therefore we intercept the segfault and just exit() ourselves
- struct sigaction sigAction;
-
- sigemptyset(&sigAction.sa_mask);
- sigAction.sa_handler = &sigSegvHandler;
- sigAction.sa_flags = 0;
-
- sigaction(SIGSEGV, &sigAction, nullptr);
-#endif
#ifdef QT_SIMULATOR
// Running this application would bring up the Qt Simulator (since it links Qt GUI), avoid that!