File indexing completed on 2024-05-19 05:39:08

0001 /*
0002     SPDX-FileCopyrightText: 2001 Waldo Bastian <bastian@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "autostart.h"
0008 
0009 #include "../plasmaautostart/plasmaautostart.h"
0010 
0011 #include <QDir>
0012 #include <QHash>
0013 #include <QStandardPaths>
0014 
0015 AutoStart::AutoStart()
0016     : m_phase(-1)
0017     , m_phasedone(false)
0018 {
0019     loadAutoStartList();
0020 }
0021 
0022 AutoStart::~AutoStart()
0023 {
0024 }
0025 
0026 void AutoStart::setPhase(int phase)
0027 {
0028     if (phase > m_phase) {
0029         m_phase = phase;
0030         m_phasedone = false;
0031     }
0032 }
0033 
0034 void AutoStart::setPhaseDone()
0035 {
0036     m_phasedone = true;
0037 }
0038 
0039 static QString extractName(QString path) // krazy:exclude=passbyvalue
0040 {
0041     int i = path.lastIndexOf(QLatin1Char('/'));
0042     if (i >= 0) {
0043         path = path.mid(i + 1);
0044     }
0045     i = path.lastIndexOf(QLatin1Char('.'));
0046     if (i >= 0) {
0047         path.truncate(i);
0048     }
0049     return path;
0050 }
0051 
0052 void AutoStart::loadAutoStartList()
0053 {
0054     // XDG autostart dirs
0055 
0056     // Make unique list of relative paths
0057     QHash<QString, QString> files;
0058     const QStringList dirs = QStandardPaths::locateAll(QStandardPaths::GenericConfigLocation, QStringLiteral("autostart"), QStandardPaths::LocateDirectory);
0059     for (const QString &dir : dirs) {
0060         const QDir d(dir);
0061         const QStringList fileNames = d.entryList(QStringList() << QStringLiteral("*.desktop"));
0062         for (const QString &file : fileNames) {
0063             if (!files.contains(file)) {
0064                 files.insert(file, d.absoluteFilePath(file));
0065             }
0066         }
0067     }
0068 
0069     for (auto it = files.constBegin(); it != files.constEnd(); ++it) {
0070         PlasmaAutostart config(*it);
0071         if (!config.autostarts(QStringLiteral("KDE"), PlasmaAutostart::CheckAll)) {
0072             continue;
0073         }
0074 
0075         AutoStartItem item;
0076         item.service = *it;
0077         item.name = extractName(it.key());
0078         item.startAfter = config.startAfter();
0079         item.phase = qMax(PlasmaAutostart::BaseDesktop, config.startPhase());
0080         m_startList.append(item);
0081     }
0082 }
0083 
0084 QString AutoStart::startService()
0085 {
0086     if (m_startList.isEmpty()) {
0087         return QString();
0088     }
0089 
0090     while (!m_started.isEmpty()) {
0091         // Check for items that depend on previously started items
0092         QString lastItem = m_started[0];
0093         QMutableListIterator<AutoStartItem> it(m_startList);
0094         while (it.hasNext()) {
0095             const auto &item = it.next();
0096             if (item.phase == m_phase && item.startAfter == lastItem) {
0097                 m_started.prepend(item.name);
0098                 QString service = item.service;
0099                 it.remove();
0100                 return service;
0101             }
0102         }
0103         m_started.removeFirst();
0104     }
0105 
0106     // Check for items that don't depend on anything
0107     QMutableListIterator<AutoStartItem> it(m_startList);
0108     while (it.hasNext()) {
0109         const auto &item = it.next();
0110         if (item.phase == m_phase && item.startAfter.isEmpty()) {
0111             m_started.prepend(item.name);
0112             QString service = item.service;
0113             it.remove();
0114             return service;
0115         }
0116     }
0117 
0118     // Just start something in this phase
0119     it = m_startList;
0120     while (it.hasNext()) {
0121         const auto &item = it.next();
0122         if (item.phase == m_phase) {
0123             m_started.prepend(item.name);
0124             QString service = item.service;
0125             it.remove();
0126             return service;
0127         }
0128     }
0129 
0130     return QString();
0131 }
0132 
0133 QList<AutoStartItem> AutoStart::startList() const
0134 {
0135     QList<AutoStartItem> ret;
0136     for (const auto &asi : m_startList) {
0137         if (asi.phase == m_phase)
0138             ret << asi;
0139     }
0140     return ret;
0141 }