aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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/quick/accessible/qaccessiblequickitem.cpp10
-rw-r--r--src/quick/items/qquickevents_p_p.h2
-rw-r--r--src/quick/items/qquickwindow.cpp8
-rw-r--r--src/quick/scenegraph/qsgbasicinternalimagenode.cpp3
-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--tools/qmlplugindump/main.cpp25
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!