feat(app-database-service):add a method to find desktop file through WinId, add a START_UP_WMCLASS field to the database.

This commit is contained in:
JunjieBai 2023-08-08 17:00:31 +08:00
parent 20a3b21f75
commit ba31496a89
10 changed files with 117 additions and 11 deletions

View File

@ -53,6 +53,7 @@ public:
//通过pid查找desktop文件 //通过pid查找desktop文件
bool tranPidToDesktopFp(uint pid, QString &desktopfp); bool tranPidToDesktopFp(uint pid, QString &desktopfp);
bool tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopfp);
bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath); bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath);
//下面的接口都不外放,暂时没啥用 //下面的接口都不外放,暂时没啥用

View File

@ -188,6 +188,18 @@ bool AppInfoTablePrivate::tranPidToDesktopFp(uint pid, QString &desktopfp)
} }
} }
bool AppInfoTablePrivate::tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopfp)
{
QDBusReply<QString> reply = m_appDBInterface->call("tranWinIdToDesktopFilePath", QVariant::fromValue(QDBusVariant(winId)));
if (reply.isValid()) {
desktopfp = reply.value();
return true;
} else {
qDebug() << m_appDBInterface->lastError();
return false;
}
}
bool AppInfoTablePrivate::desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath) bool AppInfoTablePrivate::desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath)
{ {
QDBusReply<QString> reply = m_appDBInterface->call("desktopFilePathFromName", desktopFileName); QDBusReply<QString> reply = m_appDBInterface->call("desktopFilePathFromName", desktopFileName);
@ -578,6 +590,11 @@ bool AppInfoTable::desktopFilePathFromName(const QString &desktopFileName, QStri
return d->desktopFilePathFromName(desktopFileName, desktopFilePath); return d->desktopFilePathFromName(desktopFileName, desktopFilePath);
} }
bool AppInfoTable::tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopfp)
{
return d->tranWinIdToDesktopFilePath(winId, desktopfp);
}
//下面接口暂时没啥用,不外放。 //下面接口暂时没啥用,不外放。
bool AppInfoTable::setAppLaunchTimes(const QString &desktopfp, size_t num) bool AppInfoTable::setAppLaunchTimes(const QString &desktopfp, size_t num)
{ {

View File

@ -99,6 +99,8 @@ public:
bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath); bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath);
bool tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopfp);
private: private:
//暂不外放的接口 //暂不外放的接口
bool setAppLaunchTimes(const QString &desktopfp, size_t num); bool setAppLaunchTimes(const QString &desktopfp, size_t num);

View File

@ -106,3 +106,8 @@ bool ApplicationInfo::desktopFilePathFromName(const QString &desktopFileName, QS
{ {
return AppInfoTable::self()->desktopFilePathFromName(desktopFileName, desktopFilePath); return AppInfoTable::self()->desktopFilePathFromName(desktopFileName, desktopFilePath);
} }
bool ApplicationInfo::tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopFilePath)
{
return AppInfoTable::self()->tranWinIdToDesktopFilePath(winId, desktopFilePath);
}

View File

@ -121,6 +121,16 @@ public:
*/ */
bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath); bool desktopFilePathFromName(const QString &desktopFileName, QString &desktopFilePath);
/**
* @brief ApplicationInfo::tranWinIdToDesktopFilePath
* find the desktop file path of the process which corresponds to the winId.
* it will find through tranPidToDesktopFp method first, and then use the winId if the desktop file can not be found by pid;
* @param winId: the winId of the process which need to get its desktop file path
* @param desktopFilePath: the desktop file path of the process corresponding to pid
* @return bool:true if success,else false
*/
bool tranWinIdToDesktopFilePath(const QVariant &winId, QString &desktopFilePath);
Q_SIGNALS: Q_SIGNALS:
void DBOpenFailed(); void DBOpenFailed();
void appDBItems2BUpdate(ApplicationInfoMap); void appDBItems2BUpdate(ApplicationInfoMap);

View File

@ -170,13 +170,10 @@ AppDBManager::AppDBManager(QObject *parent) : QThread(parent), m_database(QSqlDa
//监控应用进程开启 //监控应用进程开启
connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) { connect(KWindowSystem::self(), &KWindowSystem::windowAdded, [ = ](WId id) {
KWindowInfo info(id, NET::Properties(), NET::WM2AllProperties); QDBusVariant dbusVariant(id);
if (info.valid()) { QString desktopFilePath = this->tranWinIdToDesktopFilePath(dbusVariant);
QString desktopfp; if (!desktopFilePath.isEmpty()) {
desktopfp = this->tranPidToDesktopFp(info.pid()); this->updateLaunchTimes(desktopFilePath);
if (!desktopfp.isEmpty()) {
this->updateLaunchTimes(desktopfp);
}
} }
}); });
m_adaptor = new AppDBManagerAdaptor(this); m_adaptor = new AppDBManagerAdaptor(this);
@ -566,9 +563,9 @@ bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath)
"LOCAL_NAME, NAME_EN, NAME_ZH, PINYIN_NAME, " "LOCAL_NAME, NAME_EN, NAME_ZH, PINYIN_NAME, "
"FIRST_LETTER_OF_PINYIN, FIRST_LETTER_ALL, " "FIRST_LETTER_OF_PINYIN, FIRST_LETTER_ALL, "
"ICON, TYPE, CATEGORY, EXEC, COMMENT, MD5, " "ICON, TYPE, CATEGORY, EXEC, COMMENT, MD5, "
"LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY, AUTO_START) " "LAUNCH_TIMES, FAVORITES, LAUNCHED, TOP, LOCK, DONT_DISPLAY, AUTO_START, START_UP_WMCLASS) "
"VALUES(:desktopFilePath, '%0', '%1', :localName, :enName, :zhName, :pinyinName, :firstLetterOfPinyin, :firstLetter2All, " "VALUES(:desktopFilePath, '%0', '%1', :localName, :enName, :zhName, :pinyinName, :firstLetterOfPinyin, :firstLetter2All, "
":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8,%9)") ":icon, :type, :categories, :exec, :comment,'%2',%3,%4,%5,%6,%7,%8,%9, :wmClass)")
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")) .arg(QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss"))
.arg(getAppDesktopMd5(desktopFilePath)) .arg(getAppDesktopMd5(desktopFilePath))
@ -591,6 +588,7 @@ bool AppDBManager::handleDBItemInsert(const QString &desktopFilePath)
sql.bindValue(":categories", desktopfile.value("Categories").toString()); sql.bindValue(":categories", desktopfile.value("Categories").toString());
sql.bindValue(":exec", desktopfile.value("Exec").toString()); sql.bindValue(":exec", desktopfile.value("Exec").toString());
sql.bindValue(":comment", desktopfile.value("Comment").toString()); sql.bindValue(":comment", desktopfile.value("Comment").toString());
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
if (!this->startTransaction()) { if (!this->startTransaction()) {
return false; return false;
@ -767,6 +765,7 @@ bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath)
"CATEGORY=:categories," "CATEGORY=:categories,"
"EXEC=:exec," "EXEC=:exec,"
"COMMENT=:comment," "COMMENT=:comment,"
"START_UP_WMCLASS=:wmClass,"
"MD5='%1'," "MD5='%1',"
"DONT_DISPLAY=%2," "DONT_DISPLAY=%2,"
"AUTO_START=%3 " "AUTO_START=%3 "
@ -787,6 +786,7 @@ bool AppDBManager::handleDBItemUpdate(const QString &desktopFilePath)
sql.bindValue(":categories", desktopfile.value("Categories").toString()); sql.bindValue(":categories", desktopfile.value("Categories").toString());
sql.bindValue(":exec", desktopfile.value("Exec").toString()); sql.bindValue(":exec", desktopfile.value("Exec").toString());
sql.bindValue(":comment", desktopfile.value("Comment").toString()); sql.bindValue(":comment", desktopfile.value("Comment").toString());
sql.bindValue(":wmClass", desktopfile.value("StartupWMClass").toString());
if (!this->startTransaction()) { if (!this->startTransaction()) {
return false; return false;
@ -1530,6 +1530,55 @@ QString AppDBManager::desktopFilePathFromName(const QString &desktopFileName)
return desktopFilePath; return desktopFilePath;
} }
QString AppDBManager::tranWinIdToDesktopFilePath(const QDBusVariant &id)
{
KWindowInfo info(id.variant().toULongLong(), NET::Properties(), NET::WM2AllProperties);
QString desktopFilePath;
if (info.valid()) {
desktopFilePath = this->tranPidToDesktopFp(info.pid());
if (desktopFilePath.isEmpty()) {
QString classClass = info.windowClassClass(); //the 2nd part of WM_CLASS, specified by the application writer
QSqlQuery query(m_database);
query.setForwardOnly(true);
query.prepare("SELECT DESKTOP_FILE_PATH, START_UP_WMCLASS FROM APPINFO WHERE EXEC LIKE :classClass OR DESKTOP_FILE_PATH LIKE :classClass OR START_UP_WMCLASS=:windowClassClass");
query.bindValue(":classClass", "%" + classClass + "%");
query.bindValue(":windowClassClass", classClass);
if (query.exec()) {
QMap<QString, QString> wmClassInfos;
while (query.next()) {
wmClassInfos[query.value("DESKTOP_FILE_PATH").toString()] = query.value("START_UP_WMCLASS").toString();
desktopFilePath = query.value("DESKTOP_FILE_PATH").toString();
}
//筛选后有多个结果时进一步过滤
if (wmClassInfos.size() > 1) {
desktopFilePath.clear();
for (auto it = wmClassInfos.constBegin(); it != wmClassInfos.constEnd(); it++) {
if (it.key().startsWith(AUTOSTART_APP_DESKTOP_PATH)) {
continue;
}
if (it.key().section("/", -1) == (classClass + ".desktop") || it.value() == classClass) {
desktopFilePath = it.key();
break;
}
}
}
if (!desktopFilePath.isEmpty()) {
qDebug() << "WId:" << id.variant() << "Classclass of window:" << classClass << "Desktop file path:" << desktopFilePath;
} else {
qWarning() << "Can not find the desktop file by windowClassClass:" << classClass;
}
} else {
qWarning() << "Fail to exec cmd" << query.lastQuery();
}
}
} else {
qWarning() << "Cannot find desktop flie by WinId:" << id.variant() << "it is invalid" << id.variant().toULongLong();
}
return desktopFilePath;
}
void AppDBManager::insertDBItem(const QString &desktopfd) void AppDBManager::insertDBItem(const QString &desktopfd)
{ {
PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Insert); PendingAppInfo item(desktopfd, PendingAppInfo::HandleType::Insert);

View File

@ -38,7 +38,10 @@
#define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/" #define APP_DATABASE_PATH QDir::homePath()+"/.config/org.ukui/ukui-search/appdata/"
#define APP_DATABASE_NAME "app-info.db" #define APP_DATABASE_NAME "app-info.db"
#define CONNECTION_NAME QLatin1String("ukss-appdb-connection") #define CONNECTION_NAME QLatin1String("ukss-appdb-connection")
static const QString APP_DATABASE_VERSION = QStringLiteral("1.2"); /**
* changelog(1.2 to 1.3): Add the START_UP_WMCLASS field in order to find desktop file path by the windowClassClass.
*/
static const QString APP_DATABASE_VERSION = QStringLiteral("1.3");
namespace UkuiSearch { namespace UkuiSearch {
/** /**
@ -87,6 +90,7 @@ public Q_SLOTS:
//通过pid查找对应的desktop文件 //通过pid查找对应的desktop文件
QString tranPidToDesktopFp(uint pid); QString tranPidToDesktopFp(uint pid);
QString desktopFilePathFromName(const QString &desktopFileName); QString desktopFilePathFromName(const QString &desktopFileName);
QString tranWinIdToDesktopFilePath(const QDBusVariant &id);
//对数据库单条所有信息进行增删改 //对数据库单条所有信息进行增删改
void insertDBItem(const QString &desktopfd); void insertDBItem(const QString &desktopfd);
@ -173,7 +177,8 @@ private:
{"TOP", "INT"}, {"TOP", "INT"},
{"LOCK", "INT"}, {"LOCK", "INT"},
{"DONT_DISPLAY", "INT"}, {"DONT_DISPLAY", "INT"},
{"AUTO_START", "INT"} {"AUTO_START", "INT"},
{"START_UP_WMCLASS", "TEXT"}
}; };
//应用黑名单 //应用黑名单

View File

@ -67,6 +67,14 @@ QString AppDBManagerAdaptor::tranPidToDesktopFp(uint pid)
return out0; return out0;
} }
QString AppDBManagerAdaptor::tranWinIdToDesktopFilePath(const QDBusVariant &id)
{
// handle method call org.ukui.search.appDBManager.tranWinIdToDesktopFilePath
QString out0;
QMetaObject::invokeMethod(parent(), "tranWinIdToDesktopFilePath", Q_RETURN_ARG(QString, out0), Q_ARG(QDBusVariant, id));
return out0;
}
void AppDBManagerAdaptor::updateDBItem(const QString &desktopfd) void AppDBManagerAdaptor::updateDBItem(const QString &desktopfd)
{ {
// handle method call org.ukui.search.appDBManager.updateDBItem // handle method call org.ukui.search.appDBManager.updateDBItem

View File

@ -41,6 +41,10 @@ class AppDBManagerAdaptor: public QDBusAbstractAdaptor
" <arg direction=\"out\" type=\"s\"/>\n" " <arg direction=\"out\" type=\"s\"/>\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopFileName\"/>\n" " <arg direction=\"in\" type=\"s\" name=\"desktopFileName\"/>\n"
" </method>\n" " </method>\n"
" <method name=\"tranWinIdToDesktopFilePath\">\n"
" <arg direction=\"out\" type=\"s\"/>\n"
" <arg direction=\"in\" type=\"v\" name=\"id\"/>\n"
" </method>\n"
" <method name=\"insertDBItem\">\n" " <method name=\"insertDBItem\">\n"
" <arg direction=\"in\" type=\"s\" name=\"desktopfd\"/>\n" " <arg direction=\"in\" type=\"s\" name=\"desktopfd\"/>\n"
" </method>\n" " </method>\n"
@ -87,6 +91,7 @@ public Q_SLOTS: // METHODS
void insertDBItem(const QString &desktopfd); void insertDBItem(const QString &desktopfd);
void setValue(UkuiSearch::ApplicationInfoMap infos2BSet); void setValue(UkuiSearch::ApplicationInfoMap infos2BSet);
QString tranPidToDesktopFp(uint pid); QString tranPidToDesktopFp(uint pid);
QString tranWinIdToDesktopFilePath(const QDBusVariant &id);
void updateDBItem(const QString &desktopfd); void updateDBItem(const QString &desktopfd);
void updateFavoritesState(const QString &desktopFilePath); void updateFavoritesState(const QString &desktopFilePath);
void updateFavoritesState(const QString &desktopFilePath, uint num); void updateFavoritesState(const QString &desktopFilePath, uint num);

View File

@ -9,6 +9,10 @@
<arg type="s" direction="out"/> <arg type="s" direction="out"/>
<arg name="desktopFileName" type="s" direction="in"/> <arg name="desktopFileName" type="s" direction="in"/>
</method> </method>
<method name="tranWinIdToDesktopFilePath">
<arg type="s" direction="out"/>
<arg name="id" type="v" direction="in"/>
</method>
<method name="insertDBItem"> <method name="insertDBItem">
<arg name="desktopfd" type="s" direction="in"/> <arg name="desktopfd" type="s" direction="in"/>
</method> </method>