fix: support ExecSearchPath to prevent systemd from not finding binaries
In NixOS, maintainer used a patch to modify the DEFAULT_PATH macro of systemd. However, systemd can only find its own binaries under that path. At this point, if you take the relative path of the binary as a parameter to StartTransientUnit, systemd will use DEFAULT_PATH to look for the binary, which will cause systemd to not find it. There may be other Linux distributions that change this path, so add ExecSearchPath to prevent systemd from not finding the binary. Signed-off-by: ComixHe <heyuming@deepin.org>
This commit is contained in:
@ -67,6 +67,24 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
|
||||
this,
|
||||
&ApplicationManager1Service::removeInstanceFromApplication);
|
||||
|
||||
auto envToPath = [this](const QStringList &envs) {
|
||||
if (auto path = std::find_if(envs.cbegin(), envs.cend(), [](const QString &env) { return env.startsWith("PATH="); });
|
||||
path != envs.cend()) {
|
||||
m_systemdPathEnv = path->mid(5).split(':', Qt::SkipEmptyParts);
|
||||
}
|
||||
};
|
||||
|
||||
connect(&dispatcher, &SystemdSignalDispatcher::SystemdEnvironmentChanged, envToPath);
|
||||
|
||||
auto &con = ApplicationManager1DBus::instance().globalDestBus();
|
||||
auto envMsg = QDBusMessage::createMethodCall(SystemdService, SystemdObjectPath, SystemdPropInterfaceName, "Get");
|
||||
envMsg.setArguments({SystemdInterfaceName, "Environment"});
|
||||
auto ret = con.call(envMsg);
|
||||
if (ret.type() == QDBusMessage::ErrorMessage) {
|
||||
qFatal("%s", ret.errorMessage().toLocal8Bit().data());
|
||||
}
|
||||
envToPath(qdbus_cast<QStringList>(ret.arguments().first().value<QDBusVariant>().variant()));
|
||||
|
||||
auto sysBus = QDBusConnection::systemBus();
|
||||
if (!sysBus.connect("org.desktopspec.ApplicationUpdateNotifier1",
|
||||
"/org/desktopspec/ApplicationUpdateNotifier1",
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
[[nodiscard]] const QStringList &applicationHooks() const noexcept { return m_hookElements; }
|
||||
[[nodiscard]] MimeManager1Service &mimeManager() noexcept { return *m_mimeManager; }
|
||||
[[nodiscard]] const MimeManager1Service &mimeManager() const noexcept { return *m_mimeManager; }
|
||||
[[nodiscard]] const QStringList &systemdPathEnv() const noexcept { return m_systemdPathEnv; }
|
||||
|
||||
public Q_SLOTS:
|
||||
QString Identify(const QDBusUnixFileDescriptor &pidfd,
|
||||
@ -69,6 +70,7 @@ private:
|
||||
QScopedPointer<MimeManager1Service> m_mimeManager{nullptr};
|
||||
QScopedPointer<JobManager1Service> m_jobManager{nullptr};
|
||||
QStringList m_hookElements;
|
||||
QStringList m_systemdPathEnv;
|
||||
QMap<QDBusObjectPath, QSharedPointer<ApplicationService>> m_applicationList;
|
||||
|
||||
void scanMimeInfos() noexcept;
|
||||
|
@ -32,6 +32,40 @@
|
||||
#include <utility>
|
||||
#include <wordexp.h>
|
||||
|
||||
double getScaleFactor() noexcept
|
||||
{
|
||||
auto sessionBus = QDBusConnection::sessionBus();
|
||||
QDBusMessage reply1 = sessionBus.call(QDBusMessage::createMethodCall(
|
||||
"org.deepin.dde.XSettings1", "/org/deepin/dde/XSettings1", "org.deepin.dde.XSettings1", "GetScaleFactor"));
|
||||
|
||||
if (reply1.type() != QDBusMessage::ReplyMessage) {
|
||||
qWarning() << "call GetScaleFactor Failed:" << reply1.errorMessage();
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
QDBusReply<double> ret1(reply1);
|
||||
double scale = ret1.isValid() ? ret1.value() : 1.0;
|
||||
scale = scale > 0 ? scale : 1;
|
||||
return scale;
|
||||
}
|
||||
|
||||
void appendRuntimeScaleFactor(const ApplicationService &app, QVariantMap &runtimeOptions) noexcept
|
||||
{
|
||||
static QStringList scaleEnvs{"DEEPIN_WINE_SCALE=%1;", "GDK_DPI_SCALE=%1;", "QT_SCALE_FACTOR=%1;", "GDK_SCALE=%1;"};
|
||||
QString oldEnv;
|
||||
|
||||
auto factor = app.scaleFactor();
|
||||
if (auto it = runtimeOptions.find("env"); it != runtimeOptions.cend()) {
|
||||
oldEnv = it->value<QString>();
|
||||
}
|
||||
|
||||
for (const auto &env : scaleEnvs) {
|
||||
oldEnv.append(env.arg(factor));
|
||||
}
|
||||
|
||||
runtimeOptions.insert("env", oldEnv);
|
||||
}
|
||||
|
||||
ApplicationService::ApplicationService(DesktopFile source,
|
||||
ApplicationManager1Service *parent,
|
||||
std::weak_ptr<ApplicationManager1Storage> storage)
|
||||
@ -167,23 +201,6 @@ bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entr
|
||||
return true;
|
||||
}
|
||||
|
||||
void ApplicationService::appendScaleFactor(QVariantMap &optionsMap) const noexcept
|
||||
{
|
||||
static QStringList scaleEnvs{"DEEPIN_WINE_SCALE=%1;", "GDK_DPI_SCALE=%1;", "QT_SCALE_FACTOR=%1;", "GDK_SCALE=%1;"};
|
||||
QString oldEnv;
|
||||
|
||||
auto factor = scaleFactor();
|
||||
if (auto it = optionsMap.find("env"); it != optionsMap.cend()) {
|
||||
oldEnv = it->value<QString>();
|
||||
}
|
||||
|
||||
for (const auto &env : scaleEnvs) {
|
||||
oldEnv.append(env.arg(factor));
|
||||
}
|
||||
|
||||
optionsMap.insert("env", oldEnv);
|
||||
}
|
||||
|
||||
QDBusObjectPath
|
||||
ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options, const QString &realExec)
|
||||
{
|
||||
@ -191,7 +208,7 @@ ApplicationService::Launch(const QString &action, const QStringList &fields, con
|
||||
const auto &supportedActions = actions();
|
||||
auto optionsMap = options;
|
||||
|
||||
appendScaleFactor(optionsMap);
|
||||
appendRuntimeScaleFactor(*this, optionsMap);
|
||||
|
||||
if (!realExec.isNull()) { // we want to replace exec of this applications.
|
||||
if (realExec.isEmpty()) {
|
||||
@ -248,6 +265,8 @@ ApplicationService::Launch(const QString &action, const QStringList &fields, con
|
||||
if (const auto &hooks = parent()->applicationHooks(); !hooks.isEmpty()) {
|
||||
optionsMap.insert("_hooks", hooks);
|
||||
}
|
||||
optionsMap.insert("_builtIn_searchExec", parent()->systemdPathEnv());
|
||||
|
||||
auto cmds = generateCommand(optionsMap);
|
||||
auto task = unescapeExec(execStr, fields);
|
||||
if (!task) {
|
||||
@ -1112,20 +1131,3 @@ void ApplicationService::setAutostartSource(AutostartSource &&source) noexcept
|
||||
{
|
||||
m_autostartSource = std::move(source);
|
||||
}
|
||||
|
||||
double getScaleFactor() noexcept
|
||||
{
|
||||
auto sessionBus = QDBusConnection::sessionBus();
|
||||
QDBusMessage reply1 = sessionBus.call(QDBusMessage::createMethodCall(
|
||||
"org.deepin.dde.XSettings1", "/org/deepin/dde/XSettings1", "org.deepin.dde.XSettings1", "GetScaleFactor"));
|
||||
|
||||
if (reply1.type() != QDBusMessage::ReplyMessage) {
|
||||
qWarning() << "call GetScaleFactor Failed:" << reply1.errorMessage();
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
QDBusReply<double> ret1(reply1);
|
||||
double scale = ret1.isValid() ? ret1.value() : 1.0;
|
||||
scale = scale > 0 ? scale : 1;
|
||||
return scale;
|
||||
}
|
||||
|
@ -23,10 +23,6 @@
|
||||
#include <QTextStream>
|
||||
#include <QUuid>
|
||||
#include <memory>
|
||||
#include <qcontainerfwd.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
double getScaleFactor() noexcept;
|
||||
|
||||
struct AutostartSource
|
||||
{
|
||||
@ -137,7 +133,6 @@ public:
|
||||
|
||||
private Q_SLOTS:
|
||||
void onGlobalScaleFactorChanged() noexcept;
|
||||
void appendScaleFactor(QVariantMap &optionsMap) const noexcept;
|
||||
|
||||
public Q_SLOTS:
|
||||
// NOTE: 'realExec' only for internal implementation
|
||||
|
Reference in New Issue
Block a user