summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/modules/Unity/Application/application.cpp26
-rw-r--r--src/modules/Unity/Application/application.h3
-rw-r--r--src/modules/Unity/Application/application_manager.cpp10
-rw-r--r--src/modules/Unity/Application/session.cpp18
-rw-r--r--src/modules/Unity/Application/session.h1
-rw-r--r--src/modules/Unity/Application/session_interface.h1
6 files changed, 44 insertions, 15 deletions
diff --git a/src/modules/Unity/Application/application.cpp b/src/modules/Unity/Application/application.cpp
index 06471f7..5104894 100644
--- a/src/modules/Unity/Application/application.cpp
+++ b/src/modules/Unity/Application/application.cpp
@@ -79,7 +79,10 @@ Application::~Application()
wipeQMLCache();
}
- delete m_session;
+ if (m_session) {
+ m_session->setApplication(nullptr);
+ delete m_session;
+ }
delete m_desktopData;
}
@@ -426,6 +429,9 @@ void Application::setSession(SessionInterface *newSession)
if (oldFullscreen != fullscreen())
Q_EMIT fullscreenChanged(fullscreen());
+ } else {
+ // this can only happen after the session has stopped and QML code called Session::release()
+ Q_ASSERT(m_state == InternalState::Stopped || m_state == InternalState::StoppedUnexpectedly);
}
Q_EMIT sessionChanged(m_session);
@@ -521,16 +527,32 @@ void Application::setProcessState(ProcessState newProcessState)
Q_ASSERT(m_state == InternalState::SuspendingWaitProcess);
setInternalState(InternalState::Suspended);
break;
- case ProcessStopped:
+ case ProcessKilled:
// we assume the session always stop before the process
Q_ASSERT(!m_session || m_session->state() == Session::Stopped);
+
if (m_state == InternalState::Starting) {
+ // that was way too soon. let it go away
setInternalState(InternalState::Stopped);
} else {
Q_ASSERT(m_state == InternalState::Stopped
|| m_state == InternalState::StoppedUnexpectedly);
}
break;
+ case ProcessStopped:
+ // we assume the session always stop before the process
+ Q_ASSERT(!m_session || m_session->state() == Session::Stopped);
+
+ if (m_state == InternalState::Starting) {
+ // that was way too soon. let it go away
+ setInternalState(InternalState::Stopped);
+ } else if (m_state == InternalState::StoppedUnexpectedly) {
+ // the application stopped nicely, likely closed itself. Thus not really unexpected after all.
+ setInternalState(InternalState::Stopped);
+ } else {
+ Q_ASSERT(m_state == InternalState::Stopped);
+ }
+ break;
}
applyRequestedState();
diff --git a/src/modules/Unity/Application/application.h b/src/modules/Unity/Application/application.h
index 9344621..24a7a7f 100644
--- a/src/modules/Unity/Application/application.h
+++ b/src/modules/Unity/Application/application.h
@@ -61,6 +61,7 @@ public:
ProcessUnknown,
ProcessRunning,
ProcessSuspended,
+ ProcessKilled, // it stopped, but because it was killed.
ProcessStopped
};
@@ -103,7 +104,7 @@ public:
void setStage(Stage stage);
-
+ ProcessState processState() const { return m_processState; }
void setProcessState(ProcessState value);
QStringList arguments() const { return m_arguments; }
diff --git a/src/modules/Unity/Application/application_manager.cpp b/src/modules/Unity/Application/application_manager.cpp
index ba8bc9a..1aa5b82 100644
--- a/src/modules/Unity/Application/application_manager.cpp
+++ b/src/modules/Unity/Application/application_manager.cpp
@@ -465,7 +465,7 @@ void ApplicationManager::onProcessFailed(const QString &appId, const bool during
}
Q_UNUSED(duringStartup); // FIXME(greyback) upstart reports app that fully started up & crashes as failing during startup??
- application->setProcessState(Application::ProcessStopped);
+ application->setProcessState(Application::ProcessKilled);
application->setPid(0);
}
@@ -481,8 +481,12 @@ void ApplicationManager::onProcessStopped(const QString &appId)
return;
}
- application->setProcessState(Application::ProcessStopped);
- application->setPid(0);
+ // if an application gets killed, onProcessFailed is called first, followed by onProcessStopped.
+ // we don't want to override what onProcessFailed already set.
+ if (application->processState() != Application::ProcessKilled) {
+ application->setProcessState(Application::ProcessStopped);
+ application->setPid(0);
+ }
}
void ApplicationManager::onProcessSuspended(const QString &appId)
diff --git a/src/modules/Unity/Application/session.cpp b/src/modules/Unity/Application/session.cpp
index 033e188..8908b09 100644
--- a/src/modules/Unity/Application/session.cpp
+++ b/src/modules/Unity/Application/session.cpp
@@ -52,6 +52,7 @@ Session::Session(const std::shared_ptr<ms::Session>& session,
, m_fullscreen(false)
, m_state(State::Starting)
, m_live(true)
+ , m_released(false)
, m_suspendTimer(new QTimer(this))
, m_promptSessionManager(promptSessionManager)
{
@@ -96,15 +97,10 @@ void Session::doSuspend()
void Session::release()
{
qCDebug(QTMIR_SESSIONS) << "Session::release " << name();
- Q_EMIT aboutToBeDestroyed();
- if (m_parentSession) {
- m_parentSession->removeChildSession(this);
- }
- if (m_application) {
- m_application->setSession(nullptr);
- }
- if (!parent()) {
+ m_released = true;
+
+ if (m_state == Stopped) {
deleteLater();
}
}
@@ -304,6 +300,9 @@ void Session::stop()
});
setState(Stopped);
+ if (m_released) {
+ deleteLater();
+ }
}
}
@@ -314,6 +313,9 @@ void Session::setLive(const bool live)
Q_EMIT liveChanged(m_live);
if (!live) {
setState(Stopped);
+ if (m_released) {
+ deleteLater();
+ }
}
}
}
diff --git a/src/modules/Unity/Application/session.h b/src/modules/Unity/Application/session.h
index f80d36e..1f9fbb6 100644
--- a/src/modules/Unity/Application/session.h
+++ b/src/modules/Unity/Application/session.h
@@ -105,6 +105,7 @@ private:
bool m_fullscreen;
State m_state;
bool m_live;
+ bool m_released;
QTimer* m_suspendTimer;
QList<std::shared_ptr<mir::scene::PromptSession>> m_promptSessions;
std::shared_ptr<mir::scene::PromptSessionManager> const m_promptSessionManager;
diff --git a/src/modules/Unity/Application/session_interface.h b/src/modules/Unity/Application/session_interface.h
index 819b581..be00893 100644
--- a/src/modules/Unity/Application/session_interface.h
+++ b/src/modules/Unity/Application/session_interface.h
@@ -101,7 +101,6 @@ Q_SIGNALS:
void surfaceChanged(MirSurfaceItemInterface*);
void parentSessionChanged(SessionInterface*);
void applicationChanged(unity::shell::application::ApplicationInfoInterface* application);
- void aboutToBeDestroyed();
void stateChanged(State state);
void fullscreenChanged(bool fullscreen);
void liveChanged(bool live);