diff --git a/kate/session/katesessionmanager.h b/kate/session/katesessionmanager.h --- a/kate/session/katesessionmanager.h +++ b/kate/session/katesessionmanager.h @@ -186,6 +186,11 @@ */ void loadSession(const KateSession::Ptr &session) const; + /** + * Writes sessions as jump list actions to the kate.desktop file + */ + void updateJumpListActions(const QStringList &sessionList); + private: /** * absolute path to dir in home dir where to store the sessions diff --git a/kate/session/katesessionmanager.cpp b/kate/session/katesessionmanager.cpp --- a/kate/session/katesessionmanager.cpp +++ b/kate/session/katesessionmanager.cpp @@ -35,11 +35,16 @@ #include #include #include +#include #include +#include +#include #include +#include #include #include +#include #include #ifndef Q_OS_WIN @@ -87,6 +92,9 @@ list << QUrl::fromPercentEncoding(name.toLatin1()); } + // write jump list actions to disk in the kate.desktop file + updateJumpListActions(list); + // delete old items; QMutableHashIterator i(m_sessions); @@ -504,5 +512,63 @@ return m_sessions.values(); } +void KateSessionManager::updateJumpListActions(const QStringList &sessionList) +{ + KService::Ptr service = KService::serviceByStorageId(qApp->desktopFileName()); + if (!service) { + return; + } + + QScopedPointer df(new KDesktopFile(service->entryPath())); + + QStringList newActions = df->readActions(); + + // try to keep existing custom actions intact, only remove our "Session" actions and add them back later + newActions.erase(std::remove_if(newActions.begin(), newActions.end(), [](const QString &action) { + return action.startsWith(QLatin1String("Session ")); + }), newActions.end()); + + // we compute the new group names in advance so we can tell whether we changed something + // and avoid touching the desktop file leading to an expensive ksycoca recreation + QStringList sessionActions; + sessionActions.reserve(sessionList.count()); + + std::transform(sessionList.constBegin(), sessionList.constEnd(), std::back_inserter(sessionActions), [](const QString &session) { + return QStringLiteral("Session %1").arg(QString::fromLatin1(QCryptographicHash::hash(session.toUtf8(), QCryptographicHash::Md5).toHex())); + }); + + newActions += sessionActions; + + // nothing to do + if (df->readActions() == newActions) { + return; + } + + const QString &localPath = service->locateLocal(); + if (service->entryPath() != localPath) { + df.reset(df->copyTo(localPath)); + } + + // remove all Session action groups first to not leave behind any cruft + for (const QString &action : df->readActions()) { + if (action.startsWith(QLatin1String("Session "))) { + // TODO is there no deleteGroup(KConfigGroup)? + df->deleteGroup(df->actionGroup(action).name()); + } + } + + const int maxEntryCount = std::min(sessionActions.count(), 10); + for (int i = 0; i < maxEntryCount; ++i) { + const QString &action = sessionActions.at(i); // is a transform of sessionList, so count and order is identical + const QString &session = sessionList.at(i); + + KConfigGroup grp = df->actionGroup(action); + grp.writeEntry(QStringLiteral("Name"), session); + grp.writeEntry(QStringLiteral("Exec"), QStringLiteral("kate -s %1").arg(KShell::quoteArg(session))); // TODO proper executable name? + } + + df->desktopGroup().writeXdgListEntry("Actions", newActions); +} + //END KateSessionManager