Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/dde-autostart/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void scanAndLaunch()
continue;
}

if (ApplicationFilter::tryExecCheck(tmp) || ApplicationFilter::showInCheck(tmp)
if (ApplicationFilter::tryExecCheck(tmp, desktopFile.desktopId()) || ApplicationFilter::showInCheck(tmp)
|| ApplicationFilter::hiddenCheck(tmp)) {
qInfo() << "autostart application " << id << " couldn't pass check:" << desktopFile.sourcePath();
continue;
Expand Down
1 change: 1 addition & 0 deletions misc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,4 +93,5 @@ dtk_add_config_meta_files(APPID ${APPLICATION_SERVICEID}
FILES
${CMAKE_CURRENT_LIST_DIR}/dsg/configs/dde-application-manager/org.deepin.dde.am.json
${CMAKE_CURRENT_LIST_DIR}/dsg/configs/dde-application-manager/org.deepin.dde.application-manager.json
${CMAKE_CURRENT_LIST_DIR}/dsg/configs/dde-application-manager/org.deepin.dde.am.appoverride.json
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"magic": "dsg.config.meta",
"version": "1.0",
"contents": {
"Exec": {
"value": "",
"serial": 0,
"flags": [],
"name": "Session-specific Exec override",
"name[zh_CN]": "会话感知的 Exec 覆盖",
"description": "Overrides the Exec field. Supports !AM_FULL! placeholder.",
"permissions": "readonly",
"visibility": "public"
},
"TryExec": {
"value": "",
"serial": 0,
"flags": [],
"name": "Session-specific TryExec override",
"name[zh_CN]": "会话感知的 TryExec 覆盖",
"description": "Overrides the TryExec field. Empty string forces the app to be shown.",
"permissions": "readonly",
"visibility": "public"
},
"Icon": {
"value": "",
"serial": 0,
"flags": [],
"name": "Session-specific Icon override",
"name[zh_CN]": "会话感知的 Icon 覆盖",
"description": "Overrides the Icon field.",
"permissions": "readwrite",
Comment thread
BLumia marked this conversation as resolved.
"visibility": "public"
}
}
}
Comment thread
BLumia marked this conversation as resolved.
14 changes: 13 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
find_package(Dtk6 REQUIRED COMPONENTS Core Tools)

dtk_add_config_to_cpp(
AM_APP_OVERRIDE_CONFIG_SRC
"${CMAKE_SOURCE_DIR}/misc/dsg/configs/dde-application-manager/org.deepin.dde.am.appoverride.json"
OUTPUT_FILE_NAME "am_appoverride_config.hpp"
CLASS_NAME "ApplicationOverrideConfig"
)

add_custom_target(am_appoverride_config_generate DEPENDS ${AM_APP_OVERRIDE_CONFIG_SRC})

add_subdirectory(dbus)

include(GNUInstallDirs)
Expand All @@ -9,7 +20,8 @@ set(LIB_NAME dde_am_static)
file(GLOB SRCS ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h)
list(REMOVE_ITEM SRCS ${UTILS_SRCS})

add_library(${LIB_NAME} STATIC ${SRCS})
add_library(${LIB_NAME} STATIC ${SRCS} ${AM_APP_OVERRIDE_CONFIG_SRC})
add_dependencies(${LIB_NAME} am_appoverride_config_generate)

target_include_directories(${LIB_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
Expand Down
21 changes: 20 additions & 1 deletion src/applicationchecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "global.h"
#include "constant.h"
#include "applicationchecker.h"
#include "sessionoverrideconfig.h"
#include <QDir>
#include <QFileInfo>
#include <QStandardPaths>
Expand Down Expand Up @@ -69,8 +70,26 @@ bool ApplicationFilter::hiddenCheck(const DesktopEntry &entry) noexcept
return hidden;
}

bool ApplicationFilter::tryExecCheck(const DesktopEntry &entry) noexcept
bool ApplicationFilter::tryExecCheck(const DesktopEntry &entry, QStringView desktopId, const SessionOverrideConfig *sessionConfig) noexcept
{
// DConfig session-level TryExec override takes highest priority
if (sessionConfig) {
auto overrideTryExec = sessionConfig->getValue(desktopId.toString(), fromStaticRaw(DesktopFileEntryKey), fromStaticRaw(DesktopEntryTryExec));
if (overrideTryExec) {
auto executable = *overrideTryExec;
if (executable.isEmpty()) {
qCInfo(DDEAMChecker) << "session override TryExec is empty for" << desktopId << ", treated as shown.";
return false; // empty means force-show
}

if (executable.startsWith(QDir::separator())) {
const QFileInfo info{executable};
return !(info.exists() && info.isExecutable());
}
return QStandardPaths::findExecutable(executable).isEmpty();
}
}

auto tryExecVal = entry.value(fromStaticRaw(DesktopFileEntryKey), fromStaticRaw(DesktopEntryTryExec));
if (tryExecVal.has_value()) {
auto executable = toString(tryExecVal.value());
Expand Down
6 changes: 5 additions & 1 deletion src/applicationchecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@
#ifndef APPLICATIONCHECKER_H
#define APPLICATIONCHECKER_H

#include <QLoggingCategory>

#include "desktopentry.h"

Q_DECLARE_LOGGING_CATEGORY(DDEAMChecker)

class SessionOverrideConfig;

namespace ApplicationFilter {

bool hiddenCheck(const DesktopEntry &entry) noexcept;
bool tryExecCheck(const DesktopEntry &entry) noexcept;
bool tryExecCheck(const DesktopEntry &entry, QStringView desktopId, const SessionOverrideConfig *sessionConfig = nullptr) noexcept;
bool showInCheck(const DesktopEntry &entry) noexcept;

} // namespace ApplicationFilter
Expand Down
1 change: 1 addition & 0 deletions src/constant.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ constexpr static auto &ApplicationManagerHookDir = u"/deepin/dde-application-man
constexpr static auto &ApplicationManagerToolsConfig = u"org.deepin.dde.am";

constexpr static auto &ApplicationManagerConfig = u"org.deepin.dde.application-manager";
constexpr static auto &ApplicationOverrideConfigResource = u"org.deepin.dde.am.appoverride";
constexpr static auto &AppExtraEnvironments = u"appExtraEnvironments";
constexpr static auto &AppEnvironmentsBlacklist = u"appEnvironmentsBlacklist";
constexpr static auto &SkipEventAppIds = u"skipEventAppIds";
Expand Down
2 changes: 2 additions & 0 deletions src/dbus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ target_sources(dde_am_dbus PRIVATE
${dde_am_dbus_SOURCE}
)

add_dependencies(dde_am_dbus am_appoverride_config_generate)

target_link_libraries(
dde_am_dbus PUBLIC
Qt6::Core
Expand Down
27 changes: 24 additions & 3 deletions src/dbus/applicationmanager1service.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ void forEachAutostartDesktopFile(T &&func) noexcept
}
}

[[nodiscard]] std::optional<ParsedAutostartEntry> parseAutostartDesktopFile(DesktopFile desktopFile) noexcept
[[nodiscard]] std::optional<ParsedAutostartEntry> parseAutostartDesktopFile(DesktopFile desktopFile, const SessionOverrideConfig *sessionConfig = nullptr) noexcept
{
DesktopFileGuard guard{desktopFile};
if (!guard.try_open()) {
Expand All @@ -152,7 +152,7 @@ void forEachAutostartDesktopFile(T &&func) noexcept
return std::nullopt;
}

if (ApplicationFilter::tryExecCheck(entry) || ApplicationFilter::showInCheck(entry) || ApplicationFilter::hiddenCheck(entry)) {
if (ApplicationFilter::tryExecCheck(entry, desktopFile.desktopId(), sessionConfig) || ApplicationFilter::showInCheck(entry) || ApplicationFilter::hiddenCheck(entry)) {
qInfo() << "autostart application" << desktopFile.desktopId() << "couldn't pass check.";
return std::nullopt;
}
Expand Down Expand Up @@ -228,6 +228,25 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
qWarning() << "new CompatibilityManager failed.";
}

m_sessionOverrideConfig = std::make_unique<SessionOverrideConfig>(this);
connect(m_sessionOverrideConfig.get(), &SessionOverrideConfig::configChanged, this, [this]() {
qCInfo(DDEAM) << "Session override config changed, rebuilding application list.";
doReloadApplications();
});
connect(m_sessionOverrideConfig.get(), &SessionOverrideConfig::overrideChanged,
this, [this](const QString &desktopId, const QString &key) {
auto app = m_applicationList.value(desktopId);
if (!app)
return;
if (key == u"Icon"_s) {
qCInfo(DDEAM) << "Icon override changed for" << desktopId << ", emitting iconsChanged.";
emit app->iconsChanged();
} else if (key == u"Exec"_s || key == u"TryExec"_s) {
qCInfo(DDEAM) << "Exec/TryExec override changed for" << desktopId << ", emitting execsChanged.";
emit app->execsChanged();
}
});

connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &ApplicationManager1Service::ReloadApplications);

// Ensure all directories exist before adding watches
Expand Down Expand Up @@ -482,7 +501,7 @@ void ApplicationManager1Service::scanInstances() noexcept
void ApplicationManager1Service::updateAutostartStatus() noexcept
{
forEachAutostartDesktopFile([this](DesktopFile desktopFile) -> bool {
auto parsedSource = parseAutostartDesktopFile(std::move(desktopFile));
auto parsedSource = parseAutostartDesktopFile(std::move(desktopFile), m_sessionOverrideConfig.get());
if (!parsedSource) {
return false;
}
Expand Down Expand Up @@ -784,6 +803,8 @@ void ApplicationManager1Service::doReloadApplications()

updateAutostartStatus();

m_sessionOverrideConfig->preload(m_applicationList.keys());

reloadMimeInfos();

EventReporter::instance().initialize();
Expand Down
3 changes: 3 additions & 0 deletions src/dbus/applicationmanager1service.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "identifier.h"
#include "compatibilitymanager.h"
#include "prelaunchsplashhelper.h"
#include "sessionoverrideconfig.h"

Q_DECLARE_LOGGING_CATEGORY(DDEAM)

Expand Down Expand Up @@ -90,6 +91,7 @@ class ApplicationManager1Service final : public QObject, protected QDBusContext
[[nodiscard]] const MimeManager1Service &mimeManager() const noexcept { return *m_mimeManager; }
[[nodiscard]] const QStringList &systemdPathEnv() const noexcept { return m_systemdPathEnv; }
[[nodiscard]] QSharedPointer<CompatibilityManager> getCompatibilityManager() const noexcept { return m_compatibilityManager; }
[[nodiscard]] SessionOverrideConfig *getSessionOverrideConfig() const noexcept { return m_sessionOverrideConfig.get(); }
[[nodiscard]] PrelaunchSplashHelper *splashHelper() const noexcept { return m_splashHelper.get(); }
[[nodiscard]] bool isNewSession() const noexcept { return m_isNewSession; }
[[nodiscard]] bool isStartupPhase() const noexcept { return m_startupPhase; }
Expand Down Expand Up @@ -132,6 +134,7 @@ private Q_SLOTS:
bool m_pendingReload{false};
QHash<QString, QSharedPointer<ApplicationService>> m_applicationList;
QSharedPointer<CompatibilityManager> m_compatibilityManager;
std::unique_ptr<SessionOverrideConfig> m_sessionOverrideConfig;
std::unique_ptr<PrelaunchSplashHelper> m_splashHelper;

void scanMimeInfos() noexcept;
Expand Down
41 changes: 38 additions & 3 deletions src/dbus/applicationservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ void ApplicationService::appendExtraEnvironments(QVariantMap &runtimeOptions) co

void ApplicationService::processCompatibility(const QString &action, QVariantMap &options, QString &execStr)
{
const auto originalExec = execStr;
auto compatibilityManager = parent()->getCompatibilityManager();

auto getExec = [action, compatibilityManager](const QString &desktopID) -> QString {
Expand Down Expand Up @@ -193,6 +194,20 @@ void ApplicationService::processCompatibility(const QString &action, QVariantMap
addEnv();
qInfo() << "get compatibility : " << m_desktopSource.desktopId() << " Exec : " << execStr;
}

// Session-specific DConfig overrides (higher priority than compatibility file)
auto sessionConfig = parent()->getSessionOverrideConfig();
if (!sessionConfig) {
return;
}

const auto &groupKey = fromStaticRaw(DesktopFileEntryKey);

auto overrideExec = sessionConfig->getValue(m_desktopSource.desktopId(), groupKey, fromStaticRaw(DesktopEntryExec));
if (overrideExec) {
execStr = SessionOverrideConfig::resolveExecValue(*overrideExec, originalExec);
qInfo() << "session override for" << m_desktopSource.desktopId() << "Exec:" << execStr;
}
}

ApplicationService::ApplicationService(DesktopFile source,
Expand Down Expand Up @@ -322,7 +337,7 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
}
}

if (!shouldBeShown(entry)) {
if (!shouldBeShown(entry, app->desktopFileSource().desktopId(), parent->getSessionOverrideConfig())) {
qDebug() << "application shouldn't be shown:" << app->desktopFileSource().sourcePath();
return nullptr;
}
Expand All @@ -341,14 +356,14 @@ QSharedPointer<ApplicationService> ApplicationService::createApplicationService(
return app;
}

bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept
bool ApplicationService::shouldBeShown(const std::unique_ptr<DesktopEntry> &entry, QStringView desktopId, const SessionOverrideConfig *sessionConfig) noexcept
{
if (ApplicationFilter::hiddenCheck(*entry)) {
qDebug() << "hidden check failed.";
return false;
}

if (ApplicationFilter::tryExecCheck(*entry)) {
if (ApplicationFilter::tryExecCheck(*entry, desktopId, sessionConfig)) {
qDebug() << "tryExec check failed";
return false;
}
Expand Down Expand Up @@ -796,6 +811,16 @@ QStringMap ApplicationService::icons() const noexcept
ret.insert(fromStaticRaw(DesktopFileEntryKey), mainIcon->get().value<QString>());
}

auto sessionConfig = parent()->getSessionOverrideConfig();
if (sessionConfig) {
auto overrideIcon = sessionConfig->getValue(m_desktopSource.desktopId(),
fromStaticRaw(DesktopFileEntryKey),
fromStaticRaw(DesktopEntryIcon));
if (overrideIcon && !overrideIcon->isEmpty()) {
ret.insert(fromStaticRaw(DesktopFileEntryKey), *overrideIcon);
}
}

return ret;
}

Expand Down Expand Up @@ -857,6 +882,16 @@ QStringMap ApplicationService::execs() const noexcept
ret.insert(actionKey, value->get().value<QString>());
}

auto sessionConfig = parent()->getSessionOverrideConfig();
if (sessionConfig) {
auto overrideExec = sessionConfig->getValue(m_desktopSource.desktopId(),
fromStaticRaw(DesktopFileEntryKey),
fromStaticRaw(DesktopEntryExec));
if (overrideExec && !overrideExec->isEmpty()) {
ret.insert(fromStaticRaw(DesktopFileEntryKey), *overrideExec);
}
}

return ret;
}

Expand Down
2 changes: 1 addition & 1 deletion src/dbus/applicationservice.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public Q_SLOTS:
bool m_propertiesForwarderInitialized{false};
QString m_eventAppId;
void updateAfterLaunch(bool isLaunch) noexcept;
static bool shouldBeShown(const std::unique_ptr<DesktopEntry> &entry) noexcept;
static bool shouldBeShown(const std::unique_ptr<DesktopEntry> &entry, QStringView desktopId, const SessionOverrideConfig *sessionConfig = nullptr) noexcept;
[[nodiscard]] bool autostartCheck() const noexcept;
[[nodiscard]] bool autostartSourceFileExists() const noexcept;
[[nodiscard]] bool hasGeneratedAutostartSource() const noexcept;
Expand Down
Loading
Loading