summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernd Weimer <bernd.weimer@pelagicore.com>2020-03-04 17:15:30 +0100
committerBernd Weimer <bernd.weimer@pelagicore.com>2020-03-10 16:59:31 +0100
commit4edf7ce7dfad0d86baf0e58d5b95057c8bb7eb05 (patch)
treec4a3ee7883e9c618bb8fd48f733d7e60f7ffe342
parent4491e824ff8a5a1d3b13631ea483bdff51429f94 (diff)
Delay emitting applicationWasActivated signal
The runtime could be in an indistinct state when the signal was emitted. Now it is possible to shutdown the runtime in the signal handler. Also fixed object lifetime in the in-process runtime. Cherry-picked from 5.13: 03471c7 Fixes: AUTOSUITE-1431 Change-Id: I2782f4d91872c1037462bbce171fa432ed43fb6e Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r--src/manager-lib/applicationmanager.cpp20
-rw-r--r--src/manager-lib/qmlinprocessruntime.cpp17
-rw-r--r--src/manager-lib/qmlinprocessruntime.h1
3 files changed, 18 insertions, 20 deletions
diff --git a/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp
index dc6071d9..2af2d742 100644
--- a/src/manager-lib/applicationmanager.cpp
+++ b/src/manager-lib/applicationmanager.cpp
@@ -620,8 +620,6 @@ bool ApplicationManager::startApplicationInternal(AbstractApplication *app, cons
if (app->isBlocked())
throw Exception("Application %1 is blocked - cannot start").arg( app->id());
- Application* realApp = app->nonAliased();
-
AbstractRuntime *runtime = app->currentRuntime();
auto runtimeManager = runtime ? runtime->manager() : RuntimeFactory::instance()->manager(app->runtimeName());
if (!runtimeManager)
@@ -770,7 +768,7 @@ bool ApplicationManager::startApplicationInternal(AbstractApplication *app, cons
attachRuntime = true;
}
if (!runtime)
- runtime = RuntimeFactory::instance()->create(container, realApp);
+ runtime = RuntimeFactory::instance()->create(container, app->nonAliased());
if (runtime)
emit internalSignals.newRuntimeCreated(runtime);
@@ -810,8 +808,6 @@ bool ApplicationManager::startApplicationInternal(AbstractApplication *app, cons
else if (!app->documentUrl().isNull())
runtime->openDocument(app->documentUrl(), documentMimeType);
- emitActivated(app);
-
qCDebug(LogSystem) << "Starting application" << app->id() << "in container" << containerId
<< "using runtime" << runtimeManager->identifier();
if (!documentUrl.isEmpty())
@@ -819,7 +815,9 @@ bool ApplicationManager::startApplicationInternal(AbstractApplication *app, cons
if (inProcess) {
bool ok = runtime->start();
- if (!ok)
+ if (ok)
+ emitActivated(app);
+ else
runtime->deleteLater();
return ok;
} else {
@@ -827,11 +825,13 @@ bool ApplicationManager::startApplicationInternal(AbstractApplication *app, cons
// Using a state-machine would be one option, but then we would need that state-machine
// object plus the per-app state. Relying on 2 lambdas is the easier choice for now.
- auto doStartInContainer = [realApp, attachRuntime, runtime]() -> bool {
- bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(realApp)
+ auto doStartInContainer = [this, app, attachRuntime, runtime]() -> bool {
+ bool successfullyStarted = attachRuntime ? runtime->attachApplicationToQuickLauncher(app->nonAliased())
: runtime->start();
- if (!successfullyStarted)
- runtime->deleteLater(); // ~Runtime() will clean realApp->m_runtime
+ if (successfullyStarted)
+ emitActivated(app);
+ else
+ runtime->deleteLater(); // ~Runtime() will clean app->nonAliased()->m_runtime
return successfullyStarted;
};
diff --git a/src/manager-lib/qmlinprocessruntime.cpp b/src/manager-lib/qmlinprocessruntime.cpp
index 52f59e5b..c7d7aa9b 100644
--- a/src/manager-lib/qmlinprocessruntime.cpp
+++ b/src/manager-lib/qmlinprocessruntime.cpp
@@ -120,7 +120,6 @@ bool QmlInProcessRuntime::start()
qCDebug(LogSystem) << "Updated Qml import paths:" << m_inProcessQmlEngine->importPathList();
}
- m_componentError = false;
QQmlComponent *component = new QQmlComponent(m_inProcessQmlEngine, m_app->nonAliasedInfo()->absoluteCodeFilePath());
if (!component->isReady()) {
@@ -132,7 +131,7 @@ bool QmlInProcessRuntime::start()
// We are running each application in it's own, separate Qml context.
// This way, we can export an unique ApplicationInterface object for each app
- QQmlContext *appContext = new QQmlContext(m_inProcessQmlEngine->rootContext());
+ QQmlContext *appContext = new QQmlContext(m_inProcessQmlEngine->rootContext(), this);
m_applicationIf = new QmlInProcessApplicationInterface(this);
appContext->setContextProperty(qSL("ApplicationInterface"), m_applicationIf);
connect(m_applicationIf, &QmlInProcessApplicationInterface::quitAcknowledged,
@@ -143,16 +142,17 @@ bool QmlInProcessRuntime::start()
QObject *obj = component->beginCreate(appContext);
- QMetaObject::invokeMethod(this, [component, appContext, obj, this]() {
+ QMetaObject::invokeMethod(this, [component, obj, this]() {
component->completeCreate();
- if (!obj || m_componentError) {
+ delete component;
+ if (!obj) {
qCCritical(LogSystem) << "could not load" << m_app->nonAliasedInfo()->absoluteCodeFilePath() << ": no root object";
- delete obj;
- delete appContext;
- delete m_applicationIf;
- m_applicationIf = nullptr;
finish(3, Am::NormalExit);
} else {
+ if (state() == Am::ShuttingDown) {
+ delete obj;
+ return;
+ }
#if !defined(AM_HEADLESS)
if (!qobject_cast<QmlInProcessApplicationManagerWindow*>(obj)) {
QQuickItem *item = qobject_cast<QQuickItem*>(obj);
@@ -168,7 +168,6 @@ bool QmlInProcessRuntime::start()
openDocument(m_document, QString());
setState(Am::Running);
}
- delete component;
}, Qt::QueuedConnection);
return true;
}
diff --git a/src/manager-lib/qmlinprocessruntime.h b/src/manager-lib/qmlinprocessruntime.h
index f2d57eb6..72a96a09 100644
--- a/src/manager-lib/qmlinprocessruntime.h
+++ b/src/manager-lib/qmlinprocessruntime.h
@@ -100,7 +100,6 @@ private:
QString m_document;
QmlInProcessApplicationInterface *m_applicationIf = nullptr;
- bool m_componentError;
bool m_stopIfNoVisibleSurfaces = false;