refact: Autostart

Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
ComixHe 2023-11-08 18:21:09 +08:00 committed by Comix
parent 74931e3d1a
commit b9bbfb7f6d
10 changed files with 284 additions and 79 deletions

View File

@ -8,10 +8,10 @@
#include <QFileInfo> #include <QFileInfo>
#include <QStandardPaths> #include <QStandardPaths>
bool ApplicationFilter::hiddenCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept bool ApplicationFilter::hiddenCheck(const DesktopEntry &entry) noexcept
{ {
bool hidden{false}; bool hidden{false};
auto hiddenVal = entry->value(DesktopFileEntryKey, "Hidden"); auto hiddenVal = entry.value(DesktopFileEntryKey, DesktopEntryHidden);
if (hiddenVal.has_value()) { if (hiddenVal.has_value()) {
bool ok{false}; bool ok{false};
@ -24,9 +24,9 @@ bool ApplicationFilter::hiddenCheck(const std::unique_ptr<DesktopEntry> &entry)
return hidden; return hidden;
} }
bool ApplicationFilter::tryExecCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept bool ApplicationFilter::tryExecCheck(const DesktopEntry &entry) noexcept
{ {
auto tryExecVal = entry->value(DesktopFileEntryKey, "TryExec"); auto tryExecVal = entry.value(DesktopFileEntryKey, "TryExec");
if (tryExecVal.has_value()) { if (tryExecVal.has_value()) {
auto executable = toString(tryExecVal.value()); auto executable = toString(tryExecVal.value());
if (executable.isEmpty()) { if (executable.isEmpty()) {
@ -44,7 +44,7 @@ bool ApplicationFilter::tryExecCheck(const std::unique_ptr<DesktopEntry> &entry)
return false; return false;
} }
bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept bool ApplicationFilter::showInCheck(const DesktopEntry &entry) noexcept
{ {
auto desktops = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")).split(':', Qt::SkipEmptyParts); auto desktops = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")).split(':', Qt::SkipEmptyParts);
if (desktops.isEmpty()) { if (desktops.isEmpty()) {
@ -53,7 +53,7 @@ bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry)
desktops.removeDuplicates(); desktops.removeDuplicates();
bool showInCurrentDE{true}; bool showInCurrentDE{true};
auto onlyShowInVal = entry->value(DesktopFileEntryKey, "OnlyShowIn"); auto onlyShowInVal = entry.value(DesktopFileEntryKey, "OnlyShowIn");
while (onlyShowInVal.has_value()) { while (onlyShowInVal.has_value()) {
auto deStr = toString(onlyShowInVal.value()); auto deStr = toString(onlyShowInVal.value());
if (deStr.isEmpty()) { if (deStr.isEmpty()) {
@ -75,7 +75,7 @@ bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry)
} }
bool notShowInCurrentDE{false}; bool notShowInCurrentDE{false};
auto notShowInVal = entry->value(DesktopFileEntryKey, "NotShowIn"); auto notShowInVal = entry.value(DesktopFileEntryKey, "NotShowIn");
while (notShowInVal.has_value()) { while (notShowInVal.has_value()) {
auto deStr = toString(notShowInVal.value()); auto deStr = toString(notShowInVal.value());
if (deStr.isEmpty()) { if (deStr.isEmpty()) {
@ -98,3 +98,18 @@ bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry)
return !showInCurrentDE or notShowInCurrentDE; return !showInCurrentDE or notShowInCurrentDE;
} }
bool ApplicationFilter::hiddenCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept
{
return hiddenCheck(*entry);
}
bool ApplicationFilter::tryExecCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept
{
return tryExecCheck(*entry);
}
bool ApplicationFilter::showInCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept
{
return showInCheck(*entry);
}

View File

@ -13,6 +13,9 @@ namespace ApplicationFilter {
bool hiddenCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept; bool hiddenCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept;
bool tryExecCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept; bool tryExecCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept;
bool showInCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept; bool showInCheck(const std::unique_ptr<DesktopEntry> &entry) noexcept;
bool hiddenCheck(const DesktopEntry &entry) noexcept;
bool tryExecCheck(const DesktopEntry &entry) noexcept;
bool showInCheck(const DesktopEntry &entry) noexcept;
} // namespace ApplicationFilter } // namespace ApplicationFilter
#endif #endif

View File

@ -23,6 +23,8 @@ constexpr auto DDEApplicationManager1MimeManager1ObjectPath = u8"/org/desktopspe
constexpr auto DesktopFileEntryKey = u8"Desktop Entry"; constexpr auto DesktopFileEntryKey = u8"Desktop Entry";
constexpr auto DesktopFileActionKey = u8"Desktop Action "; constexpr auto DesktopFileActionKey = u8"Desktop Action ";
constexpr auto DesktopFileDefaultKeyLocale = "default"; constexpr auto DesktopFileDefaultKeyLocale = "default";
constexpr auto X_Deepin_GenerateSource = u8"X-Deepin-GenerateSource";
constexpr auto DesktopEntryHidden = u8"Hidden";
constexpr auto ApplicationManagerServerDBusName = constexpr auto ApplicationManagerServerDBusName =
#ifdef DDE_AM_USE_DEBUG_DBUS_NAME #ifdef DDE_AM_USE_DEBUG_DBUS_NAME

View File

@ -2,6 +2,7 @@
// //
// SPDX-License-Identifier: LGPL-3.0-or-later // SPDX-License-Identifier: LGPL-3.0-or-later
#include "applicationadaptor.h" #include "applicationadaptor.h"
#include "applicationchecker.h"
#include "dbus/applicationmanager1adaptor.h" #include "dbus/applicationmanager1adaptor.h"
#include "applicationservice.h" #include "applicationservice.h"
#include "dbus/AMobjectmanager1adaptor.h" #include "dbus/AMobjectmanager1adaptor.h"
@ -79,6 +80,8 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
scanApplications(); scanApplications();
auto needLaunch = scanAutoStart();
scanInstances(); scanInstances();
loadHooks(); loadHooks();
@ -112,16 +115,20 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
constexpr auto XSettings = "org.deepin.dde.XSettings1"; constexpr auto XSettings = "org.deepin.dde.XSettings1";
auto *watcher = auto *watcher = new (std::nothrow)
new QDBusServiceWatcher{XSettings, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this}; QDBusServiceWatcher{XSettings, QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForRegistration, this};
auto *sigCon = new QMetaObject::Connection{}; auto *sigCon = new (std::nothrow) QMetaObject::Connection{};
auto singleSlot = [this, watcher, sigCon]() { auto singleSlot = [watcher, sigCon, autostartList = std::move(needLaunch)]() {
QObject::disconnect(*sigCon); QObject::disconnect(*sigCon);
delete sigCon; delete sigCon;
qDebug() << XSettings << "is registered."; qDebug() << XSettings << "is registered.";
scanAutoStart();
for (const auto &app : autostartList) {
app->Launch({}, {}, {});
}
watcher->deleteLater(); watcher->deleteLater();
}; };
@ -236,23 +243,29 @@ void ApplicationManager1Service::scanApplications() noexcept
{ {
const auto &desktopFileDirs = getDesktopFileDirs(); const auto &desktopFileDirs = getDesktopFileDirs();
std::map<QString, DesktopFile> fileMap;
applyIteratively( applyIteratively(
QList<QDir>(desktopFileDirs.crbegin(), desktopFileDirs.crend()), QList<QDir>(desktopFileDirs.crbegin(), desktopFileDirs.crend()),
[this](const QFileInfo &info) -> bool { [&fileMap](const QFileInfo &info) -> bool {
ParserError err{ParserError::NoError}; ParserError err{ParserError::NoError};
auto ret = DesktopFile::searchDesktopFileByPath(info.absoluteFilePath(), err); auto ret = DesktopFile::searchDesktopFileByPath(info.absoluteFilePath(), err);
if (!ret.has_value()) { if (!ret.has_value()) {
qWarning() << "failed to search File:" << err; qWarning() << "failed to search File:" << err;
return false; return false;
} }
if (!this->addApplication(std::move(ret).value())) { auto file = std::move(ret).value();
qWarning() << "add Application failed, skip..."; fileMap.insert_or_assign(file.desktopId(), std::move(file));
}
return false; // means to apply this function to the rest of the files return false; // means to apply this function to the rest of the files
}, },
QDir::Readable | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Readable | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot,
{"*.desktop"}, {"*.desktop"},
QDir::Name | QDir::DirsLast); QDir::Name | QDir::DirsLast);
for (auto &&[k, v] : std::move(fileMap)) {
if (!addApplication(std::move(v))) {
qWarning() << "add Application" << k << " failed, skip...";
}
}
} }
void ApplicationManager1Service::scanInstances() noexcept void ApplicationManager1Service::scanInstances() noexcept
@ -278,32 +291,117 @@ void ApplicationManager1Service::scanInstances() noexcept
} }
} }
void ApplicationManager1Service::scanAutoStart() noexcept QList<QSharedPointer<ApplicationService>> ApplicationManager1Service::scanAutoStart() noexcept
{ {
QList<QSharedPointer<ApplicationService>> ret;
auto autostartDirs = getAutoStartDirs(); auto autostartDirs = getAutoStartDirs();
QStringList needToLaunch; std::map<QString, DesktopFile> autostartItems;
applyIteratively( applyIteratively(
QList<QDir>{autostartDirs.cbegin(), autostartDirs.cend()}, QList<QDir>{autostartDirs.crbegin(), autostartDirs.crend()},
[&needToLaunch](const QFileInfo &info) { [&autostartItems](const QFileInfo &info) {
if (info.isSymbolicLink()) { ParserError err{ParserError::InternalError};
needToLaunch.emplace_back(info.symLinkTarget()); auto desktopSource = DesktopFile::searchDesktopFileByPath(info.absoluteFilePath(), err);
if (err != ParserError::NoError) {
qWarning() << "skip" << info.absoluteFilePath();
return false;
} }
auto file = std::move(desktopSource).value();
autostartItems.insert_or_assign(file.desktopId(), std::move(file));
return false; return false;
}, },
QDir::Readable | QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Readable | QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot,
{"*.desktop"}, {"*.desktop"},
QDir::Name | QDir::DirsLast); QDir::Name | QDir::DirsLast);
while (!needToLaunch.isEmpty()) { for (auto &it : autostartItems) {
const auto &filePath = needToLaunch.takeFirst(); auto desktopFile = std::move(it.second);
auto appIt =
std::find_if(m_applicationList.constKeyValueBegin(), DesktopFileGuard guard{desktopFile};
m_applicationList.constKeyValueEnd(), if (!guard.try_open()) {
[&filePath](const auto &pair) { return pair.second->m_desktopSource.sourcePath() == filePath; }); continue;
if (appIt != m_applicationList.constKeyValueEnd()) { }
appIt->second->Launch({}, {}, {});
auto &file = desktopFile.sourceFileRef();
QTextStream stream{&file};
DesktopEntry tmp;
auto err = tmp.parse(stream);
if (err != ParserError::NoError) {
qWarning() << "parse autostart file" << desktopFile.sourcePath() << " error:" << err;
continue;
}
QSharedPointer<ApplicationService> app{nullptr};
auto asApplication = tmp.value(DesktopFileEntryKey, X_Deepin_GenerateSource).value_or(DesktopEntry::Value{});
if (!asApplication.isNull()) { // modified by application manager
auto appSource = asApplication.toString();
QFileInfo sourceInfo{appSource};
if ((!sourceInfo.exists() or !sourceInfo.isFile()) and !file.remove()) {
qWarning() << "remove invalid autostart file error:" << file.error();
continue;
}
// add original application
auto desktopSource = DesktopFile::searchDesktopFileByPath(appSource, err);
if (err != ParserError::NoError) {
qWarning() << "search autostart application failed:" << err;
continue;
}
auto source = std::move(desktopSource).value();
if (source.desktopId().isEmpty()) {
qWarning() << X_Deepin_GenerateSource << "is" << appSource
<< ", but couldn't find it in applications, maybe this autostart file has been modified, skip.";
continue;
}
// add application directly, it wouldn't add the same application twice.
app = addApplication(std::move(source));
if (!app) {
qWarning() << "add autostart application failed, skip.";
continue;
} }
} }
auto shouldLaunch = tmp.value(DesktopFileEntryKey, DesktopEntryHidden).value_or(DesktopEntry::Value{});
if (!shouldLaunch.isNull() and (shouldLaunch.toString().compare("true", Qt::CaseInsensitive) == 0)) {
qInfo() << "shouldn't launch this autoStart item.";
continue;
}
if (app) {
ret.append(app);
continue;
}
// maybe some application generate autostart desktop by itself
if (ApplicationFilter::tryExecCheck(tmp) or ApplicationFilter::showInCheck(tmp)) {
qInfo() << "autostart application couldn't pass check.";
continue;
}
if (auto appIt = std::find_if(m_applicationList.cbegin(),
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);
continue;
}
guard.close();
// new application
auto newApp = addApplication(std::move(desktopFile));
if (!newApp) {
qWarning() << "add autostart application failed, skip.";
continue;
}
ret.append(newApp);
}
return ret;
} }
void ApplicationManager1Service::loadHooks() noexcept void ApplicationManager1Service::loadHooks() noexcept
@ -337,36 +435,39 @@ QList<QDBusObjectPath> ApplicationManager1Service::list() const
return m_applicationList.keys(); return m_applicationList.keys();
} }
bool ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) noexcept QSharedPointer<ApplicationService> ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) noexcept
{ {
auto source = desktopFileSource.sourcePath();
QSharedPointer<ApplicationService> application = QSharedPointer<ApplicationService> application =
ApplicationService::createApplicationService(std::move(desktopFileSource), this, m_storage); ApplicationService::createApplicationService(std::move(desktopFileSource), this, m_storage);
if (!application) { if (!application) {
return false; qWarning() << "can't create application" << source;
return nullptr;
} }
if (m_applicationList.constFind(application->applicationPath()) != m_applicationList.cend()) { if (auto app = m_applicationList.constFind(application->applicationPath()); app != m_applicationList.cend()) {
qInfo() << "this application already exists." qInfo() << "this application already exists."
<< "desktop source:" << application->desktopFileSource().sourcePath(); << "current desktop source:" << application->desktopFileSource().sourcePath()
return false; << "exists app source:" << app->data()->desktopFileSource().sourcePath();
return *app;
} }
auto *ptr = application.data(); auto *ptr = application.data();
if (auto *adaptor = new (std::nothrow) ApplicationAdaptor{ptr}; adaptor == nullptr) { if (auto *adaptor = new (std::nothrow) ApplicationAdaptor{ptr}; adaptor == nullptr) {
qCritical() << "new ApplicationAdaptor failed."; qCritical() << "new ApplicationAdaptor failed.";
return false; return nullptr;
} }
if (!registerObjectToDBus(ptr, application->applicationPath().path(), ApplicationInterface)) { if (!registerObjectToDBus(ptr, application->applicationPath().path(), ApplicationInterface)) {
return false; return nullptr;
} }
m_applicationList.insert(application->applicationPath(), application); m_applicationList.insert(application->applicationPath(), application);
emit listChanged(); emit listChanged();
emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr)); emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr));
return true; return application;
} }
void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &application) noexcept void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &application) noexcept

View File

@ -36,7 +36,7 @@ public:
[[nodiscard]] QList<QDBusObjectPath> list() const; [[nodiscard]] QList<QDBusObjectPath> list() const;
void initService(QDBusConnection &connection) noexcept; void initService(QDBusConnection &connection) noexcept;
bool addApplication(DesktopFile desktopFileSource) noexcept; QSharedPointer<ApplicationService> addApplication(DesktopFile desktopFileSource) noexcept;
void removeOneApplication(const QDBusObjectPath &application) noexcept; void removeOneApplication(const QDBusObjectPath &application) noexcept;
void removeAllApplication() noexcept; void removeAllApplication() noexcept;
[[nodiscard]] QMap<QDBusObjectPath, QSharedPointer<ApplicationService>> [[nodiscard]] QMap<QDBusObjectPath, QSharedPointer<ApplicationService>>
@ -74,7 +74,7 @@ private:
void scanMimeInfos() noexcept; void scanMimeInfos() noexcept;
void scanApplications() noexcept; void scanApplications() noexcept;
void scanInstances() noexcept; void scanInstances() noexcept;
void scanAutoStart() noexcept; QList<QSharedPointer<ApplicationService>> scanAutoStart() noexcept;
void loadHooks() noexcept; void loadHooks() noexcept;
void addInstanceToApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath); void addInstanceToApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath);
void removeInstanceFromApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath); void removeInstanceFromApplication(const QString &unitName, const QDBusObjectPath &systemdUnitPath);

View File

@ -6,10 +6,14 @@
#include "APPobjectmanager1adaptor.h" #include "APPobjectmanager1adaptor.h"
#include "applicationchecker.h" #include "applicationchecker.h"
#include "applicationmanagerstorage.h" #include "applicationmanagerstorage.h"
#include "constant.h"
#include "global.h"
#include "iniParser.h"
#include "propertiesForwarder.h" #include "propertiesForwarder.h"
#include "dbus/instanceadaptor.h" #include "dbus/instanceadaptor.h"
#include "launchoptions.h" #include "launchoptions.h"
#include "desktopentry.h" #include "desktopentry.h"
#include "desktopfileparser.h"
#include <QUuid> #include <QUuid>
#include <QStringList> #include <QStringList>
#include <QList> #include <QList>
@ -19,6 +23,11 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <algorithm> #include <algorithm>
#include <new> #include <new>
#include <qdbuserror.h>
#include <qfileinfo.h>
#include <qlogging.h>
#include <qnamespace.h>
#include <qtmetamacros.h>
#include <utility> #include <utility>
#include <wordexp.h> #include <wordexp.h>
@ -102,6 +111,7 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
DesktopFileGuard guard{app->desktopFileSource()}; DesktopFileGuard guard{app->desktopFileSource()};
if (!guard.try_open()) { if (!guard.try_open()) {
qDebug() << "open source desktop failed.";
return nullptr; return nullptr;
} }
@ -139,14 +149,17 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept
{ {
if (ApplicationFilter::hiddenCheck(entry)) { if (ApplicationFilter::hiddenCheck(entry)) {
qDebug() << "hidden check failed.";
return false; return false;
} }
if (ApplicationFilter::tryExecCheck(entry)) { if (ApplicationFilter::tryExecCheck(entry)) {
qDebug() << "tryExec check failed";
return false; return false;
} }
if (ApplicationFilter::showInCheck(entry)) { if (ApplicationFilter::showInCheck(entry)) {
qDebug() << "showIn check failed.";
return false; return false;
} }
@ -541,47 +554,77 @@ void ApplicationService::setScaleFactor(double value) noexcept
emit scaleFactorChanged(); emit scaleFactorChanged();
} }
bool ApplicationService::autostartCheck(const QString &linkPath) const noexcept bool ApplicationService::autostartCheck(const QString &filePath) noexcept
{ {
QFileInfo info{linkPath}; qDebug() << "current check autostart file:" << filePath;
if (info.exists()) { QFile file{filePath};
if (info.isSymbolicLink() and info.symLinkTarget() == m_desktopSource.sourcePath()) { if (!file.open(QFile::ExistingOnly | QFile::ReadOnly | QFile::Text)) {
qWarning() << "open" << filePath << "failed:" << file.errorString();
return false;
}
QTextStream stream{&file};
DesktopEntry s;
if (auto err = s.parse(stream); err != ParserError::NoError) {
qWarning() << "parse" << filePath << "failed:" << err;
return false;
}
auto hiddenVal = s.value(DesktopFileEntryKey, DesktopEntryHidden);
if (!hiddenVal) {
qDebug() << "no hidden in autostart desktop";
return true; return true;
} }
qWarning() << "same name desktop file exists:" << linkPath << "but this may not created by AM.";
}
return false; auto hidden = hiddenVal.value().toString();
return hidden.compare("false", Qt::CaseInsensitive) == 0;
} }
bool ApplicationService::isAutoStart() const noexcept bool ApplicationService::isAutoStart() const noexcept
{ {
auto path = getAutoStartDirs().first(); auto autostartDirs = getAutoStartDirs();
auto linkName = QDir{path}.filePath(m_desktopSource.desktopId() + ".desktop"); auto sourcePath = m_desktopSource.sourcePath();
return autostartCheck(linkName); auto userAutostart = QDir{autostartDirs.first()}.filePath(id() + ".desktop");
QFileInfo info{userAutostart};
auto isOverride = info.exists() and info.isFile();
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);
}
return isOverride and autostartCheck(userAutostart);
} }
void ApplicationService::setAutoStart(bool autostart) noexcept void ApplicationService::setAutoStart(bool autostart) noexcept
{ {
auto path = getAutoStartDirs().first(); if (isAutoStart() == autostart) {
auto linkName = QDir{path}.filePath(m_desktopSource.desktopId() + ".desktop"); return;
auto &file = m_desktopSource.sourceFileRef(); }
if (autostart) { auto fileName = QDir{getAutoStartDirs().first()}.filePath(m_desktopSource.desktopId() + ".desktop");
if (!autostartCheck(linkName) and !file.link(linkName)) { QFile autostartFile{fileName};
qWarning() << "link to autostart failed:" << file.errorString(); if (!autostartFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate)) {
qWarning() << "open file" << fileName << "failed:" << autostartFile.error();
sendErrorReply(QDBusError::Failed);
return; return;
} }
} else {
if (autostartCheck(linkName)) { auto newEntry = *m_entry;
QFile linkFile{linkName}; newEntry.insert(DesktopFileEntryKey, X_Deepin_GenerateSource, m_desktopSource.sourcePath());
if (!linkFile.remove()) { newEntry.insert(DesktopFileEntryKey, DesktopEntryHidden, !autostart);
qWarning() << "remove link failed:" << linkFile.errorString();
auto hideAutostart = toString(newEntry.data()).toLocal8Bit();
auto writeBytes = autostartFile.write(hideAutostart);
if (writeBytes != hideAutostart.size() or !autostartFile.flush()) {
qWarning() << "incomplete write:" << autostartFile.error();
sendErrorReply(QDBusError::Failed, "set failed: filesystem error.");
return; return;
} }
}
}
emit autostartChanged(); emit autostartChanged();
} }
@ -1021,7 +1064,7 @@ double getScaleFactor() noexcept
QString getDeepinWineScaleFactor(const QString &appId) noexcept QString getDeepinWineScaleFactor(const QString &appId) noexcept
{ {
qCritical() << "Don't using env to control the window scale factor, this function" qCritical() << "Don't using env to control the window scale factor, this function"
"should via using graphisc server(Wayland Compositor/Xorg Xft) in deepin wine."; "should via using graphic server(Wayland Compositor/Xorg Xft) in deepin wine.";
QString factor{"1.0"}; QString factor{"1.0"};
auto objectPath = QString{"/dde_launcher/org_deepin_dde_launcher/%1"}.arg(getCurrentUID()); auto objectPath = QString{"/dde_launcher/org_deepin_dde_launcher/%1"}.arg(getCurrentUID());

View File

@ -177,7 +177,7 @@ private:
QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances; QMap<QDBusObjectPath, QSharedPointer<InstanceService>> m_Instances;
void updateAfterLaunch(bool isLaunch) noexcept; void updateAfterLaunch(bool isLaunch) noexcept;
static bool shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept; static bool shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept;
[[nodiscard]] bool autostartCheck(const QString &linkPath) const noexcept; [[nodiscard]] static bool autostartCheck(const QString &filePath) noexcept;
[[nodiscard]] ApplicationManager1Service *parent() { return dynamic_cast<ApplicationManager1Service *>(QObject::parent()); } [[nodiscard]] ApplicationManager1Service *parent() { return dynamic_cast<ApplicationManager1Service *>(QObject::parent()); }
[[nodiscard]] const ApplicationManager1Service *parent() const [[nodiscard]] const ApplicationManager1Service *parent() const
{ {

View File

@ -111,18 +111,31 @@ std::optional<DesktopFile> DesktopFile::searchDesktopFileByPath(const QString &d
return std::nullopt; return std::nullopt;
} }
QString path{desktopFile};
QString id;
const auto &XDGDataDirs = getDesktopFileDirs(); const auto &XDGDataDirs = getDesktopFileDirs();
auto idGen = std::any_of(XDGDataDirs.cbegin(), XDGDataDirs.cend(), [&desktopFile](const QString &suffixPath) { const auto &autostartDirs = getAutoStartDirs();
auto IsCommonApp = std::any_of(XDGDataDirs.cbegin(), XDGDataDirs.cend(), [&desktopFile](const QString &suffixPath) {
return desktopFile.startsWith(suffixPath); return desktopFile.startsWith(suffixPath);
}); });
if (idGen) { auto IsAutostartApp = std::any_of(autostartDirs.cbegin(), autostartDirs.cend(), [&desktopFile](const QString &suffixPath) {
return desktopFile.startsWith(suffixPath);
});
QString path{desktopFile};
QString id;
if (IsCommonApp or IsAutostartApp) {
auto tmp = path.chopped(sizeof(desktopSuffix) - 1); auto tmp = path.chopped(sizeof(desktopSuffix) - 1);
auto components = tmp.split(QDir::separator()).toList(); auto components = tmp.split(QDir::separator(), Qt::SkipEmptyParts).toList();
auto it = std::find(components.cbegin(), components.cend(), "applications"); decltype(components)::const_iterator it;
if (auto appIt = std::find(components.cbegin(), components.cend(), "applications"); appIt != components.cend()) {
it = appIt;
} else if (auto autostartIt = std::find(components.cbegin(), components.cend(), "autostart");
autostartIt != components.cend()) {
it = autostartIt;
}
QString FileId; QString FileId;
++it; ++it;
while (it != components.cend()) { while (it != components.cend()) {
@ -236,6 +249,16 @@ std::optional<DesktopEntry::Value> DesktopEntry::value(const QString &groupKey,
return *it; return *it;
} }
void DesktopEntry::insert(const QString &key, const QString &valueKey, Value &&val) noexcept
{
auto outer = m_entryMap.find(key);
if (outer == m_entryMap.end()) {
outer = m_entryMap.insert(key, {});
}
outer->insert(valueKey, val);
}
QString unescape(const QString &str, bool shellMode) noexcept QString unescape(const QString &str, bool shellMode) noexcept
{ {
QString unescapedStr; QString unescapedStr;

View File

@ -78,6 +78,10 @@ struct DesktopFileGuard
bool try_open() bool try_open()
{ {
if (!fileRef.m_fileSource) {
return false;
}
if (fileRef.m_fileSource->isOpen()) { if (fileRef.m_fileSource->isOpen()) {
return true; return true;
} }
@ -90,13 +94,19 @@ struct DesktopFileGuard
return ret; return ret;
} }
~DesktopFileGuard() void close()
{ {
if (!fileRef.m_fileSource) {
return;
}
if (fileRef.m_fileSource->isOpen()) { if (fileRef.m_fileSource->isOpen()) {
fileRef.m_fileSource->close(); fileRef.m_fileSource->close();
} }
} }
~DesktopFileGuard() { close(); }
private: private:
const DesktopFile &fileRef; const DesktopFile &fileRef;
}; };
@ -116,6 +126,8 @@ public:
[[nodiscard]] ParserError parse(QTextStream &stream) noexcept; [[nodiscard]] ParserError parse(QTextStream &stream) noexcept;
[[nodiscard]] std::optional<QMap<QString, Value>> group(const QString &key) const noexcept; [[nodiscard]] std::optional<QMap<QString, Value>> group(const QString &key) const noexcept;
[[nodiscard]] std::optional<Value> value(const QString &key, const QString &valueKey) const noexcept; [[nodiscard]] std::optional<Value> value(const QString &key, const QString &valueKey) const noexcept;
void insert(const QString &key, const QString &valueKey, Value &&val) noexcept;
[[nodiscard]] const auto &data() const noexcept { return m_entryMap; }
friend bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs); friend bool operator==(const DesktopEntry &lhs, const DesktopEntry &rhs);
friend bool operator!=(const DesktopEntry &lhs, const DesktopEntry &rhs); friend bool operator!=(const DesktopEntry &lhs, const DesktopEntry &rhs);

View File

@ -403,7 +403,12 @@ inline QStringList getXDGDataDirs()
XDGDataDirs.append("/usr/share"); XDGDataDirs.append("/usr/share");
} }
XDGDataDirs.push_front(getXDGDataHome()); auto XDGDataHome = getXDGDataHome();
if (XDGDataDirs.contains(XDGDataHome)) {
XDGDataDirs.removeAll(XDGDataHome);
}
XDGDataDirs.push_front(XDGDataHome);
return XDGDataDirs; return XDGDataDirs;
} }
@ -416,6 +421,7 @@ inline QStringList getDesktopFileDirs()
} }
str.append("applications"); str.append("applications");
}); });
return XDGDataDirs; return XDGDataDirs;
} }