fix: 修复重启AM后浏览器没有显示在任务栏的问题

修复重启AM后浏览器没有显示在任务栏的问题

Log:
Task: https://pms.uniontech.com/task-view-137667.html
Influence: 无
Change-Id: I147ff7d2329f0d568496fdb6970925392e485d77
This commit is contained in:
weizhixiang 2022-05-27 21:03:41 +08:00
parent e817c291bc
commit 42d50bae4f
14 changed files with 152 additions and 55 deletions

View File

@ -271,7 +271,7 @@ std::string DesktopInfo::getId()
idStr = m_fileName.substr(0, m_fileName.size() - 8); // trim suffix idStr = m_fileName.substr(0, m_fileName.size() - 8); // trim suffix
size_t dirPos = idStr.find("/applications/"); size_t dirPos = idStr.find("/applications/");
if (dirPos == std::string::npos) if (dirPos == std::string::npos)
return ""; return idStr;
std::string baseDir(idStr.substr(0, dirPos + 14)); // length of "/applications/" is 14 std::string baseDir(idStr.substr(0, dirPos + 14)); // length of "/applications/" is 14
std::vector<std::string> appDirs = BaseDir::appDirs(); std::vector<std::string> appDirs = BaseDir::appDirs();

View File

@ -145,3 +145,16 @@ void DString::delQuote(std::string &str)
str.assign(str.substr(1, str.size() - 2)); str.assign(str.substr(1, str.size() - 2));
} }
std::string DString::join(std::vector<std::string> strs, std::string joinStr)
{
std::string ret;
for (uint i = 0; i < strs.size(); i++) {
if (i < strs.size() - 1) {
ret += strs[i] + joinStr;
} else {
ret += strs[i];
}
}
return ret;
}

View File

@ -51,6 +51,8 @@ public:
// 去除首尾引用 // 去除首尾引用
static char *delQuote(const char *chars); static char *delQuote(const char *chars);
static void delQuote(std::string &str); static void delQuote(std::string &str);
// 连接字符串
static std::string join(std::vector<std::string> strs, std::string joinStr);
}; };
#endif // DSTRING_H #endif // DSTRING_H

View File

@ -441,18 +441,13 @@ WMClass XCBUtils::getWMClass(XWindow xid)
xcb_icccm_get_wm_class_reply_t reply; xcb_icccm_get_wm_class_reply_t reply;
reply.instance_name = nullptr; reply.instance_name = nullptr;
reply.class_name = nullptr; reply.class_name = nullptr;
if (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) { xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr); // 返回值为0不一定表示失败 故不做返回值判断
if (reply.class_name) if (reply.class_name)
ret.className.assign(reply.class_name); ret.className.assign(reply.class_name);
if (reply.instance_name) if (reply.instance_name)
ret.instanceName.assign(reply.instance_name); ret.instanceName.assign(reply.instance_name);
//xcb_icccm_get_wm_class_reply_wipe(&reply);
} else {
std::cout << xid << " getWMClass error" << std::endl;
}
return ret; return ret;
} }

View File

@ -33,7 +33,6 @@ DBusHandler::DBusHandler(Dock *_dock, QObject *parent)
, wm(new com::deepin::WM("com.deepin.wm", "/com/deepin/wm", session, this)) , wm(new com::deepin::WM("com.deepin.wm", "/com/deepin/wm", session, this))
, wmSwitcher(new com::deepin::WMSwitcher("com.deepin.wmWMSwitcher", "/com/deepin/WMSwitcher", session, this)) , wmSwitcher(new com::deepin::WMSwitcher("com.deepin.wmWMSwitcher", "/com/deepin/WMSwitcher", session, this))
, kwaylandManager(nullptr) , kwaylandManager(nullptr)
, bamfMatcher(new org::ayatana::bamf::BamfMatcher("org.ayatana.bamf.matcher", "/org/ayatana/bamf/matcher", session, this))
{ {
// 关联org.deepin.dde.daemon.Launcher1事件 ItemChanged // 关联org.deepin.dde.daemon.Launcher1事件 ItemChanged
connect(launcherEnd, &LauncherBackEnd::ItemChanged, this, &DBusHandler::handleLauncherItemChanged); connect(launcherEnd, &LauncherBackEnd::ItemChanged, this, &DBusHandler::handleLauncherItemChanged);
@ -200,17 +199,22 @@ void DBusHandler::presentWindows(QList<uint> windows)
wm->PresentWindows(windows); wm->PresentWindows(windows);
} }
// TODO: 待优化点, 查看Bamf根据windowId获取对应应用desktopFile路径实现方式, 移除bamf依赖
QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId) QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId)
{ {
QDBusPendingReply<QString> reply = bamfMatcher->ApplicationForXid(windowId); QDBusInterface interface0 = QDBusInterface("org.ayatana.bamf", "/org/ayatana/bamf/matcher", "org.ayatana.bamf.matcher");
if (!reply.isValid()) QDBusReply<QString> replyApplication = interface0.call("ApplicationForXid", windowId);
QString appObjPath = replyApplication.value();
if (!replyApplication.isValid() || appObjPath.isEmpty())
return ""; return "";
QString appObjPath = reply.value();
org::ayatana::bamf::BamfApplication bamfApp("org.ayatana.bamf.application", appObjPath, session, this); QDBusInterface interface = QDBusInterface("org.ayatana.bamf", appObjPath, "org.ayatana.bamf.application");
if (bamfApp.isValid()) QDBusReply<QString> replyDesktopFile = interface.call("DesktopFile");
return bamfApp.DesktopFile();
if (replyDesktopFile.isValid())
return replyDesktopFile.value();
return ""; return "";
} }

View File

@ -29,7 +29,6 @@
#include "dbuskwaylandwindowmanager.h" #include "dbuskwaylandwindowmanager.h"
#include "windowinfok.h" #include "windowinfok.h"
#include "dbusplasmawindow.h" #include "dbusplasmawindow.h"
#include "dbusbamfmatcher.h"
#include <QObject> #include <QObject>
#include <QDBusConnection> #include <QDBusConnection>
@ -86,7 +85,6 @@ private:
com::deepin::WM *wm; com::deepin::WM *wm;
com::deepin::WMSwitcher *wmSwitcher; com::deepin::WMSwitcher *wmSwitcher;
com::deepin::daemon::kwayland::WindowManager *kwaylandManager; com::deepin::daemon::kwayland::WindowManager *kwaylandManager;
org::ayatana::bamf::BamfMatcher *bamfMatcher;
}; };
#endif // DBUSHANDLER_H #endif // DBUSHANDLER_H

View File

@ -116,6 +116,11 @@ int ProcessInfo::getPpid()
return process.getPpid(); return process.getPpid();
} }
bool ProcessInfo::initWithPid()
{
return hasPid;
}
std::string ProcessInfo::getExe() std::string ProcessInfo::getExe()
{ {
return exe; return exe;

View File

@ -39,6 +39,7 @@ public:
std::vector<std::string> getArgs(); std::vector<std::string> getArgs();
int getPid(); int getPid();
int getPpid(); int getPpid();
bool initWithPid();
std::string getExe(); std::string getExe();
std::string getOneCommandLine(); std::string getOneCommandLine();
std::string getShellScriptLines(); std::string getShellScriptLines();

View File

@ -34,8 +34,6 @@
#define XCB XCBUtils::instance() #define XCB XCBUtils::instance()
WindowPatterns WindowIdentify::patterns;
static QMap<QString, QString> crxAppIdMap = { static QMap<QString, QString> crxAppIdMap = {
{"crx_onfalgmmmaighfmjgegnamdjmhpjpgpi", "apps.com.aiqiyi"}, {"crx_onfalgmmmaighfmjgegnamdjmhpjpgpi", "apps.com.aiqiyi"},
{"crx_gfhkopakpiiaeocgofdpcpjpdiglpkjl", "apps.cn.kugou.hd"}, {"crx_gfhkopakpiiaeocgofdpcpjpdiglpkjl", "apps.cn.kugou.hd"},
@ -385,6 +383,7 @@ AppInfo *WindowIdentify::identifyWindowByCrxId(Dock *_dock, WindowInfoX *winInfo
AppInfo *WindowIdentify::identifyWindowByRule(Dock *_dock, WindowInfoX *winInfo, QString &innerId) AppInfo *WindowIdentify::identifyWindowByRule(Dock *_dock, WindowInfoX *winInfo, QString &innerId)
{ {
static WindowPatterns patterns;
qInfo() << "identifyWindowByRule: windowId=" << winInfo->getXid(); qInfo() << "identifyWindowByRule: windowId=" << winInfo->getXid();
AppInfo *ret = nullptr; AppInfo *ret = nullptr;
QString matchStr = patterns.match(winInfo); QString matchStr = patterns.match(winInfo);
@ -417,13 +416,11 @@ AppInfo *WindowIdentify::identifyWindowByBamf(Dock *_dock, WindowInfoX *winInfo,
XWindow xid = winInfo->getXid(); XWindow xid = winInfo->getXid();
qInfo() << "identifyWindowByBamf: windowId=" << xid; qInfo() << "identifyWindowByBamf: windowId=" << xid;
QString desktopFile; QString desktopFile;
// 重试 bamf 识别,yozo office 的窗口经常要第二次时才能识别到。 // 重试 bamf 识别,部分的窗口经常要多次调用才能识别到。
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
desktopFile = _dock->getDesktopFromWindowByBamf(xid); desktopFile = _dock->getDesktopFromWindowByBamf(xid);
if (!desktopFile.isEmpty()) if (!desktopFile.isEmpty())
break; break;
QThread::msleep(100);
} }
if (!desktopFile.isEmpty()) { if (!desktopFile.isEmpty()) {

View File

@ -67,7 +67,6 @@ private:
static int32_t getAndroidUengineId(XWindow winId); static int32_t getAndroidUengineId(XWindow winId);
static QString getAndroidUengineName(XWindow winId); static QString getAndroidUengineName(XWindow winId);
static WindowPatterns patterns; // 根据rule识别
Dock *dock; Dock *dock;
QMap<QString, IdentifyFunc> identifyWindowFuns; QMap<QString, IdentifyFunc> identifyWindowFuns;
}; };

View File

@ -350,7 +350,7 @@ void WindowInfoX::updateHasWmTransientFor()
} }
/** /**
* @brief WindowInfoX::update * @brief WindowInfoX::update
*/ */
void WindowInfoX::update() void WindowInfoX::update()
{ {

View File

@ -21,6 +21,9 @@
#include "windowpatterns.h" #include "windowpatterns.h"
#include "common.h" #include "common.h"
#include "processinfo.h"
#include "dfile.h"
#include "dstring.h"
#include <QJsonDocument> #include <QJsonDocument>
#include <QJsonObject> #include <QJsonObject>
@ -56,53 +59,123 @@ bool equalIgnoreCase(QString key, QString value) {
bool regexMatch(QString key, QString value) { bool regexMatch(QString key, QString value) {
QRegExp ruleRegex(value); QRegExp ruleRegex(value);
return ruleRegex.exactMatch(key); bool ret = ruleRegex.exactMatch(key);
// 配置中\.exe$ 在V20中go代码可以匹配以.exe结尾的字符串, Qt中使用\.*exe$匹配以.exe结尾字符串失败暂时做兼容处理
if (!ret && value == "\\.exe$") {
ret = key.endsWith(".exe");
}
return ret;
} }
bool regexMatchIgnoreCase(QString key, QString value) { bool regexMatchIgnoreCase(QString key, QString value) {
QRegExp ruleRegex(value, Qt::CaseInsensitive); QRegExp ruleRegex(value, Qt::CaseInsensitive);
return ruleRegex.exactMatch(key); bool ret = ruleRegex.exactMatch(key);
// 配置中\.exe$ 在V20中go代码可以匹配以.exe结尾的字符串, Qt中使用\.*exe$匹配以.exe结尾字符串失败暂时做兼容处理
if (!ret && value == "\\.exe$") {
QString _key = key.toLower();
ret = _key.endsWith(".exe");
}
return ret;
} }
RuleValueParse::RuleValueParse() RuleValueParse::RuleValueParse()
: negative(0) : negative(false)
, type(0) , type(0)
, flags(0) , flags(0)
{ {
} }
bool RuleValueParse::parse(QString parsedKey) bool RuleValueParse::match(const WindowInfoX *winInfo)
{ {
QString parsedKey = parseRuleKey(const_cast<WindowInfoX *>(winInfo), key);
if (!fn) if (!fn)
return false; return false;
return negative ? fn(parsedKey, value) : !fn(parsedKey, value); bool ret = fn(parsedKey, value);
return negative ? !ret : ret;
} }
bool RuleValueParse::match(const WindowInfoX *winInfo) QString RuleValueParse::parseRuleKey(WindowInfoX *winInfo, const QString &ruleKey)
{ {
QString parsedKey; ProcessInfo * process = winInfo->getProcess();
if (ruleKey == "hasPid") {
if (process && process->initWithPid()) {
return "t";
}
return "f";
} else if (ruleKey == "exec") {
if (process) {
// 返回执行文件baseName
auto baseName = DFile::base(process->getExe());
return baseName.empty() ? "" : baseName.c_str();
}
} else if (ruleKey == "arg") {
if (process) {
// 返回命令行参数
auto ret = DString::join(process->getArgs(), "");
return ret.empty() ? "" : ret.c_str();
}
} else if (ruleKey == "wmi") {
// 窗口实例
auto wmClass = winInfo->getWMClass();
if (!wmClass.instanceName.empty())
return wmClass.instanceName.c_str();
} else if (ruleKey == "wmc") {
// 窗口类型
auto wmClass = winInfo->getWMClass();
if (!wmClass.className.empty())
return wmClass.className.c_str();
} else if (ruleKey == "wmn") {
// 窗口名称
return winInfo->getWMName();
} else if (ruleKey == "wmrole") {
// 窗口角色
return winInfo->getWmRole();
} else {
const QString envPrefix = "env.";
if (ruleKey.startsWith(envPrefix)) {
QString envName = ruleKey.mid(envPrefix.size());
if (winInfo->getProcess()) {
auto ret = process->getEnv(envName.toStdString());
return ret.empty() ? "" : ret.c_str();
}
}
}
return parse(parsedKey); return "";
} }
WindowPatterns::WindowPatterns() WindowPatterns::WindowPatterns()
{ {
loadWindowPatterns();
} }
/** /**
* @brief WindowPatterns::match * @brief WindowPatterns::match
* @param winInfo * @param winInfo
* @return * @return
*/ */
QString WindowPatterns::match(WindowInfoX *winInfo) QString WindowPatterns::match(WindowInfoX *winInfo)
{ {
for (auto pattern : patterns) { for (auto pattern : patterns) {
bool patternOk = true;
for (auto rule : pattern.parseRules) {
if (!rule.match(winInfo)) {
patternOk = false;
break;
} }
}
if (patternOk) {
// 匹配成功
return pattern.result;
}
}
// 匹配失败
return ""; return "";
} }
@ -193,6 +266,7 @@ RuleValueParse WindowPatterns::parseRule(QVector<QString> rule)
strncpy(orig, ret.original.toStdString().c_str(), size_t(len)); strncpy(orig, ret.original.toStdString().c_str(), size_t(len));
switch (orig[1]) { switch (orig[1]) {
case ':': case ':':
break;
case '!': case '!':
ret.flags |= parsedFlagNegative; ret.flags |= parsedFlagNegative;
ret.negative = true; ret.negative = true;
@ -227,9 +301,10 @@ RuleValueParse WindowPatterns::parseRule(QVector<QString> rule)
ret.fn = regexMatchIgnoreCase; ret.fn = regexMatchIgnoreCase;
break; break;
default: default:
return ret; break;
} }
free(orig);
return ret; return ret;
} }

View File

@ -30,8 +30,8 @@
struct RuleValueParse { struct RuleValueParse {
RuleValueParse(); RuleValueParse();
bool parse(QString parsedKey);
bool match(const WindowInfoX *winInfo); bool match(const WindowInfoX *winInfo);
static QString parseRuleKey(WindowInfoX *winInfo, const QString &ruleKey);
QString key; QString key;
bool negative; bool negative;
bool (*fn)(QString, QString); bool (*fn)(QString, QString);

View File

@ -153,7 +153,11 @@ void X11Manager::listenXEventUseXCB()
*/ */
} }
// 注册X11窗口 /**
* @brief X11Manager::registerWindow X11窗口
* @param xid
* @return
*/
WindowInfoX *X11Manager::registerWindow(XWindow xid) WindowInfoX *X11Manager::registerWindow(XWindow xid)
{ {
qInfo() << "registWindow: windowId=" << xid; qInfo() << "registWindow: windowId=" << xid;
@ -249,6 +253,10 @@ void X11Manager::listenRootWindowXEvent()
handleClientListChanged(); handleClientListChanged();
} }
/**
* @brief X11Manager::listenWindowXEvent
* @param winInfo
*/
void X11Manager::listenWindowXEvent(WindowInfoX *winInfo) void X11Manager::listenWindowXEvent(WindowInfoX *winInfo)
{ {
uint32_t eventMask = EventMask::XCB_EVENT_MASK_PROPERTY_CHANGE | EventMask::XCB_EVENT_MASK_STRUCTURE_NOTIFY | EventMask::XCB_EVENT_MASK_VISIBILITY_CHANGE; uint32_t eventMask = EventMask::XCB_EVENT_MASK_PROPERTY_CHANGE | EventMask::XCB_EVENT_MASK_STRUCTURE_NOTIFY | EventMask::XCB_EVENT_MASK_VISIBILITY_CHANGE;