diff options
author | Qt Forward Merge Bot <qt_forward_merge_bot@qt-project.org> | 2018-07-14 01:02:04 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-07-16 09:38:30 +0200 |
commit | 43645fd59c6bcb0a3e37eef530ef970f51ed48af (patch) | |
tree | d377a19c36e9e853377db59b58d937db0ea67e0d | |
parent | ad0f200df54e5afcb1fdcb977794259bdb9216b5 (diff) | |
parent | f42207cbdb0cbe5e345bfd9e000b3e77b34a503c (diff) |
Merge remote-tracking branch 'origin/5.11' into dev
Conflicts:
src/quick/items/qquickloader.cpp
tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
Change-Id: I0cb9f637d24ccd0ecfb50c455cc210119f744b02
35 files changed, 519 insertions, 129 deletions
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp index b3a5a2cfc8..cc206bcb95 100644 --- a/src/imports/layouts/qquicklayout.cpp +++ b/src/imports/layouts/qquicklayout.cpp @@ -764,6 +764,9 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in ignoreItem = effectiveMaxSize.isNull(); } + if (!ignoreItem && childPrivate->isTransparentForPositioner()) + ignoreItem = true; + if (ignoreItem) d->m_ignoredItems << child; return ignoreItem; diff --git a/src/imports/window/plugins.qmltypes b/src/imports/window/plugins.qmltypes index 4ae23a093e..4815be7262 100644 --- a/src/imports/window/plugins.qmltypes +++ b/src/imports/window/plugins.qmltypes @@ -4,7 +4,7 @@ import QtQuick.tooling 1.2 // It is used for QML tooling purposes only. // // This file was auto-generated by: -// 'qmlplugindump -nonrelocatable QtQuick.Window 2.10' +// 'qmlplugindump -nonrelocatable QtQuick.Window 2.11' Module { dependencies: ["QtQuick 2.8"] diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 17bae6d695..4c104f01de 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -68,6 +68,37 @@ QT_BEGIN_NAMESPACE using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>; +class NullDevice : public QIODevice +{ +public: + NullDevice() { open(QIODevice::ReadWrite); } + +protected: + qint64 readData(char *data, qint64 maxlen) final; + qint64 writeData(const char *data, qint64 len) final; +}; + +qint64 NullDevice::readData(char *data, qint64 maxlen) +{ + Q_UNUSED(data); + return maxlen; +} + +qint64 NullDevice::writeData(const char *data, qint64 len) +{ + Q_UNUSED(data); + return len; +} + +// check whether the data can be saved +// (otherwise we assert in QVariant::operator<< when actually saving it) +static bool isSaveable(const QVariant &value) +{ + NullDevice nullDevice; + QDataStream fakeStream(&nullDevice); + return QMetaType::save(fakeStream, static_cast<int>(value.type()), value.constData()); +} + QQmlEngineDebugServiceImpl::QQmlEngineDebugServiceImpl(QObject *parent) : QQmlEngineDebugService(2, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(nullptr) { @@ -106,13 +137,7 @@ QDataStream &operator<<(QDataStream &ds, const QQmlEngineDebugServiceImpl::QQmlObjectProperty &data) { ds << (int)data.type << data.name; - // check first whether the data can be saved - // (otherwise we assert in QVariant::operator<<) - QQmlDebugPacket fakeStream; - if (QMetaType::save(fakeStream, data.value.type(), data.value.constData())) - ds << data.value; - else - ds << QVariant(); + ds << (isSaveable(data.value) ? data.value : QVariant()); ds << data.valueTypeName << data.binding << data.hasNotifySignal; return ds; } @@ -247,8 +272,8 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const } } - // We expect all QML value types to either have a toString() method or stream operators - return value; + if (isSaveable(value)) + return value; } } diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 9d1a03a399..7fb4724f73 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -247,18 +247,18 @@ Similarly, if a C++ type uses a QDateTime for a property type or method parameter, the value can be created as a JavaScript \c Date object in QML, and is automatically converted to a QDateTime value when it is passed to C++. - -\section2 QTime to JavaScript Date +//! Target adds an anchor, so renaming the section won't break incoming links. +\target QTime to JavaScript Date +\section2 QTime and JavaScript Date The QML engine provides automatic type conversion from QTime values to -JavaScript \c Date objects. The date component of the resulting Date -object should not be relied upon, as it is operating system dependent. -Specifically, the year (and month and day) are set to zero. Conversion -from a JavaScript \c Date object to QTime is done by converting to a -QDateTime, and then relying on QVariant to convert it to a QTime. The end -effect is that the date part of the \c Date object is ignored, but the -local timezone will be used ignoring any DST complications it may have. +JavaScript \c Date objects. As QTime values do not contain a date component, +one is created for the conversion only. Thus, you should not rely on the date +component of the resulting Date object. +Under the hood, conversion from a JavaScript \c Date object to QTime is done by +converting to a QDateTime object and calling its \l {QDateTime::}{time()} +method. \section2 Sequence Type to JavaScript Array diff --git a/src/qml/doc/src/qtqml-cpp.qdoc b/src/qml/doc/src/qtqml-cpp.qdoc index 971bb88825..2c4d2a5ade 100644 --- a/src/qml/doc/src/qtqml-cpp.qdoc +++ b/src/qml/doc/src/qtqml-cpp.qdoc @@ -36,10 +36,12 @@ following directive: \snippet code/doc_src_qtqml.cpp 0 +\if !defined(qtforpython) To link against the module, add this line to your \l qmake \c .pro file: \snippet code/doc_src_qtqml.pro 0 +\endif For more information on the Qt QML module, see the \l{Qt QML} module documentation. diff --git a/src/qml/parser/qqmljsast.cpp b/src/qml/parser/qqmljsast.cpp index b8c4a58a13..d254279cbf 100644 --- a/src/qml/parser/qqmljsast.cpp +++ b/src/qml/parser/qqmljsast.cpp @@ -503,6 +503,28 @@ void NumericLiteralPropertyName::accept0(Visitor *visitor) visitor->endVisit(this); } +namespace { +struct LocaleWithoutZeroPadding : public QLocale +{ + LocaleWithoutZeroPadding() + : QLocale(QLocale::C) + { + setNumberOptions(QLocale::OmitLeadingZeroInExponent | QLocale::OmitGroupSeparator); + } +}; +} + +QString NumericLiteralPropertyName::asString()const +{ + // Can't use QString::number here anymore as it does zero padding by default now. + + // In C++11 this initialization is thread-safe (6.7 [stmt.dcl] p4) + static LocaleWithoutZeroPadding locale; + // Because of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83562 we can't use thread_local + // for the locale variable and therefore rely on toString(double) to be thread-safe. + return locale.toString(id, 'g', 16); +} + void ArrayMemberExpression::accept0(Visitor *visitor) { if (visitor->visit(this)) { diff --git a/src/qml/parser/qqmljsast_p.h b/src/qml/parser/qqmljsast_p.h index 2cf2bcb736..07999404b4 100644 --- a/src/qml/parser/qqmljsast_p.h +++ b/src/qml/parser/qqmljsast_p.h @@ -870,7 +870,7 @@ public: void accept0(Visitor *visitor) override; - QString asString() const override { return QString::number(id, 'g', 16); } + QString asString() const override; // attributes double id; diff --git a/src/quick/doc/images/flickable-contentXY-bottom-left.png b/src/quick/doc/images/flickable-contentXY-bottom-left.png Binary files differnew file mode 100644 index 0000000000..47d3be4625 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-bottom-left.png diff --git a/src/quick/doc/images/flickable-contentXY-bottom-left.svgz b/src/quick/doc/images/flickable-contentXY-bottom-left.svgz Binary files differnew file mode 100644 index 0000000000..db86262d74 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-bottom-left.svgz diff --git a/src/quick/doc/images/flickable-contentXY-bottom-right.png b/src/quick/doc/images/flickable-contentXY-bottom-right.png Binary files differnew file mode 100644 index 0000000000..eb9eff24c5 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-bottom-right.png diff --git a/src/quick/doc/images/flickable-contentXY-bottom-right.svgz b/src/quick/doc/images/flickable-contentXY-bottom-right.svgz Binary files differnew file mode 100644 index 0000000000..088c1bdf1e --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-bottom-right.svgz diff --git a/src/quick/doc/images/flickable-contentXY-resting.png b/src/quick/doc/images/flickable-contentXY-resting.png Binary files differnew file mode 100644 index 0000000000..11bde53da5 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-resting.png diff --git a/src/quick/doc/images/flickable-contentXY-resting.svgz b/src/quick/doc/images/flickable-contentXY-resting.svgz Binary files differnew file mode 100644 index 0000000000..c8ac118048 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-resting.svgz diff --git a/src/quick/doc/images/flickable-contentXY-top-left.png b/src/quick/doc/images/flickable-contentXY-top-left.png Binary files differnew file mode 100644 index 0000000000..de3d11d283 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-top-left.png diff --git a/src/quick/doc/images/flickable-contentXY-top-left.svgz b/src/quick/doc/images/flickable-contentXY-top-left.svgz Binary files differnew file mode 100644 index 0000000000..bcb6476cd2 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-top-left.svgz diff --git a/src/quick/doc/images/flickable-contentXY-top-right.png b/src/quick/doc/images/flickable-contentXY-top-right.png Binary files differnew file mode 100644 index 0000000000..7f4a16bde1 --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-top-right.png diff --git a/src/quick/doc/images/flickable-contentXY-top-right.svgz b/src/quick/doc/images/flickable-contentXY-top-right.svgz Binary files differnew file mode 100644 index 0000000000..32b721cb6b --- /dev/null +++ b/src/quick/doc/images/flickable-contentXY-top-right.svgz diff --git a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc index f27f87e743..c8bdfa28cd 100644 --- a/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc +++ b/src/quick/doc/src/guidelines/qtquick-bestpractices.qdoc @@ -59,20 +59,19 @@ custom control. \li \l{Qt Quick} \endlist +\omit \section1 Keep it Short and Simple or "KiSS" QML being a declarative language, a lot of the details are worked out by the underlying engine. So it is important for any QML application, especially one with a larger codebase, to have its code organized in smaller and simpler \c .qml files. -\omit -need a few snippet or example applications that showcase this. +TODO: need a few snippet or example applications that showcase this. \endomit -\section2 Related Information -\list - \li \l{QML Coding Conventions} -\endlist +\section1 Coding Conventions + +See \l{QML Coding Conventions}. \section1 Bundle Application Resources @@ -338,8 +337,9 @@ must be considered while using them: \section2 Dos \list - \li Use anchors or the item's width and height properties to specify the size - of the layout against its parent. + \li Use \l {Item::}{anchors} or the \l {Item::}{width} and \l {Item::}{height} + properties to specify the size of the layout against its non-layout parent + item. \li Use the \l Layout attached property to set the size and alignment attributes of the layout's immediate children. \endlist @@ -347,12 +347,10 @@ must be considered while using them: \section2 Don'ts \list - \li Do not rely on anchors to specify the preferred size of an item in a layout. - Instead, use \c Layout.preferredWidth and \c Layout.preferredHeight. \li Do not define preferred sizes for items that provide implicitWidth and implicitHeight, unless their implicit sizes are not satisfactory. - \li Do not mix anchors and layouts in ways that cause conflicts. For example, - do not apply anchor constraints to a layout's immediate children. + \li Do not use anchors on an item that is an immediate child of a layout. + Instead, use \c Layout.preferredWidth and \c Layout.preferredHeight: \snippet qml/windowconstraints.qml rowlayout \endlist @@ -369,6 +367,36 @@ properties are enough. \li \l{Qt Quick Layouts Overview} \endlist +\section1 Type Safety + +When declaring properties in QML, it's easy and convenient to use the "var" type: + +\code +property var name +property var size +property var optionsMenu +\endcode + +However, this approach has several disadvantages: +\list + \li If a value with the wrong type is assigned, the error reported will point + to the location of the property declaration, as opposed to the location + where the property was assigned to. This slows down the development + process by making it more difficult to track down errors. + \li Static anaylsis to catch errors like the ones mentioned above is not + possible. + \li The actual underlying type of the property is not always immediately clear + to the reader. +\endlist + +Instead, always use the actual type where possible: + +\code +property string name +property int size +property MyMenu optionsMenu +\endcode + \section1 Performance For information on performance in QML and Qt Quick, @@ -420,7 +448,7 @@ on the display resolution on offer. \section2 Related Information \list - \li \l{Qt Quick Controls 2 - Gallery Example}{Gallery example} + \li \l{Qt Quick Controls 2 - Gallery}{Gallery example} \li \l{Qt Quick Controls 2 - Text Editor}{Text Editor example} \li \l{Font Awesome} \li \l{Scalability} diff --git a/src/quick/doc/src/includes/item.qdocinc b/src/quick/doc/src/includes/item.qdocinc new file mode 100644 index 0000000000..12472cb928 --- /dev/null +++ b/src/quick/doc/src/includes/item.qdocinc @@ -0,0 +1,6 @@ +//! [mapping] + +The following properties of the item are used in the mapping: +\l x, \l y, \l scale, \l rotation, \l transformOrigin, and \l [QML]{Item::}{transform}. + +//! [mapping] diff --git a/src/quick/doc/src/qtquick-cpp.qdoc b/src/quick/doc/src/qtquick-cpp.qdoc index ca6fe3d0c0..8a1ab915f2 100644 --- a/src/quick/doc/src/qtquick-cpp.qdoc +++ b/src/quick/doc/src/qtquick-cpp.qdoc @@ -38,10 +38,12 @@ \snippet code/doc_src_qtquick.cpp 0 + \if !defined(qtforpython) To link against the module, add this line to your \l qmake \c .pro file: \snippet code/doc_src_qtquick.pro 0 + \endif For more information on the Qt Quick module, see the \l{Qt Quick} module documentation. diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 5a3db5e1eb..b47d055ca4 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -633,6 +633,31 @@ void QQuickFlickablePrivate::updateBeginningEnd() \c contentItem that are relevant. For example, the bound of Items added to the Flickable will be available by \c contentItem.childrenRect + \section1 Examples of contentX and contentY + + The following images demonstrate a flickable being flicked in various + directions and the resulting \l contentX and \l contentY values. + The blue square represents the flickable's content, and the black + border represents the bounds of the flickable. + + \table + \row + \li \image flickable-contentXY-resting.png + \li The \c contentX and \c contentY are both \c 0. + \row + \li \image flickable-contentXY-top-left.png + \li The \c contentX and the \c contentY are both \c 50. + \row + \li \image flickable-contentXY-top-right.png + \li The \c contentX is \c -50 and the \c contentY is \c 50. + \row + \li \image flickable-contentXY-bottom-right.png + \li The \c contentX and the \c contentY are both \c -50. + \row + \li \image flickable-contentXY-bottom-left.png + \li The \c contentX is \c 50 and the \c contentY is \c -50. + \endtable + \section1 Limitations \note Due to an implementation detail, items placed inside a Flickable @@ -738,7 +763,7 @@ QQuickFlickable::~QQuickFlickable() for the position; another way is to use the normalized values in \l {QtQuick::Flickable::visibleArea}{visibleArea}. - \sa originX, originY + \sa {Examples of contentX and contentY}, originX, originY */ qreal QQuickFlickable::contentX() const { diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index b09dbdad84..c1e625ef95 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -2356,6 +2356,9 @@ void QQuickItemPrivate::updateSubFocusItem(QQuickItem *scope, bool focus) \fn QQuickItem::QQuickItem(QQuickItem *parent) Constructs a QQuickItem with the given \a parent. + + The \c parent will be used as both the \l {setParentItem()}{visual parent} + and the \l QObject parent. */ QQuickItem::QQuickItem(QQuickItem* parent) : QObject(*(new QQuickItemPrivate), parent) @@ -4407,6 +4410,8 @@ void QQuickItem::polish() item's coordinate system, to this item's coordinate system, and returns a \l point or \l rect matching the mapped coordinate. + \input item.qdocinc mapping + If \a item is a \c null value, this maps the point or rect from the coordinate system of the root QML view. */ @@ -4495,6 +4500,8 @@ QTransform QQuickItem::itemTransform(QQuickItem *other, bool *ok) const item's coordinate system, to \a item's coordinate system, and returns a \l point or \l rect matching the mapped coordinate. + \input item.qdocinc mapping + If \a item is a \c null value, this maps the point or rect to the coordinate system of the root QML view. */ @@ -4564,6 +4571,8 @@ void QQuickItem::mapToItem(QQmlV4Function *args) const Maps the point (\a x, \a y), which is in the global coordinate system, to the item's coordinate system, and returns a \l point matching the mapped coordinate. + + \input item.qdocinc mapping */ /*! \internal @@ -4599,6 +4608,8 @@ void QQuickItem::mapFromGlobal(QQmlV4Function *args) const Maps the point (\a x, \a y), which is in this item's coordinate system, to the global coordinate system, and returns a \l point matching the mapped coordinate. + + \input item.qdocinc mapping */ /*! \internal @@ -7701,6 +7712,8 @@ void QQuickItem::setContainmentMask(QObject *mask) point within \a item's coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + If \a item is 0, this maps \a point to the coordinate system of the scene. @@ -7719,6 +7732,8 @@ QPointF QQuickItem::mapToItem(const QQuickItem *item, const QPointF &point) cons point within the scene's coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + \sa {Concepts - Visual Coordinates in Qt Quick} */ QPointF QQuickItem::mapToScene(const QPointF &point) const @@ -7732,6 +7747,8 @@ QPointF QQuickItem::mapToScene(const QPointF &point) const point within global screen coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + For example, this may be helpful to add a popup to a Qt Quick component. \note Window positioning is done by the window manager and this value is @@ -7753,6 +7770,8 @@ QPointF QQuickItem::mapToGlobal(const QPointF &point) const rectangular area within \a item's coordinate system, and returns the mapped rectangle value. + \input item.qdocinc mapping + If \a item is 0, this maps \a rect to the coordinate system of the scene. @@ -7772,6 +7791,8 @@ QRectF QQuickItem::mapRectToItem(const QQuickItem *item, const QRectF &rect) con rectangular area within the scene's coordinate system, and returns the mapped rectangle value. + \input item.qdocinc mapping + \sa {Concepts - Visual Coordinates in Qt Quick} */ QRectF QQuickItem::mapRectToScene(const QRectF &rect) const @@ -7785,6 +7806,8 @@ QRectF QQuickItem::mapRectToScene(const QRectF &rect) const point within this item's coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + If \a item is 0, this maps \a point from the coordinate system of the scene. @@ -7801,6 +7824,8 @@ QPointF QQuickItem::mapFromItem(const QQuickItem *item, const QPointF &point) co point within this item's coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + \sa {Concepts - Visual Coordinates in Qt Quick} */ QPointF QQuickItem::mapFromScene(const QPointF &point) const @@ -7814,6 +7839,8 @@ QPointF QQuickItem::mapFromScene(const QPointF &point) const equivalent point within this item's coordinate system, and returns the mapped coordinate. + \input item.qdocinc mapping + For example, this may be helpful to add a popup to a Qt Quick component. \note Window positioning is done by the window manager and this value is @@ -7835,6 +7862,8 @@ QPointF QQuickItem::mapFromGlobal(const QPointF &point) const rectangular area within this item's coordinate system, and returns the mapped rectangle value. + \input item.qdocinc mapping + If \a item is 0, this maps \a rect from the coordinate system of the scene. @@ -7853,6 +7882,8 @@ QRectF QQuickItem::mapRectFromItem(const QQuickItem *item, const QRectF &rect) c rectangular area within this item's coordinate system, and returns the mapped rectangle value. + \input item.qdocinc mapping + \sa {Concepts - Visual Coordinates in Qt Quick} */ QRectF QQuickItem::mapRectFromScene(const QRectF &rect) const diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index 0de9d6c49a..f32f25a42f 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -112,6 +112,8 @@ void QQuickLoaderPrivate::clear() q, SIGNAL(progressChanged())); component->deleteLater(); component.setObject(nullptr, q); + } else if (component) { + component.setObject(nullptr, q); } source = QUrl(); @@ -437,7 +439,8 @@ void QQuickLoader::loadFromSource() if (isComponentComplete()) { QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous; - d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); + if (!d->component) + d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); d->load(); } } @@ -823,7 +826,8 @@ void QQuickLoader::componentComplete() if (active()) { if (d->loadingFromSource) { QQmlComponent::CompilationMode mode = d->asynchronous ? QQmlComponent::Asynchronous : QQmlComponent::PreferSynchronous; - d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); + if (!d->component) + d->component.setObject(new QQmlComponent(qmlEngine(this), d->source, mode, this), this); } d->load(); } diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index b06b0821d2..86a64cdeeb 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -385,7 +385,8 @@ QImage QQuickRenderControl::grab() cd->syncSceneGraph(); d->rc->endSync(); render(); - grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), false, false); + const bool alpha = d->window->format().alphaBufferSize() > 0 && d->window->color().alpha() < 255; + grabContent = qt_gl_read_framebuffer(d->window->size() * d->window->effectiveDevicePixelRatio(), alpha, alpha); if (QQuickRenderControl::renderWindowFor(d->window)) { grabContent.setDevicePixelRatio(d->window->effectiveDevicePixelRatio()); } diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index c8699426f2..ad451c8f8b 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -211,6 +211,7 @@ QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransition *transition, QQuickTransitionInstance::~QQuickTransitionInstance() { + stop(); removeStateChangeListener(); delete m_anim; } diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp index 35df46d73c..e3996e0c18 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp @@ -227,6 +227,8 @@ private: QPointer<QJSDebugClient> m_client; void targetData(); + bool waitForClientSignal(const char *signal, int timeout = 30000); + QTime t; }; @@ -798,7 +800,7 @@ void tst_QQmlDebugJS::connect() QFETCH(bool, qmlscene); QCOMPARE(init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode), ConnectSuccess); m_client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected()))); + QVERIFY(waitForClientSignal(SIGNAL(connected()))); } void tst_QQmlDebugJS::interrupt() @@ -812,7 +814,7 @@ void tst_QQmlDebugJS::interrupt() m_client->connect(redundantRefs, namesAsObjects); m_client->interrupt(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(interruptRequested()))); + QVERIFY(waitForClientSignal(SIGNAL(interruptRequested()))); } void tst_QQmlDebugJS::getVersion() @@ -824,10 +826,10 @@ void tst_QQmlDebugJS::getVersion() QFETCH(bool, namesAsObjects); QCOMPARE(init(qmlscene), ConnectSuccess); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(connected()))); + QVERIFY(waitForClientSignal(SIGNAL(connected()))); m_client->version(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::getVersionWhenAttaching() @@ -841,7 +843,7 @@ void tst_QQmlDebugJS::getVersionWhenAttaching() m_client->connect(redundantRefs, namesAsObjects); m_client->version(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::disconnect() @@ -855,7 +857,7 @@ void tst_QQmlDebugJS::disconnect() m_client->connect(redundantRefs, namesAsObjects); m_client->disconnect(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() @@ -870,7 +872,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -893,7 +895,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -916,7 +918,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() //We can set the breakpoint after connect() here because the timer is repeating and if we miss //its first iteration we can still catch the second one. m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -939,7 +941,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() m_client->setBreakpoint(QLatin1String(TEST_JSFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -964,7 +966,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnComment() m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1)); + QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1)); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -989,7 +991,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()), 1)); + QVERIFY(waitForClientSignal(SIGNAL(stopped()), 1)); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1012,7 +1014,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() m_client->setBreakpoint(QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1035,7 +1037,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() m_client->connect(redundantRefs, namesAsObjects); //The breakpoint is in a timer loop so we can set it after connect(). m_client->setBreakpoint(QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10")); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); //Get the frame index QString jsonString = m_client->response; @@ -1047,7 +1049,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() //Verify the value of 'result' m_client->evaluate(QLatin1String("a"),frameIndex); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } jsonString = m_client->response; @@ -1073,7 +1075,7 @@ void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() m_client->setBreakpoint(QLatin1String(QUIT_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1102,7 +1104,7 @@ void tst_QQmlDebugJS::setBreakpointWhenAttaching() //The breakpoint is in a timer loop so we can set it after connect(). m_client->setBreakpoint(QLatin1String(TIMER_QMLFILE), sourceLine); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); } void tst_QQmlDebugJS::clearBreakpoint() @@ -1123,7 +1125,7 @@ void tst_QQmlDebugJS::clearBreakpoint() m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true); m_client->setBreakpoint(QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); //Will hit 1st brakpoint, change this breakpoint enable = false QString jsonString(m_client->response); @@ -1135,17 +1137,17 @@ void tst_QQmlDebugJS::clearBreakpoint() int breakpoint = breakpointsHit.at(0).toInt(); m_client->clearBreakpoint(breakpoint); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); //Continue with debugging m_client->continueDebugging(QJSDebugClient::Continue); //Hit 2nd breakpoint - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); //Continue with debugging m_client->continueDebugging(QJSDebugClient::Continue); //Should stop at 2nd breakpoint - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); jsonString = m_client->response; value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1165,7 +1167,7 @@ void tst_QQmlDebugJS::setExceptionBreak() QCOMPARE(init(qmlscene, EXCEPTION_QMLFILE), ConnectSuccess); m_client->setExceptionBreak(QJSDebugClient::All,true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); } void tst_QQmlDebugJS::stepNext() @@ -1180,10 +1182,10 @@ void tst_QQmlDebugJS::stepNext() m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->continueDebugging(QJSDebugClient::Next); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1215,11 +1217,11 @@ void tst_QQmlDebugJS::stepIn() m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine); m_client->continueDebugging(QJSDebugClient::In); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); const QVariantMap body = responseBody(m_client); QCOMPARE(body.value("sourceLine").toInt(), actualLine); @@ -1239,11 +1241,11 @@ void tst_QQmlDebugJS::stepOut() m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QCOMPARE(responseBody(m_client).value("sourceLine").toInt(), sourceLine); m_client->continueDebugging(QJSDebugClient::Out); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); const QVariantMap body = responseBody(m_client); QCOMPARE(body.value("sourceLine").toInt(), actualLine); @@ -1264,10 +1266,10 @@ void tst_QQmlDebugJS::continueDebugging() m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); m_client->setBreakpoint(QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->continueDebugging(QJSDebugClient::Continue); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1290,10 +1292,10 @@ void tst_QQmlDebugJS::backtrace() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->backtrace(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::getFrameDetails() @@ -1308,10 +1310,10 @@ void tst_QQmlDebugJS::getFrameDetails() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->frame(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::getScopeDetails() @@ -1326,10 +1328,10 @@ void tst_QQmlDebugJS::getScopeDetails() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->scope(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); } void tst_QQmlDebugJS::evaluateInGlobalScope() @@ -1342,7 +1344,7 @@ void tst_QQmlDebugJS::evaluateInGlobalScope() for (int i = 0; i < 10; ++i) { // The engine might not be initialized, yet. We just try until it shows up. m_client->evaluate(QLatin1String("console.log('Hello World')")); - if (QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()), 500)) + if (waitForClientSignal(SIGNAL(result()), 500)) break; } @@ -1362,10 +1364,10 @@ void tst_QQmlDebugJS::evaluateInLocalScope() m_client->setBreakpoint(QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->frame(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); //Get the frame index QString jsonString(m_client->response); @@ -1376,7 +1378,7 @@ void tst_QQmlDebugJS::evaluateInLocalScope() int frameIndex = body.value("index").toInt(); m_client->evaluate(QLatin1String("root.a"), frameIndex); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); //Verify the value of 'timer.interval' jsonString = m_client->response; @@ -1407,7 +1409,7 @@ void tst_QQmlDebugJS::evaluateInContext() // "a" not accessible without extra context m_client->evaluate(QLatin1String("a + 10"), -1, -1); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(failure()))); + QVERIFY(waitForClientSignal(SIGNAL(failure()))); bool success = false; engineClient->queryAvailableEngines(&success); @@ -1430,7 +1432,7 @@ void tst_QQmlDebugJS::evaluateInContext() // "a" accessible in context of surrounding object m_client->evaluate(QLatin1String("a + 10"), -1, object.debugId); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); QTRY_COMPARE(responseBody(m_client).value("value").toInt(), 20); } @@ -1446,10 +1448,10 @@ void tst_QQmlDebugJS::getScripts() m_client->setBreakpoint(QString(TEST_QMLFILE), 35, -1, true); m_client->connect(redundantRefs, namesAsObjects); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(stopped()))); + QVERIFY(waitForClientSignal(SIGNAL(stopped()))); m_client->scripts(); - QVERIFY(QQmlDebugTest::waitForSignal(m_client, SIGNAL(result()))); + QVERIFY(waitForClientSignal(SIGNAL(result()))); QString jsonString(m_client->response); QVariantMap value = m_client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); @@ -1545,6 +1547,11 @@ void tst_QQmlDebugJS::targetData() QTest::newRow("qmlscene / sparse / strings") << true << false << false; } +bool tst_QQmlDebugJS::waitForClientSignal(const char *signal, int timeout) +{ + return QQmlDebugTest::waitForSignal(m_client.data(), signal, timeout); +} + QTEST_MAIN(tst_QQmlDebugJS) #include "tst_qqmldebugjs.moc" diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index ba7c85df15..27e06c6f67 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -2064,15 +2064,14 @@ void tst_qqmlproperty::floatToStringPrecision_data() QTest::addColumn<QString>("propertyName"); QTest::addColumn<double>("number"); QTest::addColumn<QString>("qtString"); - QTest::addColumn<QString>("alternateQtString"); QTest::addColumn<QString>("jsString"); - QTest::newRow("3.4") << "a" << 3.4 << "3.4" << "3.4" << "3.4"; - QTest::newRow("0.035003945") << "b" << 0.035003945 << "0.035003945" << "0.0035003945" << "0.035003945"; - QTest::newRow("0.0000012345") << "c" << 0.0000012345 << "1.2345e-6" << "1.2345e-06" << "0.0000012345"; - QTest::newRow("0.00000012345") << "d" << 0.00000012345 << "1.2345e-7" << "1.2345e-07" << "1.2345e-7"; - QTest::newRow("1e20") << "e" << 1e20 << "1e+20" << "1e+20" << "100000000000000000000"; - QTest::newRow("1e21") << "f" << 1e21 << "1e+21" << "1e+21" << "1e+21"; + QTest::newRow("3.4") << "a" << 3.4 << "3.4" << "3.4"; + QTest::newRow("0.035003945") << "b" << 0.035003945 << "0.035003945" << "0.035003945"; + QTest::newRow("0.0000012345") << "c" << 0.0000012345 << "1.2345e-06" << "0.0000012345"; + QTest::newRow("0.00000012345") << "d" << 0.00000012345 << "1.2345e-07" << "1.2345e-7"; + QTest::newRow("1e20") << "e" << 1e20 << "1e+20" << "100000000000000000000"; + QTest::newRow("1e21") << "f" << 1e21 << "1e+21" << "1e+21"; } void tst_qqmlproperty::floatToStringPrecision() @@ -2084,24 +2083,15 @@ void tst_qqmlproperty::floatToStringPrecision() QFETCH(QString, propertyName); QFETCH(double, number); QFETCH(QString, qtString); - QFETCH(QString, alternateQtString); QFETCH(QString, jsString); QByteArray name = propertyName.toLatin1(); QCOMPARE(obj->property(name).toDouble(), number); - if (obj->property(name).toString() != qtString) { - QCOMPARE(obj->property(name).toString(), alternateQtString); - } else { - QCOMPARE(obj->property(name).toString(), qtString); - } + QCOMPARE(obj->property(name).toString(), qtString); QByteArray name1 = (propertyName + QLatin1Char('1')).toLatin1(); QCOMPARE(obj->property(name1).toDouble(), number); - if (obj->property(name1).toString() != qtString) { - QCOMPARE(obj->property(name1).toString(), alternateQtString); - } else { - QCOMPARE(obj->property(name1).toString(), qtString); - } + QCOMPARE(obj->property(name1).toString(), qtString); QByteArray name2 = (propertyName + QLatin1Char('2')).toLatin1(); QCOMPARE(obj->property(name2).toDouble(), number); diff --git a/tests/auto/quick/qquickanimations/data/replacingTransitions.qml b/tests/auto/quick/qquickanimations/data/replacingTransitions.qml new file mode 100644 index 0000000000..ff7c50cd67 --- /dev/null +++ b/tests/auto/quick/qquickanimations/data/replacingTransitions.qml @@ -0,0 +1,51 @@ +import QtQuick 2.9 + +Rectangle { + id: theRoot + property alias model: theModel + property alias addTimer: addToModel + property alias addTransition: addTrans + property alias displaceTransition: displaceTrans + + width: 400 + height: 400 + + ListModel { + id: theModel + } + Timer { + id: addToModel + interval: 1000 + running: false + repeat: true + onTriggered: { + theModel.insert(0, {"name": "item " + theModel.count}) + if (theModel.count > 2) + stop() + } + } + Component { + id: listDelegate + Text { + text: name + } + } + ListView { + id: listView + + property int animationDuration: 10000 + + anchors.fill: parent + model: theModel + delegate: listDelegate + add: Transition { + id: addTrans + NumberAnimation { properties: "x"; from: 400; duration: listView.animationDuration } + NumberAnimation { properties: "y"; from: 400; duration: listView.animationDuration } + } + addDisplaced: Transition { + id: displaceTrans + NumberAnimation { properties: "x,y"; duration: listView.animationDuration } + } + } +} diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp index 3cfe03a376..0f095774e8 100644 --- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp +++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp @@ -29,6 +29,8 @@ #include <QtQml/qqmlengine.h> #include <QtQml/qqmlcomponent.h> #include <QtQuick/qquickview.h> +#include <QtQml/private/qqmltimer_p.h> +#include <QtQml/private/qqmllistmodel_p.h> #include <QtQml/private/qanimationgroupjob_p.h> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquickitemanimation_p.h> @@ -106,6 +108,7 @@ private slots: void pathLineUnspecifiedXYBug(); void unsetAnimatorProxyJobWindow(); void finished(); + void replacingTransitions(); }; #define QTIMED_COMPARE(lhs, rhs) do { \ @@ -1686,6 +1689,40 @@ void tst_qquickanimations::finished() } } +void tst_qquickanimations::replacingTransitions() +{ + QQmlEngine engine; + QQmlComponent c(&engine, testFileUrl("replacingTransitions.qml")); + QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create())); + if (!c.errors().isEmpty()) + qDebug() << c.errorString(); + QVERIFY(rect); + + QQmlTimer *addTimer = rect->property("addTimer").value<QQmlTimer*>(); + QVERIFY(addTimer); + QCOMPARE(addTimer->isRunning(), false); + + QQuickTransition *addTrans = rect->property("addTransition").value<QQuickTransition*>(); + QVERIFY(addTrans); + QCOMPARE(addTrans->running(), false); + + QQuickTransition *displaceTrans = rect->property("displaceTransition").value<QQuickTransition*>(); + QVERIFY(displaceTrans); + QCOMPARE(displaceTrans->running(), false); + + QQmlListModel *model = rect->property("model").value<QQmlListModel *>(); + QVERIFY(model); + QCOMPARE(model->count(), 0); + + addTimer->start(); + QTest::qWait(1000 + 1000 + 10000); + + QTRY_COMPARE(addTimer->isRunning(), false); + QTRY_COMPARE(addTrans->running(), false); + QTRY_COMPARE(displaceTrans->running(), false); + QCOMPARE(model->count(), 3); +} + QTEST_MAIN(tst_qquickanimations) #include "tst_qquickanimations.moc" diff --git a/tests/auto/quick/qquickitem/BLACKLIST b/tests/auto/quick/qquickitem/BLACKLIST index 85c4df4feb..d94a3ef102 100644 --- a/tests/auto/quick/qquickitem/BLACKLIST +++ b/tests/auto/quick/qquickitem/BLACKLIST @@ -1,5 +1,2 @@ [contains:hollow square: testing points inside] xcb - -[qtBug60123] -offscreen diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index ee9d36560d..7e132f97b6 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -2105,32 +2105,34 @@ void tst_qquickitem::shortcutOverride() void tst_qquickitem::qtBug60123() { QMainWindow main; + main.resize(400, 200); QQuickView window; QQuickView window2; window.setSource(testFileUrl("mainWindowQtBug60123.qml")); window2.setSource(testFileUrl("mainWindowQtBug60123.qml")); + // Create central widget for the main window QWidget *baseWidget = new QWidget(&main); - main.resize(400, 200); baseWidget->resize(400, 200); baseWidget->setMaximumHeight(200); baseWidget->setMaximumWidth(400); + main.setCentralWidget(baseWidget); // Create container widgets for both windows QWidget *containers = QWidget::createWindowContainer(&window, baseWidget); - containers->setGeometry(0, 0, 400, 200); - QWidget* containers2 = QWidget::createWindowContainer(&window2, baseWidget); - containers2->setGeometry(50, 50, 300, 150); + QWidget *containers2 = QWidget::createWindowContainer(&window2, baseWidget); + containers->setGeometry(0, 0, 100, 100); + containers2->setGeometry(100, 100, 100, 100); // Show and activate the main window main.show(); - QTest::qWaitForWindowActive(&main); + QVERIFY(QTest::qWaitForWindowExposed(&main)); // Activate window, test press and release events auto activateWindowAndTestPress = [] (QQuickView* testWindow) { testWindow->requestActivate(); - QTest::qWaitForWindowActive(testWindow); + QVERIFY(QTest::qWaitForWindowActive(testWindow)); QTest::mousePress(testWindow, Qt::LeftButton, Qt::NoModifier, QPoint(10, 10)); QCOMPARE(testWindow->rootObject()->property("lastEvent").toString(), QString("pressed")); QTest::mouseRelease(testWindow, Qt::LeftButton, Qt::NoModifier, QPoint(10, 10)); diff --git a/tests/auto/quick/qquicklayouts/data/rowlayout/LayerEnabled.qml b/tests/auto/quick/qquicklayouts/data/rowlayout/LayerEnabled.qml new file mode 100644 index 0000000000..39500cc19d --- /dev/null +++ b/tests/auto/quick/qquicklayouts/data/rowlayout/LayerEnabled.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +Rectangle { + width: 100 + height: 100 + color: "black" + + property alias layout: layout + property alias item1: r1 + + RowLayout { + id: layout + anchors.fill: parent + visible: false + spacing: 0 + + Rectangle { + id: r1 + color: "red" + + layer.enabled: true + + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 763c4cf6e4..07af6a77ac 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -1082,5 +1082,23 @@ Item { // Shouldn't crash upon destroying containerUser. } + + /* + Tests that a layout-managed item that sets layer.enabled to true + still renders something. This is a simpler test case that only + reproduces the issue when the layout that manages it is made visible + after component completion, but QTBUG-63269 has a more complex example + where this (setting visible to true afterwards) isn't necessary. + */ + function test_layerEnabled() { + var component = Qt.createComponent("rowlayout/LayerEnabled.qml"); + compare(component.status, Component.Ready); + + var rootRect = createTemporaryObject(component, container); + verify(rootRect); + rootRect.layout.visible = true; + waitForRendering(rootRect.layout) + compare(rootRect.item1.width, 100) + } } } diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp index fd9fed39b5..fbdd87905b 100644 --- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp +++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp @@ -126,6 +126,8 @@ private slots: void parentErrors(); void rootContext(); + void sourceURLKeepComponent(); + }; Q_DECLARE_METATYPE(QList<QQmlError>) @@ -1388,6 +1390,57 @@ void tst_QQuickLoader::rootContext() QCOMPARE(objectInRootContext.didIt, 2); } +void tst_QQuickLoader::sourceURLKeepComponent() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData(QByteArray( + "import QtQuick 2.0\n" + " Loader { id: loader\n }"), + dataDirectoryUrl()); + + QScopedPointer<QQuickLoader> loader(qobject_cast<QQuickLoader*>(component.create())); + loader->setSource(testFileUrl("/Rect120x60.qml")); + + QVERIFY(loader); + QVERIFY(loader->item()); + QVERIFY(loader->sourceComponent()); + QCOMPARE(loader->progress(), 1.0); + + const QPointer<QQmlComponent> sourceComponent = loader->sourceComponent(); + + //Ensure toggling active status does not recreate component + loader->setActive(false); + QVERIFY(!loader->item()); + QVERIFY(loader->sourceComponent()); + QCOMPARE(sourceComponent.data(), loader->sourceComponent()); + + loader->setActive(true); + QVERIFY(loader->item()); + QVERIFY(loader->sourceComponent()); + QCOMPARE(sourceComponent.data(), loader->sourceComponent()); + + loader->setActive(false); + QVERIFY(!loader->item()); + QVERIFY(loader->sourceComponent()); + QCOMPARE(sourceComponent.data(), loader->sourceComponent()); + + //Ensure changing source url causes component to be recreated when inactive + loader->setSource(testFileUrl("/BlueRect.qml")); + + loader->setActive(true); + QVERIFY(loader->item()); + QVERIFY(loader->sourceComponent()); + + const QPointer<QQmlComponent> newSourceComponent = loader->sourceComponent(); + QVERIFY(sourceComponent.data() != newSourceComponent.data()); + + //Ensure changing source url causes component to be recreated when active + loader->setSource(testFileUrl("/Rect120x60.qml")); + QVERIFY(loader->sourceComponent() != newSourceComponent.data()); + +} + QTEST_MAIN(tst_QQuickLoader) #include "tst_qquickloader.moc" diff --git a/tools/qmlimportscanner/main.cpp b/tools/qmlimportscanner/main.cpp index 5bd66243e6..60e0f1773f 100644 --- a/tools/qmlimportscanner/main.cpp +++ b/tools/qmlimportscanner/main.cpp @@ -53,18 +53,23 @@ QT_USE_NAMESPACE -QStringList g_qmlImportPaths; +namespace { -static inline QString typeLiteral() { return QStringLiteral("type"); } -static inline QString versionLiteral() { return QStringLiteral("version"); } -static inline QString nameLiteral() { return QStringLiteral("name"); } -static inline QString relativePathLiteral() { return QStringLiteral("relativePath"); } -static inline QString pluginsLiteral() { return QStringLiteral("plugins"); } -static inline QString pathLiteral() { return QStringLiteral("path"); } -static inline QString classnamesLiteral() { return QStringLiteral("classnames"); } -static inline QString dependenciesLiteral() { return QStringLiteral("dependencies"); } +QStringList g_qmlImportPaths; -static void printUsage(const QString &appNameIn) +inline QString typeLiteral() { return QStringLiteral("type"); } +inline QString versionLiteral() { return QStringLiteral("version"); } +inline QString nameLiteral() { return QStringLiteral("name"); } +inline QString relativePathLiteral() { return QStringLiteral("relativePath"); } +inline QString pluginsLiteral() { return QStringLiteral("plugins"); } +inline QString pathLiteral() { return QStringLiteral("path"); } +inline QString classnamesLiteral() { return QStringLiteral("classnames"); } +inline QString dependenciesLiteral() { return QStringLiteral("dependencies"); } +inline QString moduleLiteral() { return QStringLiteral("module"); } +inline QString javascriptLiteral() { return QStringLiteral("javascript"); } +inline QString directoryLiteral() { return QStringLiteral("directory"); } + +void printUsage(const QString &appNameIn) { const std::wstring appName = appNameIn.toStdWString(); #ifndef QT_BOOTSTRAPPED @@ -95,9 +100,9 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con QString name = importNode->fileName.toString(); import[nameLiteral()] = name; if (name.endsWith(QLatin1String(".js"))) { - import[typeLiteral()] = QStringLiteral("javascript"); + import[typeLiteral()] = javascriptLiteral(); } else { - import[typeLiteral()] = QStringLiteral("directory"); + import[typeLiteral()] = directoryLiteral(); } import[pathLiteral()] = QDir::cleanPath(path + QLatin1Char('/') + name); @@ -113,7 +118,7 @@ QVariantList findImportsInAst(QQmlJS::AST::UiHeaderItemList *headerItemList, con name.chop(1); // remove trailing "." if (!name.isEmpty()) import[nameLiteral()] = name; - import[typeLiteral()] = QStringLiteral("module"); + import[typeLiteral()] = moduleLiteral(); import[versionLiteral()] = code.mid(importNode->versionToken.offset, importNode->versionToken.length); } @@ -223,7 +228,7 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) for (int i = 0; i < importsCopy.length(); ++i) { QVariantMap import = qvariant_cast<QVariantMap>(importsCopy.at(i)); - if (import.value(typeLiteral()) == QLatin1String("module")) { + if (import.value(typeLiteral()) == moduleLiteral()) { const QPair<QString, QString> paths = resolveImportPath(import.value(nameLiteral()).toString(), import.value(versionLiteral()).toString()); if (!paths.first.isEmpty()) { @@ -242,7 +247,7 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) for (const QString &line : dependencies) { const auto dep = line.splitRef(QLatin1Char(' ')); QVariantMap depImport; - depImport[typeLiteral()] = QStringLiteral("module"); + depImport[typeLiteral()] = moduleLiteral(); depImport[nameLiteral()] = dep[0].toString(); depImport[versionLiteral()] = dep[1].toString(); importsCopy.append(depImport); @@ -255,7 +260,7 @@ QVariantList findPathsForModuleImports(const QVariantList &imports) } // Scan a single qml file for import statements -static QVariantList findQmlImportsInQmlCode(const QString &filePath, const QString &code) +QVariantList findQmlImportsInQmlCode(const QString &filePath, const QString &code) { QQmlJS::Engine engine; QQmlJS::Lexer lexer(&engine); @@ -275,7 +280,7 @@ static QVariantList findQmlImportsInQmlCode(const QString &filePath, const QStri } // Scan a single qml file for import statements -static QVariantList findQmlImportsInQmlFile(const QString &filePath) +QVariantList findQmlImportsInQmlFile(const QString &filePath) { QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { @@ -294,7 +299,7 @@ struct ImportCollector : public QQmlJS::Directives void importFile(const QString &jsfile, const QString &module, int line, int column) override { QVariantMap entry; - entry[typeLiteral()] = QStringLiteral("javascript"); + entry[typeLiteral()] = javascriptLiteral(); entry[pathLiteral()] = jsfile; imports << entry; @@ -307,10 +312,10 @@ struct ImportCollector : public QQmlJS::Directives { QVariantMap entry; if (uri.contains(QLatin1Char('/'))) { - entry[typeLiteral()] = QStringLiteral("directory"); + entry[typeLiteral()] = directoryLiteral(); entry[nameLiteral()] = uri; } else { - entry[typeLiteral()] = QStringLiteral("module"); + entry[typeLiteral()] = moduleLiteral(); entry[nameLiteral()] = uri; entry[versionLiteral()] = version; } @@ -444,7 +449,7 @@ QSet<QString> importModulePaths(const QVariantList &imports) { QVariantMap import = qvariant_cast<QVariantMap>(importVariant); QString path = import.value(pathLiteral()).toString(); QString type = import.value(typeLiteral()).toString(); - if (type == QLatin1String("module") && !path.isEmpty()) + if (type == moduleLiteral() && !path.isEmpty()) ret.insert(QDir(path).canonicalPath()); } return ret; @@ -490,6 +495,8 @@ QVariantList findQmlImportsRecursively(const QStringList &qmlDirs, const QString return ret; } +} // namespace + int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); |