diff options
author | Liang Qi <liang.qi@qt.io> | 2018-10-29 08:09:46 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-10-29 08:10:45 +0100 |
commit | 2609429d7afc263ab8e44864b0f42f1c8356eda8 (patch) | |
tree | 78798b4006a7c6664bf41b44011a57110ee94acd | |
parent | 475c74a9926efcd968572563e678988e53804603 (diff) | |
parent | 4a886753a75c7c4d66f1fa9cab5a6c5a03240df3 (diff) |
Merge remote-tracking branch 'origin/5.11' into 5.12
Conflicts:
src/imports/settings/qqmlsettings.cpp
src/quick/items/qquickwindow.cpp
tools/qmlplugindump/main.cpp
Change-Id: I96fedbc773a110374baed79a0b7de92d65df0ed6
-rw-r--r-- | src/imports/layouts/qquicklayout.cpp | 12 | ||||
-rw-r--r-- | src/imports/settings/qqmlsettings.cpp | 22 | ||||
-rw-r--r-- | src/qml/doc/src/qmllanguageref/syntax/objectattributes.qdoc | 2 | ||||
-rw-r--r-- | src/quick/accessible/qaccessiblequickitem.cpp | 10 | ||||
-rw-r--r-- | src/quick/items/qquickevents_p_p.h | 2 | ||||
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 8 | ||||
-rw-r--r-- | src/quick/scenegraph/qsgbasicinternalimagenode.cpp | 3 | ||||
-rw-r--r-- | tests/auto/qml/qqmlsettings/tst_qqmlsettings.cpp | 34 | ||||
-rw-r--r-- | tests/auto/quick/qquickaccessible/tst_qquickaccessible.cpp | 70 | ||||
-rw-r--r-- | tests/auto/quick/qquickmousearea/data/nestedSendEvent.qml | 49 | ||||
-rw-r--r-- | tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp | 33 | ||||
-rw-r--r-- | tools/qmlplugindump/main.cpp | 25 |
12 files changed, 232 insertions, 38 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/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/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/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/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp index 8f9ac2d1da..f5bd6d2291 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! |