diff options
author | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-03-04 17:15:30 +0100 |
---|---|---|
committer | Bernd Weimer <bernd.weimer@pelagicore.com> | 2020-03-09 15:44:11 +0100 |
commit | 03471c798ae7b398c9943e9f059aeb934a1216dd (patch) | |
tree | 9ae4faeb9c0de353ddf13afa72385a7496a2685e | |
parent | 377b597e9f208c8ecd8feb731aea47adcbdecb52 (diff) |
Delay emitting applicationWasActivated signalv5.13.2_QtAS5.13
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.
Fixes: AUTOSUITE-1431
Change-Id: I2782f4d91872c1037462bbce171fa432ed43fb6e
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r-- | src/manager-lib/applicationmanager.cpp | 20 | ||||
-rw-r--r-- | src/manager-lib/qmlinprocessruntime.cpp | 17 | ||||
-rw-r--r-- | src/manager-lib/qmlinprocessruntime.h | 1 |
3 files changed, 18 insertions, 20 deletions
diff --git a/src/manager-lib/applicationmanager.cpp b/src/manager-lib/applicationmanager.cpp index b5041055..1dfe29da 100644 --- a/src/manager-lib/applicationmanager.cpp +++ b/src/manager-lib/applicationmanager.cpp @@ -619,8 +619,6 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS 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) @@ -769,7 +767,7 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS attachRuntime = true; } if (!runtime) - runtime = RuntimeFactory::instance()->create(container, realApp); + runtime = RuntimeFactory::instance()->create(container, app->nonAliased()); if (runtime) emit internalSignals.newRuntimeCreated(runtime); @@ -809,8 +807,6 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS 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()) @@ -818,7 +814,9 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS if (inProcess) { bool ok = runtime->start(); - if (!ok) + if (ok) + emitActivated(app); + else runtime->deleteLater(); return ok; } else { @@ -826,11 +824,13 @@ bool ApplicationManager::startApplicationInternal(const QString &appId, const QS // 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 f3ac72d4..cd5e8987 100644 --- a/src/manager-lib/qmlinprocessruntime.cpp +++ b/src/manager-lib/qmlinprocessruntime.cpp @@ -131,7 +131,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()) { @@ -143,7 +142,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, @@ -154,16 +153,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); @@ -179,7 +179,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; |