[plasma/plasma-workspace] /: [startplasma] Migrate autostart scripts to .desktop files
Henri Chain
null at kde.org
Wed Apr 28 17:02:34 BST 2021
Git commit 93f9ef0304f300dc3952ac9a25cbd82996eec263 by Henri Chain.
Committed on 28/04/2021 at 16:02.
Pushed by hchain into branch 'master'.
[startplasma] Migrate autostart scripts to .desktop files
M +7 -5 doc/kcontrol/autostart/index.docbook
M +1 -1 kcms/autostart/CMakeLists.txt
M +59 -72 kcms/autostart/autostartmodel.cpp
M +7 -2 kcms/autostart/autostartmodel.h
M +5 -2 kcms/autostart/package/contents/ui/main.qml
M +2 -0 libkworkspace/CMakeLists.txt
A +34 -0 libkworkspace/autostartscriptdesktopfile.cpp [License: LGPL(v2.1+)]
A +32 -0 libkworkspace/autostartscriptdesktopfile.h [License: LGPL(v2.1+)]
M +10 -38 startkde/plasma-session/startup.cpp
M +48 -0 startkde/startplasma.cpp
M +1 -0 startkde/startplasma.h
https://invent.kde.org/plasma/plasma-workspace/commit/93f9ef0304f300dc3952ac9a25cbd82996eec263
diff --git a/doc/kcontrol/autostart/index.docbook b/doc/kcontrol/autostart/index.docbook
index e5e7ed442..240f79ed0 100644
--- a/doc/kcontrol/autostart/index.docbook
+++ b/doc/kcontrol/autostart/index.docbook
@@ -31,8 +31,10 @@
<note><para>Please note that in this module all changes are immediately applied.</para></note>
-<para>The program scans <filename>$HOME/.config/autostart/</filename>,
-<filename class="directory">$HOME/.config/plasma-workspace/env</filename> and <filename class="directory">$HOME/.config/plasma-workspace/shutdown</filename> folders to check what programs and scripts are already there and displays them. It allows you to manage them easily.
+<para>The program scans <filename>$HOME/.config/autostart/</filename> for applications and login scripts, <filename class="directory">$HOME/.config/plasma-workspace/env</filename> for pre-startup scripts and <filename class="directory">$HOME/.config/plasma-workspace/shutdown</filename> for logout scripts to check what programs and scripts are already there and displays them. It allows you to manage them easily.
+</para>
+
+<para>Login scripts are <filename class="extension">.desktop</filename> files with a <literal>X-KDE-AutostartScript=true</literal> key. Pre-startup scripts are run earlier and can be used to set environment variables.
</para>
<note><para>Note that you can change the location of your <filename class="directory">Autostart</filename>
@@ -87,10 +89,10 @@ This column shows the name of the program or script you want to start with &plas
<varlistentry><term><guilabel>Properties</guilabel></term>
<listitem>
<para>
-This button is only shown when you hover the item with the mouse pointer. The button (only enabled for programs &ie; <filename class="extension">.desktop</filename> files) allows you to change the properties of the program or script. You have general properties, permissions properties, a preview when applicable, and properties related to the application for programs. The default command is extracted from the <filename class="extension">.desktop</filename> file from the <literal>Exec</literal> key.
+This button is only shown when you hover the item with the mouse pointer. The button (only enabled for programs and login scripts &ie; <filename class="extension">.desktop</filename> files) allows you to change the properties of the program or script. You have general properties, permissions properties, a preview when applicable, and properties related to the application or login script. The default command is extracted from the <filename class="extension">.desktop</filename> file from the <literal>Exec</literal> key.
</para>
<para>
-For a script, the command is the path to the script and can not be modified.
+For a logout script, the command is the path to the script and can not be modified.
</para>
</listitem>
</varlistentry>
@@ -126,7 +128,7 @@ This will copy the program <filename class="extension">.desktop</filename> file
<varlistentry><term><guimenuitem>Add Login Script...</guimenuitem></term>
<listitem>
<para>
-This item opens a dialog that asks you for the location of the script you want to add. Scripts set to run on login are copied or symlinked in <filename class="directory">$HOME/.config/autostart</filename> and will be run during Plasma startup.
+This item opens a dialog that asks you for the location of the script you want to add. Scripts set to run on login will have a corresponding <filename class="extension">.desktop</filename> file created in your <filename class="directory">Autostart</filename> folder and will be run during Plasma startup.
</para>
</listitem>
</varlistentry>
diff --git a/kcms/autostart/CMakeLists.txt b/kcms/autostart/CMakeLists.txt
index 93644f68c..f36f4d742 100644
--- a/kcms/autostart/CMakeLists.txt
+++ b/kcms/autostart/CMakeLists.txt
@@ -7,7 +7,7 @@ set(kcm_autostart_PART_SRCS
add_library(kcm_autostart MODULE ${kcm_autostart_PART_SRCS})
-target_link_libraries(kcm_autostart KF5::I18n KF5::KIOCore KF5::KIOWidgets KF5::QuickAddons)
+target_link_libraries(kcm_autostart KF5::I18n KF5::KIOCore KF5::KIOWidgets KF5::QuickAddons PW::KWorkspace)
kcoreaddons_desktop_to_json(kcm_autostart "package/metadata.desktop")
diff --git a/kcms/autostart/autostartmodel.cpp b/kcms/autostart/autostartmodel.cpp
index 94d800c84..777e2b3f0 100644
--- a/kcms/autostart/autostartmodel.cpp
+++ b/kcms/autostart/autostartmodel.cpp
@@ -34,16 +34,15 @@
#include <KLocalizedString>
#include <KOpenWithDialog>
#include <KPropertiesDialog>
-
-#include <optional>
+#include <autostartscriptdesktopfile.h>
// FDO user autostart directories are
-// .config/autostart which has .desktop files executed by klaunch
+// .config/autostart which has .desktop files executed by klaunch or systemd, some of which might be scripts
// Then we have Plasma-specific locations which run scripts
-// .config/autostart-scripts which has scripts executed by ksmserver
-// .config/plasma-workspace/shutdown which has scripts executed by startkde
-// .config/plasma-workspace/env which has scripts executed by startkde
+// .config/autostart-scripts which has scripts executed by plasma_session (now migrated to .desktop files)
+// .config/plasma-workspace/shutdown which has scripts executed by plasma-shutdown
+// .config/plasma-workspace/env which has scripts executed by startplasma
// in the case of pre-startup they have to end in .sh
// everywhere else it doesn't matter
@@ -52,7 +51,7 @@
// share/autostart shouldn't be an option as this should be reserved for global autostart entries
-static std::optional<AutostartEntry> loadDesktopEntry(const QString &fileName)
+std::optional<AutostartEntry> AutostartModel::loadDesktopEntry(const QString &fileName)
{
KDesktopFile config(fileName);
const KConfigGroup grp = config.desktopGroup();
@@ -75,7 +74,7 @@ static std::optional<AutostartEntry> loadDesktopEntry(const QString &fileName)
const auto lstEntry = grp.readXdgListEntry("OnlyShowIn");
const bool onlyInPlasma = lstEntry.contains(QLatin1String("KDE"));
const QString iconName = config.readIcon();
-
+ const auto kind = AutostartScriptDesktopFile::isAutostartScript(config) ? XdgScripts : XdgAutoStart; // .config/autostart load desktop at startup
const QString tryCommand = grp.readEntry("TryExec");
// Try to filter out entries that point to nonexistant programs
@@ -85,38 +84,28 @@ static std::optional<AutostartEntry> loadDesktopEntry(const QString &fileName)
return {};
}
- return std::optional<AutostartEntry>({name,
- AutostartModel::AutostartEntrySource::XdgAutoStart, // .config/autostart load desktop at startup
- enabled,
- fileName,
- onlyInPlasma,
- iconName});
+ return AutostartEntry{name, kind, enabled, fileName, onlyInPlasma, iconName};
}
AutostartModel::AutostartModel(QObject *parent)
: QAbstractListModel(parent)
+ , m_xdgConfigPath(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation))
+ , m_xdgAutoStartPath(m_xdgConfigPath.filePath(QStringLiteral("autostart")))
{
}
-QString AutostartModel::XdgAutoStartPath() const
-{
- return QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QLatin1String("/autostart/");
-}
-
void AutostartModel::load()
{
beginResetModel();
m_entries.clear();
- QDir autostartdir(XdgAutoStartPath());
- if (!autostartdir.exists()) {
- autostartdir.mkpath(XdgAutoStartPath());
- }
-
- autostartdir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
+ // Creates if doesn't already exist
+ m_xdgAutoStartPath.mkpath(QStringLiteral("."));
- const auto filesInfo = autostartdir.entryInfoList();
+ // Needed to add all script entries after application entries
+ QVector<AutostartEntry> scriptEntries;
+ const auto filesInfo = m_xdgAutoStartPath.entryInfoList(QDir::Files);
for (const QFileInfo &fi : filesInfo) {
if (!KDesktopFile::isDesktopFile(fi.fileName())) {
continue;
@@ -128,12 +117,16 @@ void AutostartModel::load()
continue;
}
- m_entries.push_back(entry.value());
+ if (entry->source == XdgScripts) {
+ scriptEntries.push_back(entry.value());
+ } else {
+ m_entries.push_back(entry.value());
+ }
}
- loadScriptsFromDir(QStringLiteral("/autostart-scripts/"), AutostartModel::AutostartEntrySource::XdgScripts);
- // Treat them as XdgScripts so they appear together in the UI
- loadScriptsFromDir(QStringLiteral("/plasma-workspace/env/"), AutostartModel::AutostartEntrySource::XdgScripts);
+ m_entries.append(scriptEntries);
+
+ loadScriptsFromDir(QStringLiteral("/plasma-workspace/env/"), AutostartModel::AutostartEntrySource::PlasmaEnvScripts);
loadScriptsFromDir(QStringLiteral("/plasma-workspace/shutdown/"), AutostartModel::AutostartEntrySource::PlasmaShutdown);
@@ -142,15 +135,11 @@ void AutostartModel::load()
void AutostartModel::loadScriptsFromDir(const QString &subDir, AutostartModel::AutostartEntrySource kind)
{
- const QString path = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + subDir;
- QDir dir(path);
- if (!dir.exists()) {
- dir.mkpath(path);
- }
+ QDir dir(m_xdgConfigPath.filePath(subDir));
+ // Creates if doesn't already exist
+ dir.mkpath(QStringLiteral("."));
- dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);
-
- const auto autostartDirFilesInfo = dir.entryInfoList();
+ const auto autostartDirFilesInfo = dir.entryInfoList(QDir::Files);
for (const QFileInfo &fi : autostartDirFilesInfo) {
QString fileName = fi.absoluteFilePath();
const bool isSymlink = fi.isSymLink();
@@ -223,7 +212,7 @@ void AutostartModel::addApplication(const KService::Ptr &service)
// https://bugs.launchpad.net/ubuntu/+source/kde-workspace/+bug/923360
if (service->desktopEntryName().isEmpty() || service->entryPath().isEmpty()) {
// create a new desktop file in s_desktopPath
- desktopPath = XdgAutoStartPath() + service->name() + QStringLiteral(".desktop");
+ desktopPath = m_xdgAutoStartPath.filePath(service->name() + QStringLiteral(".desktop"));
KDesktopFile desktopFile(desktopPath);
KConfigGroup kcg = desktopFile.desktopGroup();
@@ -236,7 +225,7 @@ void AutostartModel::addApplication(const KService::Ptr &service)
desktopFile.sync();
} else {
- desktopPath = XdgAutoStartPath() + service->desktopEntryName() + QStringLiteral(".desktop");
+ desktopPath = m_xdgAutoStartPath.filePath(service->desktopEntryName() + QStringLiteral(".desktop"));
QFile::remove(desktopPath);
@@ -320,8 +309,6 @@ void AutostartModel::addScript(const QUrl &url, AutostartModel::AutostartEntrySo
}
const QString fileName = url.fileName();
- int index = 0;
- QString folder;
if (kind == AutostartModel::AutostartEntrySource::XdgScripts) {
int lastLoginScript = -1;
@@ -332,44 +319,44 @@ void AutostartModel::addScript(const QUrl &url, AutostartModel::AutostartEntrySo
++lastLoginScript;
}
- index = lastLoginScript + 1;
- folder = QStringLiteral("/autostart-scripts/");
+ AutostartScriptDesktopFile desktopFile(fileName, file.filePath());
+ insertScriptEntry(lastLoginScript + 1, fileName, desktopFile.fileName(), kind);
} else if (kind == AutostartModel::AutostartEntrySource::PlasmaShutdown) {
- index = m_entries.size();
- folder = QStringLiteral("/plasma-workspace/shutdown/");
+ const QUrl destinationScript = QUrl::fromLocalFile(QDir(m_xdgConfigPath.filePath(QStringLiteral("/plasma-workspace/shutdown/"))).filePath(fileName));
+ KIO::CopyJob *job = KIO::link(url, destinationScript, KIO::HideProgressInfo);
+ job->setAutoRename(true);
+ job->setProperty("finalUrl", destinationScript);
+
+ connect(job, &KIO::CopyJob::renamed, this, [](KIO::Job *job, const QUrl &from, const QUrl &to) {
+ Q_UNUSED(from)
+ // in case the destination filename had to be renamed
+ job->setProperty("finalUrl", to);
+ });
+
+ connect(job, &KJob::finished, this, [this, url, kind](KJob *theJob) {
+ if (theJob->error()) {
+ qWarning() << "Could not add script entry" << theJob->errorString();
+ return;
+ }
+ const QUrl dest = theJob->property("finalUrl").toUrl();
+ insertScriptEntry(m_entries.size(), dest.fileName(), dest.path(), kind);
+ });
+
+ job->start();
} else {
Q_ASSERT(0);
}
+}
- QUrl destinationScript = QUrl::fromLocalFile(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + folder + fileName);
- KIO::CopyJob *job = KIO::link(url, destinationScript, KIO::HideProgressInfo);
- job->setAutoRename(true);
- job->setProperty("finalUrl", destinationScript);
-
- connect(job, &KIO::CopyJob::renamed, this, [](KIO::Job *job, const QUrl &from, const QUrl &to) {
- Q_UNUSED(from)
- // in case the destination filename had to be renamed
- job->setProperty("finalUrl", to);
- });
-
- connect(job, &KJob::finished, this, [this, index, url, kind](KJob *theJob) {
- if (theJob->error()) {
- qWarning() << "Could add script entry" << theJob->errorString();
- return;
- }
-
- beginInsertRows(QModelIndex(), index, index);
-
- const QUrl dest = theJob->property("finalUrl").toUrl();
-
- AutostartEntry entry = AutostartEntry{dest.fileName(), kind, true, dest.path(), false, QStringLiteral("dialog-scripts")};
+void AutostartModel::insertScriptEntry(int index, const QString &name, const QString &path, AutostartEntrySource kind)
+{
+ beginInsertRows(QModelIndex(), index, index);
- m_entries.insert(index, entry);
+ AutostartEntry entry = AutostartEntry{name, kind, true, path, false, QStringLiteral("dialog-scripts")};
- endInsertRows();
- });
+ m_entries.insert(index, entry);
- job->start();
+ endInsertRows();
}
void AutostartModel::removeEntry(int row)
diff --git a/kcms/autostart/autostartmodel.h b/kcms/autostart/autostartmodel.h
index 201725d5f..f12909f76 100644
--- a/kcms/autostart/autostartmodel.h
+++ b/kcms/autostart/autostartmodel.h
@@ -20,8 +20,10 @@
#define AUTOSTARTMODEL_H
#include <QAbstractListModel>
+#include <QDir>
#include <KService>
+#include <optional>
struct AutostartEntry;
class QQuickItem;
@@ -46,7 +48,7 @@ public:
XdgAutoStart = 0,
XdgScripts = 1,
PlasmaShutdown = 2,
- PlasmaStart = 3,
+ PlasmaEnvScripts = 3,
};
Q_ENUM(AutostartEntrySource)
@@ -69,8 +71,11 @@ Q_SIGNALS:
private:
void addApplication(const KService::Ptr &service);
void loadScriptsFromDir(const QString &subDir, AutostartEntrySource kind);
- QString XdgAutoStartPath() const;
+ void insertScriptEntry(int index, const QString &name, const QString &path, AutostartModel::AutostartEntrySource kind);
+ static std::optional<AutostartEntry> loadDesktopEntry(const QString &fileName);
+ QDir m_xdgConfigPath;
+ QDir m_xdgAutoStartPath;
QVector<AutostartEntry> m_entries;
};
diff --git a/kcms/autostart/package/contents/ui/main.qml b/kcms/autostart/package/contents/ui/main.qml
index 644c417cc..3ef2a2c5a 100644
--- a/kcms/autostart/package/contents/ui/main.qml
+++ b/kcms/autostart/package/contents/ui/main.qml
@@ -75,7 +75,7 @@ KCM.ScrollViewKCM {
text: i18n("Properties")
icon.name: "document-properties"
onTriggered: kcm.model.editApplication(model.index, root)
- visible: model.source === AutostartModel.XdgAutoStart
+ visible: model.source === AutostartModel.XdgAutoStart || model.source === AutostartModel.XdgScripts
},
Kirigami.Action {
text: i18n("Remove")
@@ -91,9 +91,12 @@ KCM.ScrollViewKCM {
if (section == AutostartModel.XdgAutoStart) {
return i18n("Applications")
}
- if (section == AutostartModel.XdgScripts || section == AutostartModel.PlasmaStart) {
+ if (section == AutostartModel.XdgScripts) {
return i18n("Login Scripts")
}
+ if (section == AutostartModel.PlasmaEnvScripts) {
+ return i18n("Pre-startup Scripts")
+ }
if (section == AutostartModel.PlasmaShutdown) {
return i18n("Logout Scripts")
}
diff --git a/libkworkspace/CMakeLists.txt b/libkworkspace/CMakeLists.txt
index cca11dc2a..015c5181f 100644
--- a/libkworkspace/CMakeLists.txt
+++ b/libkworkspace/CMakeLists.txt
@@ -4,6 +4,7 @@ set(kworkspace_LIB_SRCS kdisplaymanager.cpp
sessionmanagement.cpp
sessionmanagementbackend.cpp
updatelaunchenvjob.cpp
+ autostartscriptdesktopfile.cpp
)
add_definitions(-DTRANSLATION_DOMAIN=\"libkworkspace\")
@@ -73,6 +74,7 @@ install( FILES kdisplaymanager.h
kworkspace.h
sessionmanagement.h
updatelaunchenvjob.h
+ autostartscriptdesktopfile.h
${CMAKE_CURRENT_BINARY_DIR}/config-libkworkspace.h
${CMAKE_CURRENT_BINARY_DIR}/kworkspace_export.h
DESTINATION ${KDE_INSTALL_INCLUDEDIR}/kworkspace5 COMPONENT Devel )
diff --git a/libkworkspace/autostartscriptdesktopfile.cpp b/libkworkspace/autostartscriptdesktopfile.cpp
new file mode 100644
index 000000000..4211267e6
--- /dev/null
+++ b/libkworkspace/autostartscriptdesktopfile.cpp
@@ -0,0 +1,34 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Henri Chain <henri.chain at enioka.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "autostartscriptdesktopfile.h"
+#include <KConfigGroup>
+#include <KDesktopFile>
+#include <QDir>
+#include <QStandardPaths>
+
+static const auto autostartScriptKey = QStringLiteral("X-KDE-AutostartScript");
+
+QDir AutostartScriptDesktopFile::autostartLocation()
+{
+ return QDir(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)).filePath("autostart");
+}
+
+AutostartScriptDesktopFile::AutostartScriptDesktopFile(const QString &name, const QString &execPath)
+ : KDesktopFile(autostartLocation().absoluteFilePath(name + QStringLiteral(".desktop")))
+{
+ KConfigGroup kcg = desktopGroup();
+ kcg.writeEntry("Type", "Application");
+ kcg.writeEntry("Name", name);
+ kcg.writeEntry("Exec", execPath);
+ kcg.writeEntry("Icon", "dialog-scripts");
+ kcg.writeEntry(autostartScriptKey, "true");
+ kcg.writeEntry("Path", "");
+}
+
+bool AutostartScriptDesktopFile::isAutostartScript(const KDesktopFile &file)
+{
+ return file.desktopGroup().readEntry<bool>(autostartScriptKey, false);
+}
diff --git a/libkworkspace/autostartscriptdesktopfile.h b/libkworkspace/autostartscriptdesktopfile.h
new file mode 100644
index 000000000..451c00262
--- /dev/null
+++ b/libkworkspace/autostartscriptdesktopfile.h
@@ -0,0 +1,32 @@
+/*
+ * SPDX-FileCopyrightText: 2021 Henri Chain <henri.chain at enioka.com>
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+#include "kworkspace_export.h"
+
+#include <KDesktopFile>
+#include <QDir>
+#include <QString>
+
+/**
+ * Corresponds to a .desktop file in $XDG_CONFIG_HOME/autostart that points to
+ * an autostart script and has X-KDE-AutostartScript=true
+ */
+class KWORKSPACE_EXPORT AutostartScriptDesktopFile : public KDesktopFile
+{
+public:
+ explicit AutostartScriptDesktopFile(const QString &name, const QString &execPath);
+
+ /**
+ * Checks whether this KDesktopFile has X-KDE-AutostartScript=true
+ */
+ static bool isAutostartScript(const KDesktopFile &file);
+
+ /**
+ * The location of autostart .desktop application and script files
+ * ($XDG_CONFIG_HOME/autostart)
+ */
+ static QDir autostartLocation();
+};
diff --git a/startkde/plasma-session/startup.cpp b/startkde/plasma-session/startup.cpp
index e563e3b80..81afee89b 100644
--- a/startkde/plasma-session/startup.cpp
+++ b/startkde/plasma-session/startup.cpp
@@ -132,15 +132,14 @@ public:
: Phase(autostart, parent)
{
}
- void runUserAutostart();
- bool migrateKDE4Autostart(const QString &folder);
+ void migrateKDE4Autostart();
void start() override
{
qCDebug(PLASMA_SESSION) << "Phase 2";
+ migrateKDE4Autostart();
addSubjob(new AutoStartAppsJob(m_autostart, 2));
addSubjob(new KDEDInitJob());
- runUserAutostart();
}
};
@@ -352,48 +351,21 @@ void RestoreSessionJob::start()
connect(watcher, &QDBusPendingCallWatcher::finished, watcher, &QObject::deleteLater);
}
-void StartupPhase2::runUserAutostart()
+void StartupPhase2::migrateKDE4Autostart()
{
- // Now let's execute the scripts in the KDE-specific autostart-scripts folder.
+ // Migrate user autostart from kde4
+ Kdelibs4Migration migration;
+ if (!migration.kdeHomeFound()) {
+ return;
+ }
+
const QString autostartFolder =
QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + QDir::separator() + QStringLiteral("autostart-scripts");
-
QDir dir(autostartFolder);
if (!dir.exists()) {
- // Create dir in all cases, so that users can find it :-)
dir.mkpath(QStringLiteral("."));
-
- if (!migrateKDE4Autostart(autostartFolder)) {
- return;
- }
}
- const QStringList entries = dir.entryList(QDir::Files);
- for (const QString &file : entries) {
- // Don't execute backup files
- if (!file.endsWith(QLatin1Char('~')) && !file.endsWith(QLatin1String(".bak")) && (file[0] != QLatin1Char('%') || !file.endsWith(QLatin1Char('%')))
- && (file[0] != QLatin1Char('#') || !file.endsWith(QLatin1Char('#')))) {
- const QString fullPath = dir.absolutePath() + QLatin1Char('/') + file;
-
- qCInfo(PLASMA_SESSION) << "Starting autostart script " << fullPath;
- auto p = new KProcess; // deleted in onFinished lambda
- p->setProgram(fullPath);
- p->start();
- connect(p, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [p](int exitCode) {
- qCInfo(PLASMA_SESSION) << "autostart script" << p->program() << "finished with exit code " << exitCode;
- p->deleteLater();
- });
- }
- }
-}
-
-bool StartupPhase2::migrateKDE4Autostart(const QString &autostartFolder)
-{
- // Migrate user autostart from kde4
- Kdelibs4Migration migration;
- if (!migration.kdeHomeFound()) {
- return false;
- }
// KDEHOME/Autostart was the default value for KGlobalSettings::autostart()
QString oldAutostart = migration.kdeHome() + QStringLiteral("/Autostart");
// That path could be customized in kdeglobals
@@ -420,7 +392,7 @@ bool StartupPhase2::migrateKDE4Autostart(const QString &autostartFolder)
qCWarning(PLASMA_SESSION) << "Error copying" << src << "to" << dest;
}
}
- return true;
+ return;
}
AutoStartAppsJob::AutoStartAppsJob(const AutoStart &autostart, int phase)
diff --git a/startkde/startplasma.cpp b/startkde/startplasma.cpp
index 997f91e88..f6b078e7e 100644
--- a/startkde/startplasma.cpp
+++ b/startkde/startplasma.cpp
@@ -34,6 +34,7 @@
#include <unistd.h>
+#include <autostartscriptdesktopfile.h>
#include <updatelaunchenvjob.h>
#include "startplasma.h"
@@ -538,6 +539,9 @@ bool startPlasmaSession(bool wayland)
}
});
+ // Create .desktop files for the scripts in .config/autostart-scripts
+ migrateUserScriptsAutostart();
+
if (!useSystemdBoot()) {
qCDebug(PLASMA_STARTUP) << "Using classic boot";
QProcess startPlasmaSession;
@@ -611,3 +615,47 @@ void waitForKonqi()
}
}
}
+
+static void migrateUserScriptsAutostart()
+{
+ QDir configLocation(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
+ QDir autostartScriptsLocation(configLocation.filePath(QStringLiteral("autostart-scripts")));
+ if (!autostartScriptsLocation.exists()) {
+ return;
+ }
+ const QDir autostartScriptsMovedLocation(configLocation.filePath(QStringLiteral("old-autostart-scripts")));
+ const auto entries = autostartScriptsLocation.entryInfoList(QDir::Files);
+ for (const auto &info : entries) {
+ const auto scriptName = info.fileName();
+ const auto scriptPath = info.absoluteFilePath();
+ const auto scriptMovedPath = autostartScriptsMovedLocation.filePath(scriptName);
+
+ // Don't migrate backup files
+ if (scriptName.endsWith(QLatin1Char('~')) || scriptName.endsWith(QLatin1String(".bak"))
+ || (scriptName[0] == QLatin1Char('%') && scriptName.endsWith(QLatin1Char('%')))
+ || (scriptName[0] == QLatin1Char('#') && scriptName.endsWith(QLatin1Char('#')))) {
+ qCDebug(PLASMA_STARTUP) << "Not migrating backup autostart script" << scriptName;
+ continue;
+ }
+
+ // Migrate autostart script to a standard .desktop autostart file
+ AutostartScriptDesktopFile desktopFile(scriptName, info.isSymLink() ? info.symLinkTarget() : scriptMovedPath);
+ qCInfo(PLASMA_STARTUP) << "Migrated legacy autostart script" << scriptPath << "to" << desktopFile.fileName();
+
+ if (info.isSymLink() && QFile::remove(scriptPath)) {
+ qCInfo(PLASMA_STARTUP) << "Removed legacy autostart script" << scriptPath << "that pointed to" << info.symLinkTarget();
+ }
+ }
+ // Delete or rename autostart-scripts to old-autostart-scripts to avoid running the migration again
+ if (autostartScriptsLocation.entryInfoList(QDir::Files).empty()) {
+ autostartScriptsLocation.removeRecursively();
+ } else {
+ configLocation.rename(autostartScriptsLocation.dirName(), autostartScriptsMovedLocation.dirName());
+ }
+ // Reload systemd so that the XDG autostart generator is run again to pick up the new .desktop files
+ QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.systemd1"),
+ QStringLiteral("/org/freedesktop/systemd1"),
+ QStringLiteral("org.freedesktop.systemd1.Manager"),
+ QStringLiteral("Reload"));
+ QDBusConnection::sessionBus().call(message);
+}
diff --git a/startkde/startplasma.h b/startkde/startplasma.h
index 40a78a0c2..a7c9641b4 100644
--- a/startkde/startplasma.h
+++ b/startkde/startplasma.h
@@ -54,6 +54,7 @@ void waitForKonqi();
static void resetSystemdFailedUnits();
static bool hasSystemdService(const QString &serviceName);
static bool useSystemdBoot();
+static void migrateUserScriptsAutostart();
struct KillBeforeDeleter {
static inline void cleanup(QProcess *pointer)
More information about the kde-doc-english
mailing list