feat: replace exec during autostart process
create directory of user applciation if dosen't exists Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
parent
2fb5567eaf
commit
71b3b0a6c0
@ -12,6 +12,7 @@
|
||||
#include "desktopfilegenerator.h"
|
||||
#include "processguesser1service.h"
|
||||
#include <QFile>
|
||||
#include <QHash>
|
||||
#include <QDBusMessage>
|
||||
#include <QStringBuilder>
|
||||
#include <unistd.h>
|
||||
@ -123,13 +124,13 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
|
||||
|
||||
auto *sigCon = new (std::nothrow) QMetaObject::Connection{};
|
||||
|
||||
auto singleSlot = [watcher, sigCon, autostartList = std::move(needLaunch)]() {
|
||||
auto singleSlot = [watcher, sigCon, autostartMap = std::move(needLaunch)]() {
|
||||
QObject::disconnect(*sigCon);
|
||||
delete sigCon;
|
||||
qDebug() << XSettings << "is registered.";
|
||||
|
||||
for (const auto &app : autostartList) {
|
||||
app->Launch({}, {}, {});
|
||||
for (const auto &[app, realExec] : autostartMap.asKeyValueRange()) {
|
||||
app->Launch({}, {}, {}, realExec);
|
||||
}
|
||||
|
||||
watcher->deleteLater();
|
||||
@ -294,9 +295,9 @@ void ApplicationManager1Service::scanInstances() noexcept
|
||||
}
|
||||
}
|
||||
|
||||
QList<QSharedPointer<ApplicationService>> ApplicationManager1Service::scanAutoStart() noexcept
|
||||
QHash<QSharedPointer<ApplicationService>, QString> ApplicationManager1Service::scanAutoStart() noexcept
|
||||
{
|
||||
QList<QSharedPointer<ApplicationService>> ret;
|
||||
QHash<QSharedPointer<ApplicationService>, QString> ret;
|
||||
auto autostartDirs = getAutoStartDirs();
|
||||
std::map<QString, DesktopFile> autostartItems;
|
||||
|
||||
@ -374,7 +375,9 @@ QList<QSharedPointer<ApplicationService>> ApplicationManager1Service::scanAutoSt
|
||||
}
|
||||
|
||||
if (app) {
|
||||
ret.append(app);
|
||||
auto realExec = tmp.value(DesktopFileEntryKey, "Exec").value_or(QString{""}).toString();
|
||||
qInfo() << "launch normal autostart application " << app->id() << " by " << realExec;
|
||||
ret.insert(app, realExec);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -388,8 +391,9 @@ QList<QSharedPointer<ApplicationService>> ApplicationManager1Service::scanAutoSt
|
||||
m_applicationList.cend(),
|
||||
[&desktopFile](const auto &app) { return desktopFile.desktopId() == app->id(); });
|
||||
appIt != m_applicationList.cend()) {
|
||||
qInfo() << "app already exists. use it to launch instance.";
|
||||
ret.append(*appIt);
|
||||
auto realExec = tmp.value(DesktopFileEntryKey, "Exec").value_or(QString{""}).toString();
|
||||
qInfo() << "launch exist autostart application " << (*appIt)->id() << " by " << realExec;
|
||||
ret.insert(*appIt, realExec);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -401,7 +405,9 @@ QList<QSharedPointer<ApplicationService>> ApplicationManager1Service::scanAutoSt
|
||||
continue;
|
||||
}
|
||||
|
||||
ret.append(newApp);
|
||||
auto realExec = newApp->m_entry->value(DesktopFileEntryKey, "Exec").value_or(QString{""}).toString();
|
||||
qInfo() << "launch new autostart application " << newApp->id() << " by " << realExec;
|
||||
ret.insert(newApp, realExec);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -642,7 +648,14 @@ QString ApplicationManager1Service::addUserApplication(const QVariantMap &deskto
|
||||
return {};
|
||||
}
|
||||
|
||||
QDir xdgDataHome{getXDGDataHome() + "/applications"};
|
||||
QDir xdgDataHome;
|
||||
QString dir{getXDGDataHome() + "/applications"};
|
||||
if (!xdgDataHome.mkpath(dir)) {
|
||||
sendErrorReply(QDBusError::Failed, "couldn't create directory of user applications.");
|
||||
return {};
|
||||
}
|
||||
|
||||
xdgDataHome.setPath(dir);
|
||||
const auto &filePath = xdgDataHome.filePath(name);
|
||||
|
||||
if (QFileInfo info{filePath}; info.exists() and info.isFile()) {
|
||||
|
@ -74,7 +74,7 @@ private:
|
||||
void scanMimeInfos() noexcept;
|
||||
void scanApplications() noexcept;
|
||||
void scanInstances() noexcept;
|
||||
QList<QSharedPointer<ApplicationService>> scanAutoStart() noexcept;
|
||||
QHash<QSharedPointer<ApplicationService>, QString> scanAutoStart() noexcept;
|
||||
void loadHooks() noexcept;
|
||||
void addInstanceToApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath);
|
||||
void removeInstanceFromApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath);
|
||||
|
@ -173,9 +173,10 @@ bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entr
|
||||
return true;
|
||||
}
|
||||
|
||||
QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options)
|
||||
QDBusObjectPath
|
||||
ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options, const QString &realExec)
|
||||
{
|
||||
QString execStr;
|
||||
QString execStr{};
|
||||
bool ok;
|
||||
const auto &supportedActions = actions();
|
||||
auto optionsMap = options;
|
||||
@ -190,7 +191,16 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
||||
optionsMap.insert("env", oldEnv);
|
||||
}
|
||||
|
||||
while (!action.isEmpty() and !supportedActions.isEmpty()) { // break trick
|
||||
if (!realExec.isNull()) { // we want to replace exec of this applications.
|
||||
if (realExec.isEmpty()) {
|
||||
qWarning() << "try to replace exec but it's empty.";
|
||||
return {};
|
||||
}
|
||||
|
||||
execStr = realExec;
|
||||
}
|
||||
|
||||
while (execStr.isEmpty() and !action.isEmpty() and !supportedActions.isEmpty()) { // break trick
|
||||
if (auto index = supportedActions.indexOf(action); index == -1) {
|
||||
qWarning() << "can't find " << action << " in supported actions List. application will use default action to launch.";
|
||||
break;
|
||||
@ -215,7 +225,9 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
||||
if (!Actions) {
|
||||
QString msg{"application can't be executed."};
|
||||
qWarning() << msg;
|
||||
sendErrorReply(QDBusError::Failed, msg);
|
||||
if (calledFromDBus()) {
|
||||
sendErrorReply(QDBusError::Failed, msg);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -223,7 +235,9 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
||||
if (execStr.isEmpty()) {
|
||||
QString msg{"maybe entry actions's format is invalid, abort launch."};
|
||||
qWarning() << msg;
|
||||
sendErrorReply(QDBusError::Failed, msg);
|
||||
if (calledFromDBus()) {
|
||||
sendErrorReply(QDBusError::Failed, msg);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@ -235,14 +249,18 @@ QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringL
|
||||
auto cmds = generateCommand(optionsMap);
|
||||
auto task = unescapeExec(execStr, fields);
|
||||
if (!task) {
|
||||
sendErrorReply(QDBusError::InternalError, "Invalid Command.");
|
||||
if (calledFromDBus()) {
|
||||
sendErrorReply(QDBusError::InternalError, "Invalid Command.");
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
auto [bin, execCmds, res] = std::move(task);
|
||||
if (bin.isEmpty()) {
|
||||
qCritical() << "error command is detected, abort.";
|
||||
sendErrorReply(QDBusError::Failed);
|
||||
if (calledFromDBus()) {
|
||||
sendErrorReply(QDBusError::Failed);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -592,20 +610,30 @@ bool ApplicationService::autostartCheck(const QString &filePath) noexcept
|
||||
|
||||
bool ApplicationService::isAutoStart() const noexcept
|
||||
{
|
||||
auto autostartDirs = getAutoStartDirs();
|
||||
auto sourcePath = m_desktopSource.sourcePath();
|
||||
auto userAutostart = QDir{autostartDirs.first()}.filePath(id() + ".desktop");
|
||||
auto appId = id();
|
||||
auto dirs = getAutoStartDirs();
|
||||
QString destDesktopFile;
|
||||
|
||||
QFileInfo info{userAutostart};
|
||||
auto isOverride = info.exists() and info.isFile();
|
||||
applyIteratively(
|
||||
QList<QDir>(dirs.crbegin(), dirs.crend()),
|
||||
[&appId, &destDesktopFile](const QFileInfo &file) {
|
||||
auto filePath = file.absoluteFilePath();
|
||||
if (appId == getAutostartAppIdFromAbsolutePath(filePath)) {
|
||||
destDesktopFile = filePath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
QDir::Readable | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot,
|
||||
{"*.desktop"},
|
||||
QDir::Name | QDir::DirsLast);
|
||||
|
||||
if (std::any_of(autostartDirs.cbegin(), autostartDirs.cend(), [&sourcePath](const QString &dir) {
|
||||
return sourcePath.startsWith(dir);
|
||||
})) { // load from autostart
|
||||
return isOverride ? autostartCheck(userAutostart) : autostartCheck(sourcePath);
|
||||
if (destDesktopFile.isEmpty()) {
|
||||
qDebug() << "couldn't find autostart desktopFile.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return isOverride and autostartCheck(userAutostart);
|
||||
return autostartCheck(destDesktopFile);
|
||||
}
|
||||
|
||||
void ApplicationService::setAutoStart(bool autostart) noexcept
|
||||
|
@ -133,7 +133,9 @@ private Q_SLOTS:
|
||||
void onGlobalScaleFactorChanged() noexcept;
|
||||
|
||||
public Q_SLOTS:
|
||||
QDBusObjectPath Launch(const QString &action, const QStringList &fields, const QVariantMap &options);
|
||||
// NOTE: 'realExec' only for internal implementation
|
||||
QDBusObjectPath
|
||||
Launch(const QString &action, const QStringList &fields, const QVariantMap &options, const QString &realExec = {});
|
||||
[[nodiscard]] ObjectMap GetManagedObjects() const;
|
||||
[[nodiscard]] bool SendToDesktop() const noexcept;
|
||||
[[nodiscard]] bool RemoveFromDesktop() const noexcept;
|
||||
|
14
src/global.h
14
src/global.h
@ -630,4 +630,18 @@ inline uint getPidFromPidFd(const QDBusUnixFileDescriptor &pidfd) noexcept
|
||||
return pid;
|
||||
}
|
||||
|
||||
inline QString getAutostartAppIdFromAbsolutePath(const QString &path)
|
||||
{
|
||||
constexpr decltype(auto) desktopSuffix{u8".desktop"};
|
||||
auto tmp = path.chopped(sizeof(desktopSuffix) - 1);
|
||||
auto components = tmp.split(QDir::separator(), Qt::SkipEmptyParts);
|
||||
auto location = std::find(components.cbegin(), components.cend(), "autostart");
|
||||
if (location == components.cend()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto appId = QStringList{location + 1, components.cend()}.join('-');
|
||||
return appId;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user