diff --git a/src/applicationchecker.cpp b/src/applicationchecker.cpp new file mode 100644 index 0000000..bd73c7b --- /dev/null +++ b/src/applicationchecker.cpp @@ -0,0 +1,103 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#include "constant.h" +#include "applicationchecker.h" +#include +#include +#include + +bool ApplicationFilter::hiddenCheck(const std::unique_ptr &entry) noexcept +{ + bool hidden{false}; + auto hiddenVal = entry->value(DesktopFileEntryKey, "Hidden"); + + if (hiddenVal.has_value()) { + bool ok{false}; + hidden = hiddenVal.value().toBoolean(ok); + if (!ok) { + qWarning() << "invalid hidden value:" << *hiddenVal.value().find(defaultKeyStr); + return false; + } + } + return hidden; +} + +bool ApplicationFilter::tryExecCheck(const std::unique_ptr &entry) noexcept +{ + auto tryExecVal = entry->value(DesktopFileEntryKey, "TryExec"); + if (tryExecVal.has_value()) { + bool ok{false}; + auto executable = tryExecVal.value().toString(ok); + if (!ok) { + qWarning() << "invalid TryExec value:" << *tryExecVal.value().find(defaultKeyStr); + return false; + } + + if (executable.startsWith(QDir::separator())) { + QFileInfo info{executable}; + return !(info.exists() and info.isExecutable()); + } + return QStandardPaths::findExecutable(executable).isEmpty(); + } + + return false; +} + +bool ApplicationFilter::showInCheck(const std::unique_ptr &entry) noexcept +{ + auto desktops = QString::fromLocal8Bit(qgetenv("XDG_CURRENT_DESKTOP")).split(':', Qt::SkipEmptyParts); + if (desktops.isEmpty()) { + return true; + } + desktops.removeDuplicates(); + + bool showInCurrentDE{true}; + auto onlyShowInVal = entry->value(DesktopFileEntryKey, "OnlyShowIn"); + while (onlyShowInVal.has_value()) { + bool ok{false}; + auto deStr = onlyShowInVal.value().toString(ok); + if (!ok) { + qWarning() << "invalid OnlyShowIn value:" << *onlyShowInVal.value().find(defaultKeyStr); + break; + } + + auto des = deStr.split(';', Qt::SkipEmptyParts); + if (des.contains("DDE", Qt::CaseInsensitive)) { + des.append("deepin"); + } else if (des.contains("deepin", Qt::CaseInsensitive)) { + des.append("DDE"); + } + des.removeDuplicates(); + + showInCurrentDE = std::any_of( + des.cbegin(), des.cend(), [&desktops](const QString &str) { return desktops.contains(str, Qt::CaseInsensitive); }); + break; + } + + bool notShowInCurrentDE{false}; + auto notShowInVal = entry->value(DesktopFileEntryKey, "NotShowIn"); + while (notShowInVal.has_value()) { + bool ok{false}; + auto deStr = notShowInVal.value().toString(ok); + if (!ok) { + qWarning() << "invalid OnlyShowIn value:" << *notShowInVal.value().find(defaultKeyStr); + break; + } + + auto des = deStr.split(';', Qt::SkipEmptyParts); + if (des.contains("DDE", Qt::CaseInsensitive)) { + des.append("deepin"); + } else if (des.contains("deepin", Qt::CaseInsensitive)) { + des.append("DDE"); + } + des.removeDuplicates(); + + notShowInCurrentDE = std::any_of( + des.cbegin(), des.cend(), [&desktops](const QString &str) { return desktops.contains(str, Qt::CaseInsensitive); }); + break; + } + + return !showInCurrentDE or notShowInCurrentDE; +} diff --git a/src/applicationchecker.h b/src/applicationchecker.h new file mode 100644 index 0000000..ef3350f --- /dev/null +++ b/src/applicationchecker.h @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// +// SPDX-License-Identifier: LGPL-3.0-or-later + +#ifndef APPLICATIONCHECKER_H +#define APPLICATIONCHECKER_H + +#include "desktopentry.h" +#include + +namespace ApplicationFilter { + +bool hiddenCheck(const std::unique_ptr &entry) noexcept; +bool tryExecCheck(const std::unique_ptr &entry) noexcept; +bool showInCheck(const std::unique_ptr &entry) noexcept; + +} // namespace ApplicationFilter +#endif diff --git a/src/dbus/applicationservice.cpp b/src/dbus/applicationservice.cpp index c060da3..764a7ea 100644 --- a/src/dbus/applicationservice.cpp +++ b/src/dbus/applicationservice.cpp @@ -4,6 +4,7 @@ #include "dbus/applicationservice.h" #include "APPobjectmanager1adaptor.h" +#include "applicationchecker.h" #include "applicationmanager1service.h" #include "dbus/instanceadaptor.h" #include "launchoptions.h" @@ -69,12 +70,9 @@ QSharedPointer ApplicationService::createApplicationService( return nullptr; } - if (auto val = entry->value(DesktopFileEntryKey, "Hidden"); val.has_value()) { - bool ok{false}; - if (auto hidden = val.value().toBoolean(ok); ok and hidden) { - qWarning() << "invalid hidden value:" << *val.value().find(defaultKeyStr); - return nullptr; - } + if (!shouldBeShown(entry)) { + qDebug() << "application shouldn't be shown:" << app->desktopFileSource().sourcePath(); + return nullptr; } app->m_entry.reset(entry.release()); @@ -89,6 +87,23 @@ QSharedPointer ApplicationService::createApplicationService( return app; } +bool ApplicationService::shouldBeShown(const std::unique_ptr &entry) noexcept +{ + if (!ApplicationFilter::hiddenCheck(entry)) { + return true; + } + + if (!ApplicationFilter::tryExecCheck(entry)) { + return true; + } + + if (!ApplicationFilter::showInCheck(entry)) { + return true; + } + + return false; +} + QDBusObjectPath ApplicationService::Launch(const QString &action, const QStringList &fields, const QVariantMap &options) { QString execStr; diff --git a/src/dbus/applicationservice.h b/src/dbus/applicationservice.h index 2694634..ee533e4 100644 --- a/src/dbus/applicationservice.h +++ b/src/dbus/applicationservice.h @@ -116,6 +116,7 @@ private: const QString &valueKey, EntryValueType type, const QLocale &locale = getUserLocale()) const noexcept; + static bool shouldBeShown(const std::unique_ptr &entry) noexcept; }; #endif