struct Q_QML_EXPORT QQmlDebuggingEnabler
{
+ enum StartMode {
+ DoNotWaitForClient,
+ WaitForClient
+ };
+
QQmlDebuggingEnabler(bool printWarning = true);
- static bool startTcpDebugServer(int port, bool block = false,
+ static bool startTcpDebugServer(int port, StartMode mode = DoNotWaitForClient,
const QString &hostName = QString());
+ static bool connectToLocalDebugger(const QString &socketFileName, bool block = false);
};
// Execute code in constructor before first QQmlEngine is instantiated
#endif
}
- * \a block is true. If \a block is not specified it won't block and if \a hostName isn't specified
- * it will listen on all available interfaces. You can only start one debug server at a time. A
- * debug server may have already been started if the -qmljsdebugger= command line argument was
- * given. This method returns \c true if a new debug server was successfully started, or \c false
- * otherwise.
+/*!
++ * \enum QQmlDebuggingEnabler::StartMode
++ *
++ * Defines the debug server's start behavior. You can interrupt QML engines starting while a debug
++ * client is connecting, in order to set breakpoints in or profile startup code.
++ *
++ * \value DoNotWaitForClient Run any QML engines as usual while the debug services are connecting.
++ * \value WaitForClient If a QML engine starts while the debug services are connecting,
++ * interrupt it until they are done.
++ */
++
++/*!
+ * Enables debugging for QML engines created after calling this function. The debug server will
+ * listen on \a port at \a hostName and block the QML engine until it receives a connection if
- bool QQmlDebuggingEnabler::startTcpDebugServer(int port, bool block, const QString &hostName)
++ * \a mode is \c WaitForClient. If \a mode is not specified it won't block and if \a hostName is not
++ * specified it will listen on all available interfaces. You can only start one debug server at a
++ * time. A debug server may have already been started if the -qmljsdebugger= command line argument
++ * was given. This method returns \c true if a new debug server was successfully started, or
++ * \c false otherwise.
+ */
- return QQmlDebugServerPrivate::enable(StartTcpServerAction(port, port, block, hostName));
++bool QQmlDebuggingEnabler::startTcpDebugServer(int port, StartMode mode, const QString &hostName)
+{
+#ifndef QQML_NO_DEBUG_PROTOCOL
++ return QQmlDebugServerPrivate::enable(StartTcpServerAction(port, port, mode == WaitForClient, hostName));
+#else
+ Q_UNUSED(port);
+ Q_UNUSED(block);
+ Q_UNUSED(hostName);
+ return false;
+#endif
+}
+
+/*!
+ * Enables debugging for QML engines created after calling this function. The debug server will
+ * connect to a debugger waiting on a local socket at the given \a socketFileName and block the QML
+ * engine until the connection is established if \a block is true. If \a block is not specified it
+ * won't block. You can only start one debug server at a time. A debug server may have already been
+ * started if the -qmljsdebugger= command line argument was given. This method returns \c true if a
+ * new debug server was successfully started, or \c false otherwise.
+ */
+bool QQmlDebuggingEnabler::connectToLocalDebugger(const QString &socketFileName, bool block)
+{
+#ifndef QQML_NO_DEBUG_PROTOCOL
+ return QQmlDebugServerPrivate::enable(ConnectToLocalAction(socketFileName, block));
+#else
+ Q_UNUSED(fileName);
+ Q_UNUSED(block);
+ return false;
+#endif
+}
+
void QQmlDebugServer::wakeEngine(QQmlEngine *engine)
{
// to be executed in debugger thread
qmlRegisterType<QQuickPinchArea, 1>(uri, 2, 5,"PinchArea");
qmlRegisterType<QQuickImage, 2>(uri, 2, 5,"Image");
+ qmlRegisterType<QQuickMouseArea, 2>(uri, 2, 5, "MouseArea");
+
+ qmlRegisterType<QQuickText, 6>(uri, 2, 6, "Text");
+ qmlRegisterType<QQuickTextEdit, 6>(uri, 2, 6, "TextEdit");
+ qmlRegisterType<QQuickTextInput, 6>(uri, 2, 6, "TextInput");
+ qmlRegisterUncreatableType<QQuickBasePositioner, 6>(uri, 2, 6, "Positioner",
+ QStringLiteral("Positioner is an abstract type that is only available as an attached property."));
+ qmlRegisterType<QQuickColumn, 6>(uri, 2, 6, "Column");
+ qmlRegisterType<QQuickRow, 6>(uri, 2, 6, "Row");
+ qmlRegisterType<QQuickGrid, 6>(uri, 2, 6, "Grid");
+ qmlRegisterType<QQuickFlow, 6>(uri, 2, 6, "Flow");
}
static void initResources()
{
connect(e, SIGNAL(objectCreated(QObject*,QUrl)),
this, SLOT(checkFinished(QObject*)));
+ // QQmlApplicationEngine also connects quit() to QCoreApplication::quit
+ // but if called before exec() then QCoreApplication::quit does nothing
+ connect(e, SIGNAL(quit()),
+ this, SLOT(quit()));
}
+ bool earlyExit;
+
private:
+ void contain(QObject *o, const QUrl &containPath);
+ void checkForWindow(QObject *o);
+
int expect;
bool haveOne;
exit(2);//Different return code from qFatal
}
}
+
+ void quit() {
+ //Will be checked before calling exec()
+ earlyExit = true;
+ }
+ #ifdef QT_GUI_LIB
+ void onOpenGlContextCreated(QOpenGLContext *context);
+ #endif
};
+ void LoadWatcher::contain(QObject *o, const QUrl &containPath)
+ {
+ QQmlComponent c(qae, containPath);
+ QObject *o2 = c.create();
+ if (!o2)
+ return;
+ checkForWindow(o2);
+ bool success = false;
+ int idx;
+ if ((idx = o2->metaObject()->indexOfProperty("containedObject")) != -1)
+ success = o2->metaObject()->property(idx).write(o2, QVariant::fromValue<QObject*>(o));
+ if (!success)
+ o->setParent(o2); //Set QObject parent, and assume container will react as needed
+ }
+
+ void LoadWatcher::checkForWindow(QObject *o)
+ {
+ #ifdef QT_GUI_LIB
+ if (verboseMode && o->isWindowType() && o->inherits("QQuickWindow")) {
+ connect(o, SIGNAL(openglContextCreated(QOpenGLContext*)),
+ this, SLOT(onOpenGlContextCreated(QOpenGLContext*)));
+ }
+ #else
+ Q_UNUSED(o)
+ #endif // QT_GUI_LIB
+ }
+
+ #ifdef QT_GUI_LIB
+ void LoadWatcher::onOpenGlContextCreated(QOpenGLContext *context)
+ {
+ context->makeCurrent(qobject_cast<QWindow *>(sender()));
+ QOpenGLFunctions functions(context);
+ QByteArray output = "Vendor : ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_VENDOR));
+ output += "\nRenderer: ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_RENDERER));
+ output += "\nVersion : ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_VERSION));
+ output += "\nLanguage: ";
+ output += reinterpret_cast<const char *>(functions.glGetString(GL_SHADING_LANGUAGE_VERSION));
+ puts(output.constData());
+ context->doneCurrent();
+ }
+ #endif // QT_GUI_LIB
+
void quietMessageHandler(QtMsgType type, const QMessageLogContext &ctxt, const QString &msg)
{
Q_UNUSED(ctxt);
continue;//Invalid usage, but just ignore it
dummyDir = argList[i+1];
i++;
+ } else if (arg == QLatin1String("-gles")) {
+ QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
+ } else if (arg == QLatin1String("-software")) {
+ QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
+ } else if (arg == QLatin1String("-desktop")) {
+ QCoreApplication::setAttribute(Qt::AA_UseDesktopOpenGL);
} else {
- //If it ends in .qml, treat it as a file. Else ignore it
- if (arg.endsWith(".qml"))
- files << arg;
+ files << arg;
}
}