int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
{
// This flag marks whether a session DBus daemon is installed and run
bool hasUsableSessionBus = true;
// Use another bus instance for detecting, avoid session bus cache in Qt
if (!QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("kdeconnect-test-client")).isConnected()) {
qDebug() << "Default session bus not detected, will use private D-Bus.";
// Unset launchctl env and private dbus addr file, avoid block
DBusHelper::macosUnsetLaunchctlEnv();
QFile privateDBusAddressFile(KdeConnectConfig::instance().privateDBusAddressPath());
if (privateDBusAddressFile.exists())
privateDBusAddressFile.resize(0);
// Update session bus usability state
hasUsableSessionBus = false;
}
// Start daemon
m_splashScreen->showMessage(i18n("Launching daemon") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
// Here we will try to bring our private session D-Bus
if (!hasUsableSessionBus) {
qDebug() << "Launching private session D-Bus.";
DBusHelper::macosUnsetLaunchctlEnv();
DBusHelper::launchDBusDaemon();
// Wait for dbus daemon env
QProcess getLaunchdDBusEnv;
m_splashScreen->showMessage(i18n("Waiting D-Bus") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
int retry = 0;
getLaunchdDBusEnv.setProgram(QStringLiteral("launchctl"));
getLaunchdDBusEnv.setArguments({QStringLiteral("getenv"), QStringLiteral(KDECONNECT_SESSION_DBUS_LAUNCHD_ENV)});
getLaunchdDBusEnv.start();
getLaunchdDBusEnv.waitForFinished();
QString launchdDBusEnv = QString::fromLocal8Bit(getLaunchdDBusEnv.readAllStandardOutput());
if (!launchdDBusEnv.isEmpty() && QDBusConnection::sessionBus().isConnected()) {
qDebug() << "Private D-Bus daemon launched and connected.";
hasUsableSessionBus = true;
} else if (!launchdDBusEnv.isEmpty()) {
// Show a warning and exit
qCritical() << "Invalid " << KDECONNECT_SESSION_DBUS_LAUNCHD_ENV << "env: \"" << launchdDBusEnv << "\"";
QMessageBox::critical(nullptr,
i18n("KDE Connect"),
i18n("Cannot connect to DBus\n"
"KDE Connect will quit"),
QMessageBox::Abort,
QMessageBox::Abort);
} else {
// Show a warning and exit
qCritical() << "Fail to get launchctl" << KDECONNECT_SESSION_DBUS_LAUNCHD_ENV << "env";
QMessageBox::critical(nullptr,
i18n("KDE Connect"),
i18n("Cannot connect to DBus\n"
"KDE Connect will quit"),
QMessageBox::Abort,
QMessageBox::Abort);
return -2;
}
}
// Start kdeconnectd, the daemon will not duplicate when there is already one
if (QFile::exists(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd"))) {
kdeconnectd.setProgram(QCoreApplication::applicationDirPath() + QStringLiteral("/kdeconnectd"));
} else if (QFile::exists(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd"))) {
kdeconnectd.setProgram(QString::fromLatin1(qgetenv("craftRoot")) + QStringLiteral("/../lib/libexec/kdeconnectd"));
} else {
QMessageBox::critical(nullptr, i18n("KDE Connect"), i18n("Cannot find kdeconnectd"), QMessageBox::Abort, QMessageBox::Abort);
return -1;
}
kdeconnectd.startDetached();
m_splashScreen->showMessage(i18n("Loading modules") + QStringLiteral("\n"), Qt::AlignHCenter | Qt::AlignBottom, Qt::white);
return 0;
}
This function is responsible for starting the daemon and waiting for its completion. It first checks if the default session bus is detected, if it is connected, it sets the launchctl env and the daemon to be started and connected. Then it starts the daemon and its detaching process. It returns 0 if the daemon is already running, or a warning message.