diff options
62 files changed, 355 insertions, 245 deletions
diff --git a/dist/changes-5.6.1 b/dist/changes-5.6.1 new file mode 100644 index 0000000000..5a3c9b62e6 --- /dev/null +++ b/dist/changes-5.6.1 @@ -0,0 +1,53 @@ +Qt 5.6.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + http://qt-project.org/doc/qt-5.6 + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + http://bugreports.qt-project.org/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + +* [QTBUG-51746] When matching the method signature of a invokable method to + the slot in the metaobject, the matching function now assigns the best + match to a QJSValue if the parameter actually is a QJSValue. This corrects + the previous behavior, where QJSValue and int were given the same match + score even though QJSValue would have been the best match. +* [QTBUG-50604] Assigning NaN to an Item's x or y previously had the side effect + of making the item invisible (as well as warning about a bad + QTransform::translate call). Setting NaN will now be ignored (as it already + was for width and height), and no longer have any visual effect. +* [QTBUG-51231] TextInput with a non-Normal echoMode can now no longer cut or + copy text. + +**************************************************************************** +* Library * +**************************************************************************** + +QtQuick +----------------- + + - QQuickPaintedItem: When the device pixel ratio is changed for the screen the item is rendered + on then the item will be updated. + - [QTBUG-50085] Canvas: Fix crash when item has a negative width or height. + - [QTBUG-48870] GridView: Don't get "holes" in the grid if model updates occur + frequently. + +QtQml +----- + + - [QTBUG-52065] Fix crash with Array.unshift() + diff --git a/examples/qml/qml.pro b/examples/qml/qml.pro index d5f9fa8a9e..eb4c98e5c4 100644 --- a/examples/qml/qml.pro +++ b/examples/qml/qml.pro @@ -7,6 +7,7 @@ qtHaveModule(quick): SUBDIRS += \ SUBDIRS += \ referenceexamples \ + tutorials \ shell EXAMPLE_FILES = \ diff --git a/examples/qml/qmlextensionplugins/qmlextensionplugins.pro b/examples/qml/qmlextensionplugins/qmlextensionplugins.pro index 64fd23af8d..946626cce7 100644 --- a/examples/qml/qmlextensionplugins/qmlextensionplugins.pro +++ b/examples/qml/qmlextensionplugins/qmlextensionplugins.pro @@ -21,3 +21,5 @@ target.path += $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/TimeExamp pluginfiles.path += $$[QT_INSTALL_EXAMPLES]/qml/qmlextensionplugins/imports/TimeExample INSTALLS += target qml pluginfiles + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro index 0c31592eeb..1ae83f71eb 100644 --- a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.pro @@ -4,9 +4,9 @@ HEADERS += piechart.h SOURCES += piechart.cpp \ main.cpp -RESOURCES += chapter3-binding.qrc +RESOURCES += chapter3-bindings.qrc -DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter3-binding +DESTPATH = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter3-bindings target.path = $$DESTPATH qml.files = *.qml diff --git a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.qrc index f1168aef3b..f1168aef3b 100644 --- a/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-binding.qrc +++ b/examples/qml/tutorials/extending-qml/chapter3-bindings/chapter3-bindings.qrc diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro index 4d0e807417..b340981e42 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/app.pro @@ -13,3 +13,6 @@ osx { SOURCES += main.cpp RESOURCES += app.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/qml/tutorials/extending-qml/chapter6-plugins +INSTALLS += target diff --git a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro index cefcf3b477..5cf4621420 100644 --- a/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro +++ b/examples/qml/tutorials/extending-qml/chapter6-plugins/import/import.pro @@ -20,7 +20,11 @@ qmldir.files=$$PWD/qmldir qmldir.path=$$DESTPATH INSTALLS += target qmldir +CONFIG += install_ok # Do not cargo-cult this! + OTHER_FILES += qmldir # Copy the qmldir file to the same folder as the plugin binary -QMAKE_POST_LINK += $$QMAKE_COPY $$replace($$list($$quote($$PWD/qmldir) $$DESTDIR), /, $$QMAKE_DIR_SEP) +cpqmldir.files = qmldir +cpqmldir.path = $$DESTDIR +COPIES += cpqmldir diff --git a/examples/qml/tutorials/tutorials.pro b/examples/qml/tutorials/tutorials.pro new file mode 100644 index 0000000000..265b3b69cc --- /dev/null +++ b/examples/qml/tutorials/tutorials.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +qtHaveModule(quick): SUBDIRS += \ + extending-qml diff --git a/examples/quick/customitems/painteditem/painteditem.pro b/examples/quick/customitems/painteditem/painteditem.pro index 3ec6420abf..bc7480ab9e 100644 --- a/examples/quick/customitems/painteditem/painteditem.pro +++ b/examples/quick/customitems/painteditem/painteditem.pro @@ -19,5 +19,7 @@ qmldir.path = $$[QT_INSTALL_EXAMPLES]/quick/customitems/painteditem/TextBalloonP INSTALLS += qmldir target +CONFIG += install_ok # Do not cargo-cult this! + OTHER_FILES += \ textballoons.qml diff --git a/examples/quick/imageprovider/imageprovider.pro b/examples/quick/imageprovider/imageprovider.pro index 5567a2d6d9..e54469b0d8 100644 --- a/examples/quick/imageprovider/imageprovider.pro +++ b/examples/quick/imageprovider/imageprovider.pro @@ -13,3 +13,5 @@ target.path = $$[QT_INSTALL_EXAMPLES]/quick/imageprovider/ImageProviderCore qml.files = ImageProviderCore/qmldir qml.path = $$[QT_INSTALL_EXAMPLES]/quick/imageprovider/ImageProviderCore INSTALLS = target qml + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/quick/imageresponseprovider/imageresponseprovider.pro b/examples/quick/imageresponseprovider/imageresponseprovider.pro index 856ddde863..8be4dbb658 100644 --- a/examples/quick/imageresponseprovider/imageresponseprovider.pro +++ b/examples/quick/imageresponseprovider/imageresponseprovider.pro @@ -13,3 +13,5 @@ target.path = $$[QT_INSTALL_EXAMPLES]/quick/imageresponseprovider/ImageResponseP qml.files = ImageResponseProviderCore/qmldir qml.path = $$[QT_INSTALL_EXAMPLES]/quick/imageresponseprovider/ImageResponseProviderCore INSTALLS = target qml + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/quick/quick-accessibility/quick-accessibility.pro b/examples/quick/quick-accessibility/quick-accessibility.pro index 70cf34b54c..cc9d48ac0f 100644 --- a/examples/quick/quick-accessibility/quick-accessibility.pro +++ b/examples/quick/quick-accessibility/quick-accessibility.pro @@ -6,3 +6,6 @@ RESOURCES += accessibility.qrc target.path = $$[QT_INSTALL_EXAMPLES]/quick/quick-accessibility INSTALLS += target + +EXAMPLE_FILES += \ + accessibility.qmlproject diff --git a/examples/quick/quick.pro b/examples/quick/quick.pro index e66e24882e..63730e53da 100644 --- a/examples/quick/quick.pro +++ b/examples/quick/quick.pro @@ -16,6 +16,7 @@ SUBDIRS = quick-accessibility \ scenegraph \ shadereffects \ text \ + textureprovider \ threading \ touchinteraction \ tutorials \ diff --git a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro index 9d70f7aa5a..80216da346 100644 --- a/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro +++ b/examples/quick/quickwidgets/qquickviewcomparison/qquickviewcomparison.pro @@ -15,3 +15,6 @@ HEADERS += mainwindow.h \ RESOURCES += qquickviewcomparison.qrc OTHER_FILES += test.qml + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/quickwidgets/qquickviewcomparison +INSTALLS += target diff --git a/examples/quick/quickwidgets/quickwidget/qtquickwidgets-example.png b/examples/quick/quickwidgets/quickwidget/qtquickwidgets-example.png Binary files differdeleted file mode 100644 index d9e710b7e7..0000000000 --- a/examples/quick/quickwidgets/quickwidget/qtquickwidgets-example.png +++ /dev/null diff --git a/examples/quick/quickwidgets/quickwidget/quickwidget.pro b/examples/quick/quickwidgets/quickwidget/quickwidget.pro index 1aca22082e..04fb5541a7 100644 --- a/examples/quick/quickwidgets/quickwidget/quickwidget.pro +++ b/examples/quick/quickwidgets/quickwidget/quickwidget.pro @@ -6,3 +6,6 @@ TEMPLATE = app SOURCES += main.cpp RESOURCES += quickwidget.qrc + +target.path = $$[QT_INSTALL_EXAMPLES]/quick/quickwidgets/quickwidget +INSTALLS += target diff --git a/examples/quick/scenegraph/graph/graph.pro b/examples/quick/scenegraph/graph/graph.pro index 5991f799dc..1a880b61f1 100644 --- a/examples/quick/scenegraph/graph/graph.pro +++ b/examples/quick/scenegraph/graph/graph.pro @@ -1,9 +1,3 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2013-06-11T13:13:18 -# -#------------------------------------------------- - QT += core gui quick TARGET = graph @@ -32,3 +26,5 @@ OTHER_FILES += \ shaders/line.fsh \ shaders/line.vsh +target.path = $$[QT_INSTALL_EXAMPLES]/quick/scenegraph/graph +INSTALLS += target diff --git a/examples/quick/scenegraph/scenegraph.pro b/examples/quick/scenegraph/scenegraph.pro index 1e7e74372d..cf50cdb903 100644 --- a/examples/quick/scenegraph/scenegraph.pro +++ b/examples/quick/scenegraph/scenegraph.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ customgeometry \ + graph \ openglunderqml \ sgengine \ simplematerial \ @@ -8,3 +9,6 @@ SUBDIRS += \ textureinthread \ threadedanimation \ twotextureproviders + +EXAMPLE_FILES += \ + shared diff --git a/examples/quick/tutorials/gettingStartedQml/filedialog/filedialog.pro b/examples/quick/tutorials/gettingStartedQml/filedialog/filedialog.pro index e88e8f670c..8f8f4549aa 100644 --- a/examples/quick/tutorials/gettingStartedQml/filedialog/filedialog.pro +++ b/examples/quick/tutorials/gettingStartedQml/filedialog/filedialog.pro @@ -18,8 +18,11 @@ SOURCES += \ file.cpp \ dialogPlugin.cpp -OTHER_FILES += qmldir +EXAMPLE_FILES += qmldir # Copy the qmldir file to the same folder as the plugin binary -QMAKE_POST_LINK += $$QMAKE_COPY $$shell_quote($$shell_path($$PWD/qmldir)) \ - $$shell_quote($$shell_path($$DESTDIR)) $$escape_expand(\\n\\t) +cpqmldir.files = $$PWD/qmldir +cpqmldir.path = $$DESTDIR +COPIES += cpqmldir + +CONFIG += install_ok # Do not cargo-cult this! diff --git a/examples/quick/tutorials/gettingStartedQml/gettingStartedQml.pro b/examples/quick/tutorials/gettingStartedQml/gettingStartedQml.pro index 1fc74b69f3..725ff3bbac 100644 --- a/examples/quick/tutorials/gettingStartedQml/gettingStartedQml.pro +++ b/examples/quick/tutorials/gettingStartedQml/gettingStartedQml.pro @@ -7,4 +7,5 @@ EXAMPLE_FILES = \ images \ parts \ pics \ + texteditor.qmlproject \ texteditor.qml diff --git a/examples/quick/window/window.pro b/examples/quick/window/window.pro index be35b24325..c3e9b080bb 100644 --- a/examples/quick/window/window.pro +++ b/examples/quick/window/window.pro @@ -6,7 +6,8 @@ RESOURCES += \ window.qrc \ ../shared/shared.qrc EXAMPLE_FILES = \ - window.qml + window.qml \ + resources target.path = $$[QT_INSTALL_EXAMPLES]/quick/window INSTALLS += target diff --git a/src/imports/builtins/builtins.pro b/src/imports/builtins/builtins.pro new file mode 100644 index 0000000000..112555b6de --- /dev/null +++ b/src/imports/builtins/builtins.pro @@ -0,0 +1,19 @@ +TEMPLATE = aux + +QMLTYPEFILE = builtins.qmltypes + +# install rule +builtins.files = $$QMLTYPEFILE +builtins.path = $$[QT_INSTALL_QML] +INSTALLS += builtins + +# copy to build directory +!prefix_build: COPIES += builtins + +# qmltypes target +!cross_compile:if(build_pass|!debug_and_release) { + qtPrepareTool(QMLPLUGINDUMP, qmlplugindump) + + qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE + QMAKE_EXTRA_TARGETS += qmltypes +} diff --git a/src/imports/builtins.qmltypes b/src/imports/builtins/builtins.qmltypes index cca1c20d54..cca1c20d54 100644 --- a/src/imports/builtins.qmltypes +++ b/src/imports/builtins/builtins.qmltypes diff --git a/src/imports/imports.pro b/src/imports/imports.pro index ff7b6e75af..5332fb0ef2 100644 --- a/src/imports/imports.pro +++ b/src/imports/imports.pro @@ -1,6 +1,7 @@ TEMPLATE = subdirs SUBDIRS += \ + builtins \ qtqml \ folderlistmodel \ localstorage \ @@ -18,35 +19,3 @@ qtHaveModule(quick) { } qtHaveModule(xmlpatterns) : SUBDIRS += xmllistmodel - - -QMLTYPEFILE = builtins.qmltypes - -# install rule -builtins.files = $$QMLTYPEFILE -builtins.path = $$[QT_INSTALL_QML] -INSTALLS += builtins - -# copy to build directory -!force_independent:if(!debug_and_release|!build_all|CONFIG(release, debug|release)) { - defineReplace(qmlModStripSrcDir) { - return($$relative_path($$1, $$_PRO_FILE_PWD_)) - } - - qmltypes2build.input = QMLTYPEFILE - qmltypes2build.output = $$[QT_INSTALL_QML]/${QMAKE_FUNC_FILE_IN_qmlModStripSrcDir} - !contains(TEMPLATE, vc.*): qmltypes2build.variable_out = PRE_TARGETDEPS - qmltypes2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} - qmltypes2build.name = COPY ${QMAKE_FILE_IN} - qmltypes2build.CONFIG = no_link no_clean - - QMAKE_EXTRA_COMPILERS += qmltypes2build -} - -# qmltypes target -!cross_compile:if(build_pass|!debug_and_release) { - qtPrepareTool(QMLPLUGINDUMP, qmlplugindump) - - qmltypes.commands = $$QMLPLUGINDUMP -builtins > $$PWD/$$QMLTYPEFILE - QMAKE_EXTRA_TARGETS += qmltypes -} diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index 9e1c8af3e6..a639cfb71e 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -54,7 +54,6 @@ QT_BEGIN_NAMESPACE Q_QML_DEBUG_PLUGIN_LOADER(QQmlAbstractProfilerAdapter) -Q_QML_IMPORT_DEBUG_PLUGIN(QQuickProfilerAdapterFactory) QQmlProfilerServiceImpl::QQmlProfilerServiceImpl(QObject *parent) : QQmlConfigurableDebugService<QQmlProfilerService>(1, parent), diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index a6d93e85ae..cbde86e389 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -81,8 +81,6 @@ QT_BEGIN_NAMESPACE */ Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugServerConnection) -Q_QML_IMPORT_DEBUG_PLUGIN(QTcpServerConnectionFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QLocalClientConnectionFactory) const int protocolVersion = 1; diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index e6d1a218ad..23440e7529 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -54,14 +54,9 @@ QT_BEGIN_NAMESPACE // Connectors. We could add more plugins here, and distinguish by arguments to instance() Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugConnector) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebugServerFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlNativeDebugConnectorFactory) // Services Q_QML_DEBUG_PLUGIN_LOADER(QQmlDebugService) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlInspectorServiceFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlProfilerServiceFactory) -Q_QML_IMPORT_DEBUG_PLUGIN(QQmlDebuggerServiceFactory) int QQmlDebugConnector::s_dataStreamVersion = QDataStream::Qt_4_7; diff --git a/src/qml/debugger/qqmldebugpluginmanager_p.h b/src/qml/debugger/qqmldebugpluginmanager_p.h index 2bcaf78972..8f52b65b17 100644 --- a/src/qml/debugger/qqmldebugpluginmanager_p.h +++ b/src/qml/debugger/qqmldebugpluginmanager_p.h @@ -74,15 +74,6 @@ QT_BEGIN_NAMESPACE #else // QT_NO_QML_DEBUGGER -#ifdef QT_STATIC -#define Q_QML_IMPORT_DEBUG_PLUGIN(className)\ - QT_END_NAMESPACE\ - Q_IMPORT_PLUGIN(className)\ - QT_BEGIN_NAMESPACE -#else -#define Q_QML_IMPORT_DEBUG_PLUGIN(className) -#endif // QT_STATIC - #define Q_QML_DEBUG_PLUGIN_LOADER(interfaceName)\ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, interfaceName##Loader,\ (interfaceName##Factory_iid, QLatin1String("/qmltooling")))\ diff --git a/src/qml/doc/qtqml.qdocconf b/src/qml/doc/qtqml.qdocconf index 500754ead4..74b61fd6e1 100644 --- a/src/qml/doc/qtqml.qdocconf +++ b/src/qml/doc/qtqml.qdocconf @@ -4,7 +4,7 @@ project = QtQml description = Qt QML Reference Documentation version = $QT_VERSION -examplesinstallpath = qtdeclarative/qml +examplesinstallpath = qml qhp.projects = QtQml diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index f51f677636..2e6773a927 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -247,7 +247,7 @@ struct WithContext : public ExecutionContext V4_MANAGED(WithContext, ExecutionContext) }; -struct QmlContext : public ExecutionContext +struct Q_QML_EXPORT QmlContext : public ExecutionContext { V4_MANAGED(QmlContext, ExecutionContext) diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index bc64bbfe06..b42dc37b0f 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -111,84 +111,6 @@ static ReturnedValue throwTypeError(CallContext *ctx) return ctx->engine()->throwTypeError(); } -const int MinimumStackSize = 256; // in kbytes - -QT_WARNING_PUSH -QT_WARNING_DISABLE_MSVC(4172) // MSVC 2015: warning C4172: returning address of local variable or temporary: dummy - -quintptr getStackLimit() -{ - quintptr stackLimit; -#if USE(PTHREADS) && !OS(QNX) -# if OS(DARWIN) - pthread_t thread_self = pthread_self(); - void *stackTop = pthread_get_stackaddr_np(thread_self); - stackLimit = reinterpret_cast<quintptr>(stackTop); - quintptr size = 0; - if (pthread_main_np()) { - rlimit limit; - getrlimit(RLIMIT_STACK, &limit); - size = limit.rlim_cur; - } else - size = pthread_get_stacksize_np(thread_self); - stackLimit -= size; -# elif defined(__hppa) - // On some architectures the stack grows upwards. All of these are rather exotic, so simply assume - // everything is fine there. - // Known examples: - // -HP PA-RISC - stackLimit = 0; - -# else - pthread_attr_t attr; -#if HAVE(PTHREAD_NP_H) && OS(FREEBSD) - // on FreeBSD pthread_attr_init() must be called otherwise getting the attrs crashes - if (pthread_attr_init(&attr) == 0 && pthread_attr_get_np(pthread_self(), &attr) == 0) { -#else - if (pthread_getattr_np(pthread_self(), &attr) == 0) { -#endif - void *stackBottom = Q_NULLPTR; - size_t stackSize = 0; - - pthread_attr_getstack(&attr, &stackBottom, &stackSize); - pthread_attr_destroy(&attr); - -# if defined(Q_OS_ANDROID) - // Bionic pretends that the main thread has a tiny stack; work around it - if (gettid() == getpid()) { - rlimit limit; - getrlimit(RLIMIT_STACK, &limit); - stackBottom = reinterpret_cast<void*>(reinterpret_cast<quintptr>(stackBottom) + stackSize - limit.rlim_cur); - } -# endif - - stackLimit = reinterpret_cast<quintptr>(stackBottom); - } else { - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024; - } - -# endif -// This is wrong. StackLimit is the currently committed stack size, not the real end. -// only way to get that limit is apparently by using VirtualQuery (Yuck) -//#elif OS(WINDOWS) -// PNT_TIB tib = (PNT_TIB)NtCurrentTeb(); -// stackLimit = static_cast<quintptr>(tib->StackLimit); -#else - int dummy; - // this is inexact, as part of the stack is used when being called here, - // but let's simply default to 1MB from where the stack is right now - // (Note: triggers warning C4172 as of MSVC 2015, returning address of local variable) - stackLimit = reinterpret_cast<qintptr>(&dummy) - 1024*1024; -#endif - - // 256k slack - return stackLimit + MinimumStackSize*1024; -} - -QT_WARNING_POP QJSEngine *ExecutionEngine::jsEngine() const { @@ -200,9 +122,12 @@ QQmlEngine *ExecutionEngine::qmlEngine() const return v8Engine->engine(); } +qint32 ExecutionEngine::maxCallDepth = -1; + ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) : current(0) , hasException(false) + , callDepth(0) , memoryManager(new QV4::MemoryManager(this)) , executableAllocator(new QV4::ExecutableAllocator) , regExpAllocator(new QV4::ExecutableAllocator) @@ -219,6 +144,15 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) , regExpCache(0) , m_multiplyWrappedQObjects(0) { + if (maxCallDepth == -1) { + bool ok = false; + maxCallDepth = qEnvironmentVariableIntValue("QV4_MAX_CALL_DEPTH", &ok); + if (!ok || maxCallDepth <= 0) { + maxCallDepth = 1234; + } + } + Q_ASSERT(maxCallDepth > 0); + MemoryManager::GCBlocker gcBlocker(memoryManager); if (!factory) { @@ -267,9 +201,6 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) // set up stack limits jsStackLimit = jsStackBase + JSStackLimit/sizeof(Value); - cStackLimit = getStackLimit(); - if (!recheckCStackLimits()) - qFatal("Fatal: Not enough stack space available for QML. Please increase the process stack size to more than %d KBytes.", MinimumStackSize); identifierTable = new IdentifierTable(this); @@ -1103,22 +1034,6 @@ QQmlError ExecutionEngine::catchExceptionAsQmlError() return error; } -bool ExecutionEngine::recheckCStackLimits() -{ - int dummy; -#ifdef Q_OS_WIN - // ### this is only required on windows, where we currently use heuristics to get the stack limit - if (cStackLimit - reinterpret_cast<quintptr>(&dummy) > 128*1024) - // we're more then 128k away from our stack limit, assume the thread has changed, and - // call getStackLimit -#endif - // this can happen after a thread change - cStackLimit = getStackLimit(); - - return (reinterpret_cast<quintptr>(&dummy) >= cStackLimit); -} - - // Variant conversion code typedef QSet<QV4::Heap::Object *> V4ObjectSet; diff --git a/src/qml/jsruntime/qv4engine_p.h b/src/qml/jsruntime/qv4engine_p.h index 7da4a1c3c1..73d506c4d2 100644 --- a/src/qml/jsruntime/qv4engine_p.h +++ b/src/qml/jsruntime/qv4engine_p.h @@ -81,15 +81,11 @@ namespace CompiledData { struct CompilationUnit; } -#define CHECK_STACK_LIMITS(v4) \ - if ((v4->jsStackTop <= v4->jsStackLimit) && (reinterpret_cast<quintptr>(&v4) >= v4->cStackLimit || v4->recheckCStackLimits())) {} \ - else \ - return v4->throwRangeError(QStringLiteral("Maximum call stack size exceeded.")) - - struct Q_QML_EXPORT ExecutionEngine { private: + static qint32 maxCallDepth; + friend struct ExecutionContextSaver; friend struct ExecutionContext; friend struct Heap::ExecutionContext; @@ -98,6 +94,7 @@ public: Value *jsStackTop; quint32 hasException; + qint32 callDepth; MemoryManager *memoryManager; ExecutableAllocator *executableAllocator; @@ -107,7 +104,6 @@ public: ExecutionContext *currentContext; Value *jsStackLimit; - quintptr cStackLimit; WTF::BumpPointerAllocator *bumperPointerAllocator; // Used by Yarr Regex engine. @@ -437,8 +433,6 @@ public: InternalClass *newClass(const InternalClass &other); - bool recheckCStackLimits(); - // Exception handling Value *exceptionValue; StackTrace exceptionStackTrace; @@ -471,6 +465,8 @@ public: QV4::ReturnedValue metaTypeToJS(int type, const void *data); void assertObjectBelongsToEngine(const Heap::Base &baseObject); + + bool checkStackLimits(ReturnedValue &exception); }; inline void ExecutionEngine::pushContext(Heap::ExecutionContext *context) @@ -516,7 +512,7 @@ inline Heap::QmlContext *ExecutionEngine::qmlContext() const if (ctx->type == Heap::ExecutionContext::Type_SimpleCallContext && !ctx->outer) ctx = parentContext(currentContext)->d(); - if (!ctx->outer) + if (ctx->type != Heap::ExecutionContext::Type_QmlContext && !ctx->outer) return 0; while (ctx->outer && ctx->outer->type != Heap::ExecutionContext::Type_GlobalContext) @@ -552,7 +548,26 @@ inline void Value::mark(ExecutionEngine *e) o->mark(e); } +#define CHECK_STACK_LIMITS(v4) { ReturnedValue e; if ((v4)->checkStackLimits(e)) return e; } \ + ExecutionEngineCallDepthRecorder _executionEngineCallDepthRecorder(v4); + +struct ExecutionEngineCallDepthRecorder +{ + ExecutionEngine *ee; + ExecutionEngineCallDepthRecorder(ExecutionEngine *e): ee(e) { ++ee->callDepth; } + ~ExecutionEngineCallDepthRecorder() { --ee->callDepth; } +}; + +inline bool ExecutionEngine::checkStackLimits(ReturnedValue &exception) +{ + if (Q_UNLIKELY((jsStackTop > jsStackLimit) || (callDepth >= maxCallDepth))) { + exception = throwRangeError(QStringLiteral("Maximum call stack size exceeded.")); + return true; + } + + return false; +} } // namespace QV4 diff --git a/src/qml/jsruntime/qv4value_p.h b/src/qml/jsruntime/qv4value_p.h index 514bdafb48..a8d9b0fa71 100644 --- a/src/qml/jsruntime/qv4value_p.h +++ b/src/qml/jsruntime/qv4value_p.h @@ -56,11 +56,7 @@ #include "qv4global_p.h" #include <private/qv4heap_p.h> -/* We cannot rely on QT_POINTER_SIZE to be set correctly on host builds. In qmldevtools the Value objects - are only used to store primitives, never object pointers. So we can use the 64-bit encoding. */ -#ifdef V4_BOOTSTRAP -#define QV4_USE_64_BIT_VALUE_ENCODING -#elif QT_POINTER_SIZE == 8 +#if QT_POINTER_SIZE == 8 #define QV4_USE_64_BIT_VALUE_ENCODING #endif diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index fbd2d13e40..2f4d9ec909 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1077,6 +1077,7 @@ struct QmlIncubatorObject : Object { QPointer<QObject> parent; QV4::Value valuemap; QV4::Value statusChanged; + Pointer<Heap::QmlContext> qmlContext; }; } @@ -1191,7 +1192,7 @@ static void QQmlComponent_setQmlParent(QObject *me, QObject *parent) */ -static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value &o, const QV4::Value &v) +static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v) { QV4::Scope scope(engine); QV4::ScopedObject object(scope); @@ -1202,6 +1203,9 @@ static void setInitialProperties(QV4::ExecutionEngine *engine, const QV4::Value if (engine->hasException) return; + QV4::ExecutionContextSaver saver(scope); + engine->pushContext(qmlContext); + while (1) { name = it.nextPropertyNameAsString(val); if (!name) @@ -1275,8 +1279,10 @@ void QQmlComponent::createObject(QQmlV4Function *args) QV4::ScopedValue object(scope, QV4::QObjectWrapper::wrap(v4, rv)); Q_ASSERT(object->isObject()); - if (!valuemap->isUndefined()) - setInitialProperties(v4, object, valuemap); + if (!valuemap->isUndefined()) { + QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext()); + setInitialProperties(v4, qmlContext, object, valuemap); + } d->completeCreate(); @@ -1393,6 +1399,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) if (!valuemap->isUndefined()) r->d()->valuemap = valuemap; + r->d()->qmlContext = v4->qmlContext(); r->d()->parent = parent; QQmlIncubator *incubator = r->d()->incubator.data(); @@ -1406,7 +1413,7 @@ void QQmlComponent::incubateObject(QQmlV4Function *args) } // XXX used by QSGLoader -void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate) +void QQmlComponentPrivate::initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate) { QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine); QV4::ExecutionEngine *v4engine = QV8Engine::getV4(ep->v8engine()); @@ -1416,7 +1423,7 @@ void QQmlComponentPrivate::initializeObjectWithInitialProperties(const QV4::Valu Q_ASSERT(object->as<QV4::Object>()); if (!valuemap.isUndefined()) - setInitialProperties(v4engine, object, valuemap); + setInitialProperties(v4engine, qmlContext, object, valuemap); } QQmlComponentExtension::QQmlComponentExtension(QV4::ExecutionEngine *v4) @@ -1493,6 +1500,7 @@ QQmlComponentExtension::~QQmlComponentExtension() QV4::Heap::QmlIncubatorObject::QmlIncubatorObject(QQmlIncubator::IncubationMode m) : valuemap(QV4::Primitive::undefinedValue()) , statusChanged(QV4::Primitive::undefinedValue()) + , qmlContext(0) { incubator.reset(new QQmlComponentIncubator(this, m)); } @@ -1505,7 +1513,8 @@ void QV4::QmlIncubatorObject::setInitialState(QObject *o) QV4::ExecutionEngine *v4 = engine(); QV4::Scope scope(v4); QV4::ScopedObject obj(scope, QV4::QObjectWrapper::wrap(v4, o)); - setInitialProperties(v4, obj, d()->valuemap); + QV4::Scoped<QV4::QmlContext> qmlCtxt(scope, d()->qmlContext); + setInitialProperties(v4, qmlCtxt, obj, d()->valuemap); } } @@ -1514,6 +1523,8 @@ void QV4::QmlIncubatorObject::markObjects(QV4::Heap::Base *that, QV4::ExecutionE QmlIncubatorObject::Data *o = static_cast<QmlIncubatorObject::Data *>(that); o->valuemap.mark(e); o->statusChanged.mark(e); + if (o->qmlContext) + o->qmlContext->mark(e); Object::markObjects(that, e); } diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index ba2982d76d..039b267433 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -86,7 +86,7 @@ public: QObject *beginCreate(QQmlContextData *); void completeCreate(); - void initializeObjectWithInitialProperties(const QV4::Value &valuemap, QObject *toCreate); + void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate); QQmlTypeData *typeData; virtual void typeDataReady(QQmlTypeData *); diff --git a/src/qml/qml/qqmlcontextwrapper.cpp b/src/qml/qml/qqmlcontextwrapper.cpp index 8613c78f6d..02d7f1f6e3 100644 --- a/src/qml/qml/qqmlcontextwrapper.cpp +++ b/src/qml/qml/qqmlcontextwrapper.cpp @@ -105,14 +105,23 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr QV4::ExecutionEngine *v4 = resource->engine(); QV4::Scope scope(v4); + // In V8 the JS global object would come _before_ the QML global object, + // so simulate that here. + bool hasProp; + QV4::ScopedValue result(scope, v4->globalObject->get(name, &hasProp)); + if (hasProp) { + if (hasProperty) + *hasProperty = hasProp; + return result->asReturnedValue(); + } + if (resource->d()->isNullWrapper) return Object::get(m, name, hasProperty); if (v4->callingQmlContext() != resource->d()->context) return Object::get(m, name, hasProperty); - bool hasProp; - QV4::ScopedValue result(scope, Object::get(m, name, &hasProp)); + result = Object::get(m, name, &hasProp); if (hasProp) { if (hasProperty) *hasProperty = hasProp; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 3f58e4a7e1..29fdf78797 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -964,7 +964,7 @@ struct CachedLoader { } void loadAsync(QQmlTypeLoader *loader, QQmlDataBlob *blob) const { - loader->m_thread->loadWithCachedUnit(blob, unit); + loader->m_thread->loadWithCachedUnitAsync(blob, unit); } }; diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index c81f665ad3..f3d1c4121f 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -671,9 +671,10 @@ int QQmlVMEMetaObject::metaCall(QObject *o, QMetaObject::Call c, int _id, void * } else { QV4::MemberData *md = propertiesAsMemberData(); if (md) { - QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>(); - if (v) - QQml_valueTypeProvider()->readValueType(v->d()->data, a[0], t); + QVariant propertyAsVariant; + if (QV4::VariantObject *v = (md->data() + id)->as<QV4::VariantObject>()) + propertyAsVariant = v->d()->data; + QQml_valueTypeProvider()->readValueType(propertyAsVariant, a[0], t); } } break; diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index 932f7663c3..a56d098717 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -54,6 +54,11 @@ QAccessibleQuickItem::QAccessibleQuickItem(QQuickItem *item) { } +QWindow *QAccessibleQuickItem::window() const +{ + return item()->window(); +} + int QAccessibleQuickItem::childCount() const { return childItems().count(); diff --git a/src/quick/accessible/qaccessiblequickitem_p.h b/src/quick/accessible/qaccessiblequickitem_p.h index d6792b0850..8541734d39 100644 --- a/src/quick/accessible/qaccessiblequickitem_p.h +++ b/src/quick/accessible/qaccessiblequickitem_p.h @@ -66,6 +66,8 @@ class QAccessibleQuickItem : public QAccessibleObject, public QAccessibleActionI public: QAccessibleQuickItem(QQuickItem *item); + QWindow *window() const Q_DECL_OVERRIDE; + QRect rect() const; QRect viewRect() const; diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 131cd758a5..fae2eeae2e 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -4,7 +4,7 @@ project = QtQuick description = Qt Quick Reference Documentation version = $QT_VERSION -examplesinstallpath = qtdeclarative/quick +examplesinstallpath = quick qhp.projects = QtQuick diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index ae138d7ceb..1853a1d948 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -1402,15 +1402,15 @@ void QQuickFlickable::wheelEvent(QWheelEvent *event) break; case Qt::NoScrollPhase: // default phase with an ordinary wheel mouse case Qt::ScrollUpdate: - if (d->scrollingPhase) { + if (d->scrollingPhase) d->pressed = true; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); - } +#ifdef Q_OS_OSX + d->movementEndingTimer.start(MovementEndingTimerInterval, this); +#endif break; case Qt::ScrollEnd: d->pressed = false; d->scrollingPhase = false; - d->movementEndingTimer.start(MovementEndingTimerInterval, this); d->draggingEnding(); event->accept(); returnToBounds(); diff --git a/src/quick/items/qquickloader.cpp b/src/quick/items/qquickloader.cpp index c1126d9b12..63c9558d7a 100644 --- a/src/quick/items/qquickloader.cpp +++ b/src/quick/items/qquickloader.cpp @@ -583,6 +583,7 @@ void QQuickLoader::setSource(QQmlV4Function *args) d->disposeInitialPropertyValues(); d->initialPropertyValues.set(args->v4engine(), ipv); } + d->qmlCallingContext.set(scope.engine, scope.engine->qmlContext()); setSource(sourceUrl, false); // already cleared and set ipv above. } @@ -651,7 +652,8 @@ void QQuickLoaderPrivate::setInitialState(QObject *obj) Q_ASSERT(v4); QV4::Scope scope(v4); QV4::ScopedValue ipv(scope, initialPropertyValues.value()); - d->initializeObjectWithInitialProperties(ipv, obj); + QV4::Scoped<QV4::QmlContext> qmlContext(scope, qmlCallingContext.value()); + d->initializeObjectWithInitialProperties(qmlContext, ipv, obj); } void QQuickLoaderIncubator::statusChanged(Status status) diff --git a/src/quick/items/qquickloader_p_p.h b/src/quick/items/qquickloader_p_p.h index ad05bb00ec..9ef89a74d6 100644 --- a/src/quick/items/qquickloader_p_p.h +++ b/src/quick/items/qquickloader_p_p.h @@ -108,6 +108,7 @@ public: QQmlContext *itemContext; QQuickLoaderIncubator *incubator; QV4::PersistentValue initialPropertyValues; + QV4::PersistentValue qmlCallingContext; bool updatingSize: 1; bool active : 1; bool loadingFromSource : 1; diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index f720513b85..2f43582529 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1103,12 +1103,16 @@ void QQuickWidget::mouseDoubleClickEvent(QMouseEvent *e) void QQuickWidget::showEvent(QShowEvent *) { Q_D(QQuickWidget); - d->updatePending = false; d->createContext(); - if (d->offscreenWindow->openglContext()) + if (d->offscreenWindow->openglContext()) { d->render(true); - else + if (d->updatePending) { + d->updatePending = false; + update(); + } + } else { triggerUpdate(); + } QWindowPrivate *offscreenPrivate = QWindowPrivate::get(d->offscreenWindow); if (!offscreenPrivate->visible) { offscreenPrivate->visible = true; diff --git a/tests/auto/qml/qqmlcomponent/data/callingQmlContext.qml b/tests/auto/qml/qqmlcomponent/data/callingQmlContext.qml new file mode 100644 index 0000000000..8193d0f36c --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/callingQmlContext.qml @@ -0,0 +1,13 @@ +import QtQml 2.0 +import qqmlcomponenttest 1.0 +QtObject { + property Component factory + property QtObject incubatedObject + + Component.onCompleted: { + var incubatorState = factory.incubateObject(null, { value: 42 }) + incubatorState.onStatusChanged = function(status) { + incubatedObject = incubatorState.object + } + } +} diff --git a/tests/auto/qml/qqmlcomponent/data/callingQmlContextComponent.qml b/tests/auto/qml/qqmlcomponent/data/callingQmlContextComponent.qml new file mode 100644 index 0000000000..adf491c87e --- /dev/null +++ b/tests/auto/qml/qqmlcomponent/data/callingQmlContextComponent.qml @@ -0,0 +1,3 @@ +import qqmlcomponenttest 1.0 +CallingContextCheckingClass { +} diff --git a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp index c1e51410c8..83bf783cf4 100644 --- a/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp +++ b/tests/auto/qml/qqmlcomponent/tst_qqmlcomponent.cpp @@ -35,6 +35,7 @@ #include <QtQuick> #include <QtQuick/private/qquickrectangle_p.h> #include <QtQuick/private/qquickmousearea_p.h> +#include <private/qv8engine_p.h> #include <qcolor.h> #include "../../shared/util.h" #include "testhttpserver.h" @@ -111,6 +112,7 @@ private slots: void onDestructionCount(); void recursion(); void recursionContinuation(); + void callingContextForInitialProperties(); private: QQmlEngine engine; @@ -518,6 +520,63 @@ void tst_qqmlcomponent::recursionContinuation() QVERIFY(object->property("success").toBool()); } +class CallingContextCheckingClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(int value READ value WRITE setValue) +public: + CallingContextCheckingClass() + : m_value(0) + {} + + int value() const { return m_value; } + void setValue(int v) { + scopeObject.clear(); + callingContextData.setContextData(0); + + m_value = v; + QJSEngine *jsEngine = qjsEngine(this); + if (!jsEngine) + return; + QV4::ExecutionEngine *v4 = QV8Engine::getV4(jsEngine); + if (!v4) + return; + QV4::Scope scope(v4); + QV4::Scoped<QV4::QmlContext> qmlContext(scope, v4->qmlContext()); + if (!qmlContext) + return; + callingContextData = qmlContext->qmlContext(); + scopeObject = qmlContext->qmlScope(); + } + + int m_value; + QQmlGuardedContextData callingContextData; + QPointer<QObject> scopeObject; +}; + +void tst_qqmlcomponent::callingContextForInitialProperties() +{ + qmlRegisterType<CallingContextCheckingClass>("qqmlcomponenttest", 1, 0, "CallingContextCheckingClass"); + + QQmlComponent testFactory(&engine, testFileUrl("callingQmlContextComponent.qml")); + + QQmlComponent component(&engine, testFileUrl("callingQmlContext.qml")); + QScopedPointer<QObject> root(component.beginCreate(engine.rootContext())); + QVERIFY(!root.isNull()); + root->setProperty("factory", QVariant::fromValue(&testFactory)); + component.completeCreate(); + QTRY_VERIFY(qvariant_cast<QObject *>(root->property("incubatedObject"))); + QObject *o = qvariant_cast<QObject *>(root->property("incubatedObject")); + CallingContextCheckingClass *checker = qobject_cast<CallingContextCheckingClass*>(o); + QVERIFY(checker); + + QVERIFY(!checker->callingContextData.isNull()); + QVERIFY(checker->callingContextData->urlString().endsWith(QStringLiteral("callingQmlContext.qml"))); + + QVERIFY(!checker->scopeObject.isNull()); + QVERIFY(checker->scopeObject->metaObject()->indexOfProperty("incubatedObject") != -1); +} + QTEST_MAIN(tst_qqmlcomponent) #include "tst_qqmlcomponent.moc" diff --git a/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml new file mode 100644 index 0000000000..2ceee2bade --- /dev/null +++ b/tests/auto/qml/qqmlcontext/data/qtbug_53431.qml @@ -0,0 +1,7 @@ +import QtQml 2.0 +QtObject { + property int value: { + console.log("lookup in global object") + return 1 + } +} diff --git a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp index edbf0869e8..e0cde6c86f 100644 --- a/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp +++ b/tests/auto/qml/qqmlcontext/tst_qqmlcontext.cpp @@ -56,6 +56,7 @@ private slots: void refreshExpressions(); void refreshExpressionsCrash(); void refreshExpressionsRootContext(); + void skipExpressionRefresh_qtbug_53431(); void qtbug_22535(); void evalAfterInvalidate(); @@ -637,6 +638,19 @@ void tst_qqmlcontext::refreshExpressionsRootContext() delete o1; } +void tst_qqmlcontext::skipExpressionRefresh_qtbug_53431() +{ + QQmlEngine engine; + QQmlComponent component(&engine, testFileUrl("qtbug_53431.qml")); + QScopedPointer<QObject> object(component.create(0)); + QVERIFY(!object.isNull()); + QCOMPARE(object->property("value").toInt(), 1); + object->setProperty("value", 10); + QCOMPARE(object->property("value").toInt(), 10); + engine.rootContext()->setContextProperty("randomContextProperty", 42); + QCOMPARE(object->property("value").toInt(), 10); +} + void tst_qqmlcontext::qtbug_22535() { QQmlEngine engine; diff --git a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro index 76544aa553..3eeb0008bd 100644 --- a/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro +++ b/tests/auto/qml/qqmlmoduleplugin/plugin.2/plugin.2.pro @@ -6,7 +6,6 @@ DESTDIR = ../imports/org/qtproject/AutoTestQmlPluginType.2 QT += core-private gui-private qml-private -IMPORT_DIR = DESTDIR IMPORT_FILES = \ qmldir diff --git a/tests/auto/qmldevtools/compile/compile.pro b/tests/auto/qmldevtools/compile/compile.pro index 71d91c107d..54430eb668 100644 --- a/tests/auto/qmldevtools/compile/compile.pro +++ b/tests/auto/qmldevtools/compile/compile.pro @@ -5,7 +5,7 @@ force_bootstrap { !build_pass: CONFIG += release } else { QT = core - !build_pass:contains(QT_CONFIG, build_all): CONFIG += release + !build_pass:contains(QT_CONFIG, debug_and_release): CONFIG += release } QT += qmldevtools-private macx:CONFIG -= app_bundle diff --git a/tests/auto/quick/examples/tst_examples.cpp b/tests/auto/quick/examples/tst_examples.cpp index 548b20a80a..233cb33631 100644 --- a/tests/auto/quick/examples/tst_examples.cpp +++ b/tests/auto/quick/examples/tst_examples.cpp @@ -74,15 +74,14 @@ private: tst_examples::tst_examples() { // Add files to exclude here - excludedFiles << "examples/quick/canvas/tiger/tiger.qml"; // QTBUG-26528 excludedFiles << "snippets/qml/listmodel/listmodel.qml"; //Just a ListModel, no root QQuickItem excludedFiles << "examples/quick/demos/photosurface/photosurface.qml"; // root item is Window rather than Item - // Add directories you want excluded here (don't add examples/, because they install to examples/qtdeclarative/) + // Add directories you want excluded here excludedDirs << "shared"; //Not an example - excludedDirs << "quick/text/fonts"; // QTBUG-29004 excludedDirs << "snippets/qml/path"; //No root QQuickItem - excludedDirs << "tutorials/gettingStartedQml"; //C++ example, but no cpp files in root dir + excludedDirs << "examples/qml/qmlextensionplugins"; //Requires special import search path + excludedDirs << "examples/quick/tutorials/gettingStartedQml"; //C++ example, but no cpp files in root dir // These snippets are not expected to run on their own. excludedDirs << "snippets/qml/visualdatamodel_rootindex"; @@ -170,9 +169,8 @@ void tst_examples::namingConvention(const QDir &d) void tst_examples::namingConvention() { QStringList examplesLocations; - examplesLocations << QLibraryInfo::location(QLibraryInfo::ExamplesPath) + QLatin1String("/qtdeclarative"); - examplesLocations << QLibraryInfo::location(QLibraryInfo::ExamplesPath) + QLatin1String("/qtquick"); - examplesLocations << QLibraryInfo::location(QLibraryInfo::ExamplesPath) + QLatin1String("/qtqml"); + examplesLocations << QLibraryInfo::location(QLibraryInfo::ExamplesPath) + QLatin1String("/qml"); + examplesLocations << QLibraryInfo::location(QLibraryInfo::ExamplesPath) + QLatin1String("/quick"); foreach(const QString &examples, examplesLocations) { QDir d(examples); diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp index f19a5ea167..fb8900649f 100644 --- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp @@ -3420,16 +3420,15 @@ void tst_qquicktextinput::focusOnPress() QCOMPARE(textInputObject->hasFocus(), false); QCOMPARE(textInputObject->hasActiveFocus(), false); - QPoint centerPoint(window.width()/2, window.height()/2); Qt::KeyboardModifiers noModifiers = 0; - QTest::mousePress(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&window, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QCOMPARE(textInputObject->hasFocus(), true); QCOMPARE(textInputObject->hasActiveFocus(), true); QCOMPARE(focusSpy.count(), 1); QCOMPARE(activeFocusSpy.count(), 1); QCOMPARE(textInputObject->selectedText(), QString()); - QTest::mouseRelease(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&window, Qt::LeftButton, noModifiers); textInputObject->setFocusOnPress(false); QCOMPARE(textInputObject->focusOnPress(), false); @@ -3443,13 +3442,13 @@ void tst_qquicktextinput::focusOnPress() // Wait for double click timeout to expire before clicking again. QTest::qWait(400); - QTest::mousePress(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&window, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QCOMPARE(textInputObject->hasFocus(), false); QCOMPARE(textInputObject->hasActiveFocus(), false); QCOMPARE(focusSpy.count(), 2); QCOMPARE(activeFocusSpy.count(), 2); - QTest::mouseRelease(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&window, Qt::LeftButton, noModifiers); textInputObject->setFocusOnPress(true); QCOMPARE(textInputObject->focusOnPress(), true); @@ -3459,14 +3458,14 @@ void tst_qquicktextinput::focusOnPress() textInputObject->setProperty("selectOnFocus", true); QTest::qWait(400); - QTest::mousePress(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&window, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QCOMPARE(textInputObject->hasFocus(), true); QCOMPARE(textInputObject->hasActiveFocus(), true); QCOMPARE(focusSpy.count(), 3); QCOMPARE(activeFocusSpy.count(), 3); QCOMPARE(textInputObject->selectedText(), textInputObject->text()); - QTest::mouseRelease(&window, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&window, Qt::LeftButton, noModifiers); } void tst_qquicktextinput::openInputPanel() @@ -3490,23 +3489,22 @@ void tst_qquicktextinput::openInputPanel() QCOMPARE(qApp->inputMethod()->isVisible(), false); // input panel should open on focus - QPoint centerPoint(view.width()/2, view.height()/2); Qt::KeyboardModifiers noModifiers = 0; - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&view, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QVERIFY(input->hasActiveFocus()); QCOMPARE(qApp->focusObject(), input); QCOMPARE(qApp->inputMethod()->isVisible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers); // input panel should be re-opened when pressing already focused TextInput qApp->inputMethod()->hide(); QCOMPARE(qApp->inputMethod()->isVisible(), false); QVERIFY(input->hasActiveFocus()); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&view, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QCOMPARE(qApp->inputMethod()->isVisible(), true); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers); // input panel should stay visible if focus is lost to another text inputor QSignalSpy inputPanelVisibilitySpy(qApp->inputMethod(), SIGNAL(visibleChanged())); @@ -3529,8 +3527,8 @@ void tst_qquicktextinput::openInputPanel() input->setReadOnly(true); input->setFocus(true); QCOMPARE(qApp->inputMethod()->isVisible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&view, Qt::LeftButton, noModifiers); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers); QGuiApplication::processEvents(); QCOMPARE(qApp->inputMethod()->isVisible(), false); @@ -3539,8 +3537,8 @@ void tst_qquicktextinput::openInputPanel() input->setFocus(false); input->setFocus(true); QCOMPARE(qApp->inputMethod()->isVisible(), false); - QTest::mousePress(&view, Qt::LeftButton, noModifiers, centerPoint); - QTest::mouseRelease(&view, Qt::LeftButton, noModifiers, centerPoint); + QTest::mousePress(&view, Qt::LeftButton, noModifiers); + QTest::mouseRelease(&view, Qt::LeftButton, noModifiers); QCOMPARE(qApp->inputMethod()->isVisible(), false); } diff --git a/tests/auto/shared/imports.pri b/tests/auto/shared/imports.pri index 20e9bcb371..9cbf286386 100644 --- a/tests/auto/shared/imports.pri +++ b/tests/auto/shared/imports.pri @@ -1,7 +1,4 @@ -copyimportfiles.input = IMPORT_FILES -copyimportfiles.output = $$DESTDIR/${QMAKE_FILE_IN_BASE}${QMAKE_FILE_EXT} -copyimportfiles.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} -copyimportfiles.CONFIG += no_link_no_clean -copyimportfiles.variable_out = PRE_TARGETDEPS -QMAKE_EXTRA_COMPILERS += copyimportfiles +importfiles.files = $$IMPORT_FILES +importfiles.path = $$DESTDIR +COPIES += importfiles diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp index 7b00eabc28..b47bc14a3e 100644 --- a/tests/benchmarks/qml/creation/tst_creation.cpp +++ b/tests/benchmarks/qml/creation/tst_creation.cpp @@ -96,6 +96,12 @@ public: tst_creation::tst_creation() { qmlRegisterType<TestType>("Qt.test", 1, 0, "TestType"); + + // Ensure QtQuick is loaded and imported. Some benchmark like elements() rely on QQmlMetaType::qmlTypeNames() to + // be populated. + QQmlComponent component(&engine); + component.setData("import QtQuick 2.0\nItem{}", QUrl()); + QScopedPointer<QObject> obj(component.create()); } inline QUrl TEST_FILE(const QString &filename) diff --git a/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro b/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro index 3bedc0ea18..67f9d3b395 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro +++ b/tests/benchmarks/qml/librarymetrics_performance/librarymetrics_performance.pro @@ -7,3 +7,5 @@ macx:CONFIG -= app_bundle CONFIG += release SOURCES += tst_librarymetrics_performance.cpp + +RESOURCES += data diff --git a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp index f76372932b..5513dcb9a7 100644 --- a/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp +++ b/tests/benchmarks/qml/librarymetrics_performance/tst_librarymetrics_performance.cpp @@ -114,7 +114,7 @@ tst_librarymetrics_performance::~tst_librarymetrics_performance() static QUrl testFileUrl(const char * filename) { - return QUrl::fromLocalFile(QString(QLatin1String(filename))); + return QUrl(QLatin1String("qrc:///") + QLatin1String(filename)); } void tst_librarymetrics_performance::metrics_data() diff --git a/tests/benchmarks/qml/qml.pro b/tests/benchmarks/qml/qml.pro index 7969866673..d3ce69c713 100644 --- a/tests/benchmarks/qml/qml.pro +++ b/tests/benchmarks/qml/qml.pro @@ -8,6 +8,7 @@ SUBDIRS += \ qqmlcomponent \ qqmlimage \ qqmlmetaproperty \ + librarymetrics_performance \ # script \ ### FIXME: doesn't build js diff --git a/tests/manual/qmlplugindump/tests/dumper/Dummy/dummy.pro b/tests/manual/qmlplugindump/tests/dumper/Dummy/dummy.pro index 3e690d389f..81975ee01c 100644 --- a/tests/manual/qmlplugindump/tests/dumper/Dummy/dummy.pro +++ b/tests/manual/qmlplugindump/tests/dumper/Dummy/dummy.pro @@ -18,11 +18,9 @@ HEADERS += \ DISTFILES = qmldir !equals(_PRO_FILE_PWD_, $$OUT_PWD) { - copy_qmldir.target = $$OUT_PWD/qmldir - copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir - copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" - QMAKE_EXTRA_TARGETS += copy_qmldir - PRE_TARGETDEPS += $$copy_qmldir.target + cpqmldir.files = qmldir + cpqmldir.path = $$OUT_PWD + COPIES += cpqmldir } qmldir.files = qmldir diff --git a/tests/manual/qmlplugindump/tests/dumper/Imports/imports.pro b/tests/manual/qmlplugindump/tests/dumper/Imports/imports.pro index fe9caea13a..1033c7a28f 100644 --- a/tests/manual/qmlplugindump/tests/dumper/Imports/imports.pro +++ b/tests/manual/qmlplugindump/tests/dumper/Imports/imports.pro @@ -18,11 +18,9 @@ HEADERS += \ DISTFILES = qmldir !equals(_PRO_FILE_PWD_, $$OUT_PWD) { - copy_qmldir.target = $$OUT_PWD/qmldir - copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir - copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" - QMAKE_EXTRA_TARGETS += copy_qmldir - PRE_TARGETDEPS += $$copy_qmldir.target + cpqmldir.files = qmldir + cpqmldir.path = $$OUT_PWD + COPIES += cpqmldir } qmldir.files = qmldir diff --git a/tests/manual/qmlplugindump/tests/dumper/Versions/versions.pro b/tests/manual/qmlplugindump/tests/dumper/Versions/versions.pro index 951f886368..d59470862d 100644 --- a/tests/manual/qmlplugindump/tests/dumper/Versions/versions.pro +++ b/tests/manual/qmlplugindump/tests/dumper/Versions/versions.pro @@ -18,11 +18,9 @@ HEADERS += \ DISTFILES = qmldir !equals(_PRO_FILE_PWD_, $$OUT_PWD) { - copy_qmldir.target = $$OUT_PWD/qmldir - copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir - copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\" - QMAKE_EXTRA_TARGETS += copy_qmldir - PRE_TARGETDEPS += $$copy_qmldir.target + cpqmldir.files = qmldir + cpqmldir.path = $$OUT_PWD + COPIES += cpqmldir } qmldir.files = qmldir |