diff --git a/startkde/plasma-session/startup.h b/startkde/plasma-session/startup.h --- a/startkde/plasma-session/startup.h +++ b/startkde/plasma-session/startup.h @@ -26,6 +26,7 @@ #include #include +#include #include "autostart.h" @@ -78,18 +79,35 @@ AutoStart m_autoStart; }; +/** + * Launches a process, and waits for the process to start + */ +class StartProcessJob: public KJob +{ + Q_OBJECT +public: + StartProcessJob(const QString &process, + const QStringList &args, + const QProcessEnvironment &additionalEnv = QProcessEnvironment()); + void start() override; +private: + QProcess* m_process; +}; + /** * Launches a process, and waits for the service to appear on the session bus */ class StartServiceJob: public KJob { Q_OBJECT public: - StartServiceJob(const QString &process, const QStringList &args, const QString &serviceId); + StartServiceJob(const QString &process, + const QStringList &args, + const QString &serviceId, + const QProcessEnvironment &additionalEnv = QProcessEnvironment()); void start() override; private: - const QString m_process; - const QStringList m_args; + QProcess* m_process; const QString m_serviceId; }; diff --git a/startkde/plasma-session/startup.cpp b/startkde/plasma-session/startup.cpp --- a/startkde/plasma-session/startup.cpp +++ b/startkde/plasma-session/startup.cpp @@ -203,34 +203,37 @@ QDBusConnection::sessionBus().registerObject(QStringLiteral("/Startup"), QStringLiteral("org.kde.Startup"), this); QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.Startup")); + upAndRunning(QStringLiteral("ksmserver")); const AutoStart autostart; - auto phase0 = new StartupPhase0(autostart, this); - auto phase1 = new StartupPhase1(autostart, this); - auto phase2 = new StartupPhase2(autostart, this); - auto restoreSession = new RestoreSessionJob(); - - // this includes starting kwin (currently) - // forward our arguments into ksmserver to match startplasma expectations - QStringList arguments = qApp->arguments(); - arguments.removeFirst(); - auto ksmserverJob = new StartServiceJob(QStringLiteral("ksmserver"), arguments, QStringLiteral("org.kde.ksmserver")); - - connect(ksmserverJob, &KJob::finished, phase0, &KJob::start); - - connect(phase0, &KJob::finished, phase1, &KJob::start); - - connect(phase1, &KJob::finished, restoreSession, &KJob::start); - connect(restoreSession, &KJob::finished, phase2, &KJob::start); - upAndRunning(QStringLiteral("ksmserver")); + KJob* phase1; + QProcessEnvironment kdedProcessEnv; + kdedProcessEnv.insert(QStringLiteral("KDED_STARTED_BY_KDEINIT"), QStringLiteral("1")); + + const QVector sequence = { + new StartProcessJob(QStringLiteral("kcminit_startup"), {}), + new StartServiceJob(QStringLiteral("kded5"), {}, QStringLiteral("org.kde.kded5"), kdedProcessEnv), + new StartServiceJob(QStringLiteral("ksmserver"), QCoreApplication::instance()->arguments().mid(1), QStringLiteral("org.kde.ksmserver")), + new StartupPhase0(autostart, this), + phase1 = new StartupPhase1(autostart, this), + new RestoreSessionJob(), + new StartupPhase2(autostart, this), + }; + KJob* last = nullptr; + for(KJob* job : sequence) { + if (last) { + connect(last, &KJob::finished, job, &KJob::start); + } + last = job; + } connect(phase1, &KJob::finished, this, []() { NotificationThread *loginSound = new NotificationThread(); connect(loginSound, &NotificationThread::finished, loginSound, &NotificationThread::deleteLater); loginSound->start();}); - connect(phase2, &KJob::finished, this, &Startup::finishStartup); - ksmserverJob->start(); + connect(sequence.last(), &KJob::finished, this, &Startup::finishStartup); + sequence.first()->start(); } void Startup::upAndRunning( const QString& msg ) @@ -408,12 +411,18 @@ } -StartServiceJob::StartServiceJob(const QString &process, const QStringList &args, const QString &serviceId): - KJob(), - m_process(process), - m_args(args), - m_serviceId(serviceId) + +StartServiceJob::StartServiceJob(const QString &process, const QStringList &args, const QString &serviceId, const QProcessEnvironment &additionalEnv) + : KJob() + , m_process(new QProcess(this)) + , m_serviceId(serviceId) { + m_process->setProgram(process); + m_process->setArguments(args); + auto env = QProcessEnvironment::systemEnvironment(); + env.insert(additionalEnv); + m_process->setProcessEnvironment(env); + auto watcher = new QDBusServiceWatcher(serviceId, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this); connect(watcher, &QDBusServiceWatcher::serviceRegistered, this, &StartServiceJob::emitResult); } @@ -425,9 +434,34 @@ emitResult(); return; } - qCDebug(PLASMA_SESSION) << "Starting " << m_process << m_args; - QProcess::startDetached(m_process, m_args); + qCDebug(PLASMA_SESSION) << "Starting " << m_process->program() << m_process->arguments(); + if (!m_process->startDetached()) { + qCWarning(PLASMA_SESSION) << "error starting process" << m_process->program() << m_process->arguments(); + emitResult(); + } } +StartProcessJob::StartProcessJob(const QString &process, const QStringList &args, const QProcessEnvironment &additionalEnv) + : KJob() + , m_process(new QProcess(this)) +{ + m_process->setProgram(process); + m_process->setArguments(args); + auto env = QProcessEnvironment::systemEnvironment(); + env.insert(additionalEnv); + m_process->setProcessEnvironment(env); + + connect(m_process, static_cast(&QProcess::finished), [this](int exitCode) { + qCInfo(PLASMA_SESSION) << "process job " << m_process->program() << "finished with exit code " << exitCode; + emitResult(); + }); +} + +void StartProcessJob::start() +{ + qCDebug(PLASMA_SESSION) << "Starting " << m_process->program() << m_process->arguments(); + + m_process->start(); +} #include "startup.moc" diff --git a/startkde/startplasma-waylandsession.cpp b/startkde/startplasma-waylandsession.cpp --- a/startkde/startplasma-waylandsession.cpp +++ b/startkde/startplasma-waylandsession.cpp @@ -56,9 +56,6 @@ return 2; } - if (!startKDEInit()) - return 3; - if (!startKSMServer(true)) return 4; diff --git a/startkde/startplasma-x11.cpp b/startkde/startplasma-x11.cpp --- a/startkde/startplasma-x11.cpp +++ b/startkde/startplasma-x11.cpp @@ -99,9 +99,6 @@ return 1; } - if (!startKDEInit()) - return 1; - if (!startKSMServer(false)) return 1; diff --git a/startkde/startplasma.cpp b/startkde/startplasma.cpp --- a/startkde/startplasma.cpp +++ b/startkde/startplasma.cpp @@ -327,23 +327,10 @@ } } -bool startKDEInit() +bool startKSMServer(bool wayland) { - // We set LD_BIND_NOW to increase the efficiency of kdeinit. - // kdeinit unsets this variable before loading applications. - const int exitCode = runSync(QStringLiteral(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/start_kdeinit_wrapper"), { QStringLiteral("--kded"), QStringLiteral("+kcminit_startup") }, { QStringLiteral("LD_BIND_NOW=true") }); - if (exitCode != 0) { - messageBox(QStringLiteral("startkde: Could not start kdeinit5. Check your installation.")); - return false; - } - OrgKdeKSplashInterface iface(QStringLiteral("org.kde.KSplash"), QStringLiteral("/KSplash"), QDBusConnection::sessionBus()); iface.setStage(QStringLiteral("kinit")); - return true; -} - -bool startKSMServer(bool wayland) -{ // finally, give the session control to the session manager // see kdebase/ksmserver for the description of the rest of the startup sequence // if the KDEWM environment variable has been set, then it will be used as KDE's