diff options
22 files changed, 333 insertions, 9 deletions
diff --git a/src/imports/layouts/qquicklayout.cpp b/src/imports/layouts/qquicklayout.cpp index 7d51ec3ca9..3bfdea5be7 100644 --- a/src/imports/layouts/qquicklayout.cpp +++ b/src/imports/layouts/qquicklayout.cpp @@ -771,8 +771,9 @@ bool QQuickLayout::shouldIgnoreItem(QQuickItem *child, QQuickLayoutAttached *&in void QQuickLayout::checkAnchors(QQuickItem *item) const { - if (QQuickItemPrivate::get(item)->_anchors) - qmlWarning(item) << "Detected anchors on an item that is part of a layout. This is undefined behavior."; + QQuickAnchors *anchors = QQuickItemPrivate::get(item)->_anchors; + if (anchors && anchors->activeDirections()) + qmlWarning(item) << "Detected anchors on an item that is managed by a layout. This is undefined behavior; use Layout.alignment instead."; } void QQuickLayout::itemChange(ItemChange change, const ItemChangeData &value) diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index b2808784a0..f236683506 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1263,6 +1263,8 @@ bool Codegen::visit(CallExpression *ast) switch (base.type) { case Reference::Member: case Reference::Subscript: + case Reference::QmlScopeObject: + case Reference::QmlContextObject: base = base.asLValue(); break; case Reference::Name: @@ -1277,7 +1279,21 @@ bool Codegen::visit(CallExpression *ast) return false; //### Do we really need all these call instructions? can's we load the callee in a temp? - if (base.type == Reference::Member) { + if (base.type == Reference::QmlScopeObject) { + Instruction::CallScopeObjectProperty call; + call.base = base.qmlBase.stackSlot(); + call.name = base.qmlCoreIndex; + call.argc = calldata.argc; + call.argv = calldata.argv; + bytecodeGenerator->addInstruction(call); + } else if (base.type == Reference::QmlContextObject) { + Instruction::CallContextObjectProperty call; + call.base = base.qmlBase.stackSlot(); + call.name = base.qmlCoreIndex; + call.argc = calldata.argc; + call.argv = calldata.argv; + bytecodeGenerator->addInstruction(call); + } else if (base.type == Reference::Member) { if (useFastLookups) { Instruction::CallPropertyLookup call; call.base = base.propertyBase.stackSlot(); diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp index 3a81aca7f6..34953d52ce 100644 --- a/src/qml/compiler/qv4instr_moth.cpp +++ b/src/qml/compiler/qv4instr_moth.cpp @@ -369,6 +369,14 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st d << index << dumpArguments(argc, argv, nFormals); MOTH_END_INSTR(CallGlobalLookup) + MOTH_BEGIN_INSTR(CallScopeObjectProperty) + d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals); + MOTH_END_INSTR(CallScopeObjectProperty) + + MOTH_BEGIN_INSTR(CallContextObjectProperty) + d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals); + MOTH_END_INSTR(CallContextObjectProperty) + MOTH_BEGIN_INSTR(SetExceptionHandler) if (offset) d << ABSOLUTE_OFFSET(); diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 4eeeed1fbc..2d1428bd19 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -105,6 +105,8 @@ QT_BEGIN_NAMESPACE #define INSTR_CallName(op) INSTRUCTION(op, CallName, 3, name, argc, argv) #define INSTR_CallPossiblyDirectEval(op) INSTRUCTION(op, CallPossiblyDirectEval, 2, argc, argv) #define INSTR_CallGlobalLookup(op) INSTRUCTION(op, CallGlobalLookup, 3, index, argc, argv) +#define INSTR_CallScopeObjectProperty(op) INSTRUCTION(op, CallScopeObjectProperty, 4, name, base, argc, argv) +#define INSTR_CallContextObjectProperty(op) INSTRUCTION(op, CallContextObjectProperty, 4, name, base, argc, argv) #define INSTR_SetExceptionHandler(op) INSTRUCTION(op, SetExceptionHandler, 1, offset) #define INSTR_ThrowException(op) INSTRUCTION(op, ThrowException, 0) #define INSTR_GetException(op) INSTRUCTION(op, GetException, 0) @@ -221,6 +223,8 @@ QT_BEGIN_NAMESPACE F(CallName) \ F(CallPossiblyDirectEval) \ F(CallGlobalLookup) \ + F(CallScopeObjectProperty) \ + F(CallContextObjectProperty) \ F(SetExceptionHandler) \ F(ThrowException) \ F(GetException) \ diff --git a/src/qml/debugger/qqmlprofiler_p.h b/src/qml/debugger/qqmlprofiler_p.h index a326bfc4ad..c1038d2f76 100644 --- a/src/qml/debugger/qqmlprofiler_p.h +++ b/src/qml/debugger/qqmlprofiler_p.h @@ -521,11 +521,11 @@ private: QQmlProfiler *profiler; }; -#endif // QT_NO_QML_DEBUGGER +#endif // QT_CONFIG(qml_debug) QT_END_NAMESPACE -#ifndef QT_NO_QML_DEBUGGER +#if QT_CONFIG(qml_debug) Q_DECLARE_METATYPE(QVector<QQmlProfilerData>) Q_DECLARE_METATYPE(QQmlProfiler::LocationHash) diff --git a/src/qml/jit/qv4jit.cpp b/src/qml/jit/qv4jit.cpp index 1ab45d6765..5dc98a591a 100644 --- a/src/qml/jit/qv4jit.cpp +++ b/src/qml/jit/qv4jit.cpp @@ -548,6 +548,32 @@ void BaselineJIT::generate_CallGlobalLookup(int index, int argc, int argv) as->checkException(); } +void BaselineJIT::generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv) +{ + STORE_IP(); + as->prepareCallWithArgCount(5); + as->passInt32AsArg(argc, 4); + as->passRegAsArg(argv, 3); + as->passInt32AsArg(propIdx, 2); + as->passRegAsArg(base, 1); + as->passEngineAsArg(0); + JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlScopeObjectProperty, Assembler::ResultInAccumulator); + as->checkException(); +} + +void BaselineJIT::generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv) +{ + STORE_IP(); + as->prepareCallWithArgCount(5); + as->passInt32AsArg(argc, 4); + as->passRegAsArg(argv, 3); + as->passInt32AsArg(propIdx, 2); + as->passRegAsArg(base, 1); + as->passEngineAsArg(0); + JIT_GENERATE_RUNTIME_CALL(Runtime::method_callQmlContextObjectProperty, Assembler::ResultInAccumulator); + as->checkException(); +} + void BaselineJIT::generate_SetExceptionHandler(int offset) { if (offset) @@ -1087,6 +1113,12 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_BEGIN_INSTR(CallGlobalLookup) MOTH_END_INSTR(CallGlobalLookup) + MOTH_BEGIN_INSTR(CallScopeObjectProperty) + MOTH_END_INSTR(CallScopeObjectProperty) + + MOTH_BEGIN_INSTR(CallContextObjectProperty) + MOTH_END_INSTR(CallContextObjectProperty) + MOTH_BEGIN_INSTR(SetExceptionHandler) addLabel(code - start + offset); MOTH_END_INSTR(SetExceptionHandler) @@ -1288,10 +1320,8 @@ void BaselineJIT::collectLabelsInBytecode() MOTH_BEGIN_INSTR(Ret) MOTH_END_INSTR(Ret) -#ifndef QT_NO_QML_DEBUGGER MOTH_BEGIN_INSTR(Debug) MOTH_END_INSTR(Debug) -#endif // QT_NO_QML_DEBUGGER MOTH_BEGIN_INSTR(LoadQmlContext) MOTH_END_INSTR(LoadQmlContext) diff --git a/src/qml/jit/qv4jit_p.h b/src/qml/jit/qv4jit_p.h index c7ec1700c3..077c2e2177 100644 --- a/src/qml/jit/qv4jit_p.h +++ b/src/qml/jit/qv4jit_p.h @@ -168,6 +168,8 @@ public: void generate_CallName(int name, int argc, int argv) Q_DECL_OVERRIDE; void generate_CallPossiblyDirectEval(int argc, int argv) Q_DECL_OVERRIDE; void generate_CallGlobalLookup(int index, int argc, int argv) Q_DECL_OVERRIDE; + void generate_CallScopeObjectProperty(int propIdx, int base, int argc, int argv) Q_DECL_OVERRIDE; + void generate_CallContextObjectProperty(int propIdx, int base, int argc, int argv) Q_DECL_OVERRIDE; void generate_SetExceptionHandler(int offset) Q_DECL_OVERRIDE; void generate_ThrowException() Q_DECL_OVERRIDE; void generate_GetException() Q_DECL_OVERRIDE; diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index e7a104af66..eb4f6a21fc 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1098,6 +1098,37 @@ ReturnedValue Runtime::method_callValue(ExecutionEngine *engine, const Value &fu return static_cast<const FunctionObject &>(func).call(nullptr, argv, argc); } +ReturnedValue Runtime::method_callQmlScopeObjectProperty(ExecutionEngine *engine, Value *base, + int propertyIndex, Value *argv, int argc) +{ + Scope scope(engine); + ScopedFunctionObject fo(scope, method_loadQmlScopeObjectProperty(engine, *base, propertyIndex, + /*captureRequired*/true)); + if (!fo) { + QString error = QStringLiteral("Property '%1' of scope object is not a function").arg(propertyIndex); + return engine->throwTypeError(error); + } + + QObject *qmlScopeObj = static_cast<QmlContext *>(base)->d()->qml()->scopeObject; + ScopedValue qmlScopeValue(scope, QObjectWrapper::wrap(engine, qmlScopeObj)); + return fo->call(qmlScopeValue, argv, argc); +} + +ReturnedValue Runtime::method_callQmlContextObjectProperty(ExecutionEngine *engine, Value *base, + int propertyIndex, Value *argv, int argc) +{ + Scope scope(engine); + ScopedFunctionObject fo(scope, method_loadQmlContextObjectProperty(engine, *base, propertyIndex, + /*captureRequired*/true)); + if (!fo) { + QString error = QStringLiteral("Property '%1' of context object is not a function").arg(propertyIndex); + return engine->throwTypeError(error); + } + + QObject *qmlContextObj = static_cast<QmlContext *>(base)->d()->qml()->context->contextData()->contextObject; + ScopedValue qmlContextValue(scope, QObjectWrapper::wrap(engine, qmlContextObj)); + return fo->call(qmlContextValue, argv, argc); +} ReturnedValue Runtime::method_construct(ExecutionEngine *engine, const Value &function, Value *argv, int argc) { diff --git a/src/qml/jsruntime/qv4runtimeapi_p.h b/src/qml/jsruntime/qv4runtimeapi_p.h index ea31dfd08b..2956a4a463 100644 --- a/src/qml/jsruntime/qv4runtimeapi_p.h +++ b/src/qml/jsruntime/qv4runtimeapi_p.h @@ -188,6 +188,8 @@ struct ExceptionCheck<void (*)(QV4::NoThrowEngine *, A, B, C)> { F(ReturnedValue, loadQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \ F(ReturnedValue, loadQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, bool captureRequired)) \ F(ReturnedValue, loadQmlIdObject, (ExecutionEngine *engine, const Value &context, uint index)) \ + F(ReturnedValue, callQmlScopeObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \ + F(ReturnedValue, callQmlContextObjectProperty, (ExecutionEngine *engine, Value *base, int propertyIndex, Value *argv, int argc)) \ \ F(void, storeQmlScopeObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \ F(void, storeQmlContextObjectProperty, (ExecutionEngine *engine, const Value &context, int propertyIndex, const Value &value)) \ diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index e248d590f7..d44c219d18 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -840,6 +840,18 @@ QV4::ReturnedValue VME::exec(const FunctionObject *fo, const Value *thisObject, CHECK_EXCEPTION; MOTH_END_INSTR(CallGlobalLookup) + MOTH_BEGIN_INSTR(CallScopeObjectProperty) + STORE_IP(); + acc = Runtime::method_callQmlScopeObjectProperty(engine, stack + base, name, stack + argv, argc); + CHECK_EXCEPTION; + MOTH_END_INSTR(CallScopeObjectProperty) + + MOTH_BEGIN_INSTR(CallContextObjectProperty) + STORE_IP(); + acc = Runtime::method_callQmlContextObjectProperty(engine, stack + base, name, stack + argv, argc); + CHECK_EXCEPTION; + MOTH_END_INSTR(CallContextObjectProperty) + MOTH_BEGIN_INSTR(SetExceptionHandler) exceptionHandler = offset ? code + offset : nullptr; MOTH_END_INSTR(SetExceptionHandler) diff --git a/src/quick/items/qquickanchors.cpp b/src/quick/items/qquickanchors.cpp index 45b405bd82..4367e230bc 100644 --- a/src/quick/items/qquickanchors.cpp +++ b/src/quick/items/qquickanchors.cpp @@ -1324,6 +1324,19 @@ QQuickAnchors::Anchors QQuickAnchors::usedAnchors() const return static_cast<QQuickAnchors::Anchors>(d->usedAnchors); } +Qt::Orientations QQuickAnchors::activeDirections() const +{ + Q_D(const QQuickAnchors); + if (d->fill || d->centerIn) + return Qt::Horizontal | Qt::Vertical; + Qt::Orientations o; + if (d->usedAnchors & QQuickAnchors::Horizontal_Mask) + o |= Qt::Horizontal; + if (d->usedAnchors & QQuickAnchors::Vertical_Mask) + o |= Qt::Vertical; + return o; +} + bool QQuickAnchorsPrivate::checkHValid() const { if (usedAnchors & QQuickAnchors::LeftAnchor && diff --git a/src/quick/items/qquickanchors_p.h b/src/quick/items/qquickanchors_p.h index f00b8b5ba7..bc1e6c10f5 100644 --- a/src/quick/items/qquickanchors_p.h +++ b/src/quick/items/qquickanchors_p.h @@ -174,6 +174,7 @@ public: void resetCenterIn(); Anchors usedAnchors() const; + Qt::Orientations activeDirections() const; bool mirrored(); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp index d403884b4e..ffcee5f56e 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderer.cpp @@ -156,6 +156,7 @@ void QSGSoftwareRenderer::render() m_flushRegion = renderNodes(&painter); qint64 renderTime = renderTimer.elapsed(); + painter.end(); if (m_backingStore != nullptr) m_backingStore->endPaint(); diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index 529cdaf070..4ca5fba7de 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -52,6 +52,7 @@ #include <QtGui/QWindow> #include <QtGui/qpa/qplatformnativeinterface.h> +#include <private/qqmlglobal_p.h> #include <private/qsgtexture_p.h> #include <private/qsgcompressedtexture_p.h> #include <private/qsgcompressedatlastexture_p.h> diff --git a/tests/auto/qml/qqmllanguage/data/thisInQmlScope.qml b/tests/auto/qml/qqmllanguage/data/thisInQmlScope.qml new file mode 100644 index 0000000000..e3c99e70e1 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/thisInQmlScope.qml @@ -0,0 +1,10 @@ +import QtQml 2.2 +QtObject { + property int x: 42 + property int y: 0 + function g(){ + y = this.x; + } + property var f: g + Component.onCompleted: f() +} diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index 03d53b755d..195a9687a8 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -281,6 +281,8 @@ private slots: void lowercaseTypeNames(); + void thisInQmlScope(); + private: QQmlEngine engine; QStringList defaultImportPathList; @@ -4911,6 +4913,19 @@ void tst_qqmllanguage::lowercaseTypeNames() QCOMPARE(qmlRegisterSingletonType<QObject>("Test", 1, 0, "lowerCaseTypeName", nullptr), -1); } +void tst_qqmllanguage::thisInQmlScope() +{ + QQmlEngine engine; + + QQmlComponent component(&engine, testFileUrl("thisInQmlScope.qml")); + QTRY_VERIFY(component.isReady()); + VERIFY_ERRORS(0); + QScopedPointer<QObject> o(component.create()); + QVERIFY(!o.isNull()); + QCOMPARE(o->property("x"), QVariant(42)); + QCOMPARE(o->property("y"), QVariant(42)); +} + QTEST_MAIN(tst_qqmllanguage) #include "tst_qqmllanguage.moc" diff --git a/tests/auto/quick/qquickitem/data/mainWindowQtBug60123.qml b/tests/auto/quick/qquickitem/data/mainWindowQtBug60123.qml new file mode 100644 index 0000000000..eeecd48cb2 --- /dev/null +++ b/tests/auto/quick/qquickitem/data/mainWindowQtBug60123.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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:GPL-EXCEPT$ +** 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. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 400 + height: 200 + color: "white" + property string lastEvent: "" + + Rectangle { + id: buttonRect + width: 50 + height: 50 + color: "black" + + MouseArea { + anchors.fill: parent + onPressed: { + lastEvent = "pressed" + buttonRect.color = "yellow" + } + onReleased: { + lastEvent = "released" + buttonRect.color = "black" + } + onCanceled: { + lastEvent = "canceled" + buttonRect.color = "green" + } + } + } +} diff --git a/tests/auto/quick/qquickitem/qquickitem.pro b/tests/auto/quick/qquickitem/qquickitem.pro index 9aca5926f2..003981d4de 100644 --- a/tests/auto/quick/qquickitem/qquickitem.pro +++ b/tests/auto/quick/qquickitem/qquickitem.pro @@ -11,3 +11,8 @@ TESTDATA = data/* QT += core-private gui-private qml-private quick-private testlib +qtHaveModule(widgets): { + DEFINES += TEST_QTBUG_60123 + QT += widgets +} + diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp index f4434d9d3f..f5e8c6858a 100644 --- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp +++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp @@ -41,6 +41,11 @@ #include "../shared/viewtestutil.h" #include <QSignalSpy> +#ifdef TEST_QTBUG_60123 +#include <QWidget> +#include <QMainWindow> +#endif + class TestItem : public QQuickItem { Q_OBJECT @@ -188,6 +193,10 @@ private slots: void shortcutOverride(); +#ifdef TEST_QTBUG_60123 + void qtBug60123(); +#endif + private: enum PaintOrderOp { @@ -2092,6 +2101,49 @@ void tst_qquickitem::shortcutOverride() QCOMPARE(view.rootObject()->property("shortcutActivationCount").toInt(), 1); } +#ifdef TEST_QTBUG_60123 +void tst_qquickitem::qtBug60123() +{ + QMainWindow main; + + QQuickView window; + QQuickView window2; + window.setSource(testFileUrl("mainWindowQtBug60123.qml")); + window2.setSource(testFileUrl("mainWindowQtBug60123.qml")); + + QWidget *baseWidget = new QWidget(&main); + main.resize(400, 200); + baseWidget->resize(400, 200); + baseWidget->setMaximumHeight(200); + baseWidget->setMaximumWidth(400); + + // 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); + + // Show and activate the main window + main.show(); + QTest::qWaitForWindowActive(&main); + + // Activate window, test press and release events + auto activateWindowAndTestPress = [] (QQuickView* testWindow) { + testWindow->requestActivate(); + QTest::qWaitForWindowActive(testWindow); + QTest::mousePress(testWindow, Qt::LeftButton, 0, QPoint(10, 10)); + QCOMPARE(testWindow->rootObject()->property("lastEvent").toString(), QString("pressed")); + QTest::mouseRelease(testWindow, Qt::LeftButton, 0, QPoint(10, 10)); + QCOMPARE(testWindow->rootObject()->property("lastEvent").toString(), QString("released")); + }; + + // First press after switching focus window resulted in cancelled event + activateWindowAndTestPress(&window); + activateWindowAndTestPress(&window2); + activateWindowAndTestPress(&window); +} +#endif + QTEST_MAIN(tst_qquickitem) #include "tst_qquickitem.moc" diff --git a/tests/auto/quick/qquicklayouts/data/rowlayout/ContainerUser.qml b/tests/auto/quick/qquicklayouts/data/rowlayout/ContainerUser.qml index 8c4757baaa..f6c1199218 100644 --- a/tests/auto/quick/qquicklayouts/data/rowlayout/ContainerUser.qml +++ b/tests/auto/quick/qquicklayouts/data/rowlayout/ContainerUser.qml @@ -57,7 +57,6 @@ Container { Text { objectName: "qtbug51927-text" text: qsTr("Hello World") - anchors.centerIn: parent renderType: Text.QtRendering } } diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml index 4ff1017116..d6231f28fd 100644 --- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml +++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml @@ -1004,5 +1004,67 @@ Item { // Shouldn't crash upon destroying containerUser. } + + + Component { + id: itemsWithAnchorsLayout_Component + RowLayout { + spacing: 2 + Item { + anchors.fill: parent + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.centerIn: parent + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.left: parent.left + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.right: parent.right + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.top: parent.top + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.bottom: parent.bottom + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + implicitWidth: 10 + implicitHeight: 10 + } + Item { + anchors.margins: 42 // although silly, it should not cause a warning from the Layouts POV + implicitWidth: 10 + implicitHeight: 10 + } + } + } + + function test_warnAboutLayoutItemsWithAnchors() + { + var fullPath = Qt.resolvedUrl("tst_rowlayout.qml") + for (var i = 0; i < 7; ++i) { + ignoreWarning(fullPath + ":" + (1013 + 5*i) +":17: QML Item: Detected anchors on an item that is managed by a layout. " + + "This is undefined behavior; use Layout.alignment instead.") + } + var layout = itemsWithAnchorsLayout_Component.createObject(container) + waitForRendering(layout) + layout.destroy() + } + } } diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp index 7c04f69a2b..1751ba2ecf 100644 --- a/tools/qmlcachegen/qmlcachegen.cpp +++ b/tools/qmlcachegen/qmlcachegen.cpp @@ -545,7 +545,7 @@ int main(int argc, char **argv) } else if (inputFile.endsWith(QLatin1String(".js"))) { Error error; if (!compileJSFile(inputFile, inputFileUrl, saveFunction, &error)) { - error.augment(QLatin1String("Error compiling qml file: ")).print(); + error.augment(QLatin1String("Error compiling js file: ")).print(); return EXIT_FAILURE; } } else { |