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-10 16:59:31 +0100 |
commit | 4edf7ce7dfad0d86baf0e58d5b95057c8bb7eb05 (patch) | |
tree | c4a3ee7883e9c618bb8fd48f733d7e60f7ffe342 | |
parent | 4491e824ff8a5a1d3b13631ea483bdff51429f94 (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.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 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; |