fix: 修复任务栏部分应用图标显示异常

原因:系统通过Bamf服务获取到的应用的路径为空,导致显示图标异常
解决方案:从本地读取索引文件,如果读取到的应用路径错误,则通过本地来加载,找到正确的路径

Log: 修复部分应用图标显示异常的问题
Influence: 打开安全中心、企业微信、微信等应用,观察其在任务栏上的图标
Bug: https://pms.uniontech.com/bug-view-147569.html
Change-Id: I3ba3dea9884808e5edc5559e48b5a272cde754ea
This commit is contained in:
donghualin 2022-11-15 01:34:52 +00:00
parent 282227dc2b
commit b0f10f1219
4 changed files with 186 additions and 25 deletions

View File

@ -193,6 +193,3 @@ bool hasBeginWith(std::string const& fullString, std::string const& ending)
return false; return false;
} }
} }

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "desktopfilereader.h"
#include "basedir.h"
#include <QDir>
#define BAMF_INDEX_NAME "bamf-2.index"
DesktopFileReader *DesktopFileReader::instance()
{
static DesktopFileReader instance;
return &instance;
}
QString DesktopFileReader::fileName(const QString &instanceName) const
{
for (const BamfData &lineData: m_bamfLineData) {
if (lineData.instanceName.toLower() == instanceName.toLower()) {
QString name = lineData.lineData.split("\t").first();
return QString("%1%2").arg(lineData.directory).arg(name);
}
}
// 如果根据instanceName没有找到则根据空格来进行分隔
for (const BamfData &lineData: m_bamfLineData) {
QStringList lines = lineData.lineData.split("\t");
if (lines.size() < 2)
continue;
QStringList cmds = lines[2].split(" ");
if (cmds.size() > 1 && cmds[1].toLower() == instanceName.toLower())
return QString("%1%2").arg(lineData.directory).arg(lines.first());
}
return instanceName;
}
DesktopFileReader::DesktopFileReader()
{
loadDesktopFiles();
}
DesktopFileReader::~DesktopFileReader()
{
}
QStringList DesktopFileReader::applicationDirs() const
{
std::vector<std::string> appDirs = BaseDir::appDirs();
QStringList directions;
for (std::string appDir : appDirs)
directions << appDir.c_str();
return directions;
}
void DesktopFileReader::loadDesktopFiles()
{
QStringList directions = applicationDirs();
for (const QString &direction : directions) {
// 读取后缀名为
QDir dir(direction);
dir.setNameFilters(QStringList() << BAMF_INDEX_NAME);
QFileInfoList fileList = dir.entryInfoList();
if (fileList.size() == 0)
continue;
QFileInfo fileInfo = fileList.at(0);
QFile file(fileInfo.absoluteFilePath());
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
continue;
QList<QPair<QString, QString>> bamfLine;
while (!file.atEnd()) {
QString line = file.readLine();
QStringList part = line.split("\t");
BamfData bamf;
bamf.directory = direction;
if (part.size() > 2)
bamf.instanceName = part[2].trimmed();
bamf.lineData = line;
m_bamfLineData << bamf;
}
}
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DESKTOPFILEREADER_H
#define DESKTOPFILEREADER_H
#include <QObject>
#include <QMap>
struct BamfData {
QString directory;
QString instanceName;
QString lineData;
};
class DesktopFileReader
{
public:
static DesktopFileReader *instance();
QString fileName(const QString &instanceName) const;
protected:
DesktopFileReader();
~DesktopFileReader();
private:
QStringList applicationDirs() const;
void loadDesktopFiles();
private:
QList<BamfData> m_bamfLineData;
};
#endif // DESKTOPFILEREADER_H

View File

@ -28,6 +28,7 @@
#include "basedir.h" #include "basedir.h"
#include "dfile.h" #include "dfile.h"
#include "xcbutils.h" #include "xcbutils.h"
#include "../apps/desktopfilereader.h"
#include <QDebug> #include <QDebug>
#include <QThread> #include <QThread>
@ -474,34 +475,42 @@ AppInfo *WindowIdentify::identifyWindowByGtkAppId(Dock *_dock, WindowInfoX *winI
AppInfo *WindowIdentify::identifyWindowByWmClass(Dock *_dock, WindowInfoX *winInfo, QString &innerId) AppInfo *WindowIdentify::identifyWindowByWmClass(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
{ {
AppInfo *ret = nullptr;
WMClass wmClass = winInfo->getWMClass(); WMClass wmClass = winInfo->getWMClass();
do {
if (wmClass.instanceName.size() > 0) { if (wmClass.instanceName.size() > 0) {
// example: // example:
// WM_CLASS(STRING) = "Brackets", "Brackets" // WM_CLASS(STRING) = "Brackets", "Brackets"
// wm class instance is Brackets // wm class instance is Brackets
// try app id org.deepin.flatdeb.brackets // try app id org.deepin.flatdeb.brackets
ret = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower()); //ret = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower());
if (ret) if (DesktopInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower().toStdString()).isValidDesktop()) {
break; AppInfo *appInfo = new AppInfo("org.deepin.flatdeb." + QString(wmClass.instanceName.c_str()).toLower());
innerId = appInfo->getInnerId();
return appInfo;
}
ret = new AppInfo(wmClass.instanceName.c_str()); if (DesktopInfo(wmClass.instanceName).isValidDesktop()) {
if (ret) AppInfo *appInfo = new AppInfo(wmClass.instanceName.c_str());
break; innerId = appInfo->getInnerId();
return appInfo;
}
} }
if (wmClass.className.size() > 0) { if (wmClass.className.size() > 0) {
ret = new AppInfo(wmClass.className.c_str()); std::string filename = wmClass.className;
if (ret) bool isValid = DesktopInfo(filename).isValidDesktop();
break; if (!isValid) {
filename = DesktopFileReader::instance()->fileName(wmClass.instanceName.c_str()).toStdString();
isValid = DesktopInfo(filename).isValidDesktop();
} }
} while (0);
if (ret) if (isValid) {
innerId = ret->getInnerId(); AppInfo *appInfo = new AppInfo(filename.c_str());
innerId = appInfo->getInnerId();
return appInfo;
}
}
return ret; return nullptr;
} }
AppInfo *WindowIdentify::fixAutostartAppInfo(QString fileName) AppInfo *WindowIdentify::fixAutostartAppInfo(QString fileName)