fix: 修复重启AM后浏览器没有显示在任务栏的问题
修复重启AM后浏览器没有显示在任务栏的问题 Log: Task: https://pms.uniontech.com/task-view-137667.html Influence: 无 Change-Id: I147ff7d2329f0d568496fdb6970925392e485d77
This commit is contained in:
		@ -271,7 +271,7 @@ std::string DesktopInfo::getId()
 | 
			
		||||
    idStr = m_fileName.substr(0, m_fileName.size() - 8); // trim suffix
 | 
			
		||||
    size_t dirPos = idStr.find("/applications/");
 | 
			
		||||
    if (dirPos == std::string::npos)
 | 
			
		||||
        return "";
 | 
			
		||||
        return idStr;
 | 
			
		||||
 | 
			
		||||
    std::string baseDir(idStr.substr(0, dirPos + 14)); // length of "/applications/" is 14
 | 
			
		||||
    std::vector<std::string> appDirs = BaseDir::appDirs();
 | 
			
		||||
 | 
			
		||||
@ -145,3 +145,16 @@ void DString::delQuote(std::string &str)
 | 
			
		||||
        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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -51,6 +51,8 @@ public:
 | 
			
		||||
    // 去除首尾引用
 | 
			
		||||
    static char *delQuote(const char *chars);
 | 
			
		||||
    static void delQuote(std::string &str);
 | 
			
		||||
    // 连接字符串
 | 
			
		||||
    static std::string join(std::vector<std::string> strs, std::string joinStr);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // DSTRING_H
 | 
			
		||||
 | 
			
		||||
@ -155,12 +155,12 @@ Geometry XCBUtils::getWindowGeometry(XWindow xid)
 | 
			
		||||
 | 
			
		||||
XWindow XCBUtils::getActiveWindow()
 | 
			
		||||
{
 | 
			
		||||
   XWindow ret;
 | 
			
		||||
   xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&m_ewmh, m_screenNum);
 | 
			
		||||
   if (!xcb_ewmh_get_active_window_reply(&m_ewmh, cookie, &ret, nullptr))
 | 
			
		||||
       std::cout << "getActiveWindow error" << std::endl;
 | 
			
		||||
    XWindow ret;
 | 
			
		||||
    xcb_get_property_cookie_t cookie = xcb_ewmh_get_active_window(&m_ewmh, m_screenNum);
 | 
			
		||||
    if (!xcb_ewmh_get_active_window_reply(&m_ewmh, cookie, &ret, nullptr))
 | 
			
		||||
        std::cout << "getActiveWindow error" << std::endl;
 | 
			
		||||
 | 
			
		||||
   return ret;
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void XCBUtils::setActiveWindow(XWindow xid)
 | 
			
		||||
@ -441,17 +441,12 @@ WMClass XCBUtils::getWMClass(XWindow xid)
 | 
			
		||||
    xcb_icccm_get_wm_class_reply_t reply;
 | 
			
		||||
    reply.instance_name = nullptr;
 | 
			
		||||
    reply.class_name = nullptr;
 | 
			
		||||
    if (!xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr)) {
 | 
			
		||||
        if (reply.class_name)
 | 
			
		||||
            ret.className.assign(reply.class_name);
 | 
			
		||||
    xcb_icccm_get_wm_class_reply(m_connect, cookie, &reply, nullptr);   // 返回值为0不一定表示失败, 故不做返回值判断
 | 
			
		||||
    if (reply.class_name)
 | 
			
		||||
        ret.className.assign(reply.class_name);
 | 
			
		||||
 | 
			
		||||
        if (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;
 | 
			
		||||
    }
 | 
			
		||||
    if (reply.instance_name)
 | 
			
		||||
        ret.instanceName.assign(reply.instance_name);
 | 
			
		||||
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -25,15 +25,14 @@
 | 
			
		||||
#include "dbusbamfapplication.h"
 | 
			
		||||
 | 
			
		||||
DBusHandler::DBusHandler(Dock *_dock, QObject *parent)
 | 
			
		||||
 : QObject(parent)
 | 
			
		||||
 , dock(_dock)
 | 
			
		||||
 , session(QDBusConnection::sessionBus())
 | 
			
		||||
 , launcherEnd(new LauncherBackEnd("org.deepin.dde.daemon.Launcher1", "/org/deepin/dde/daemon/Launcher1", session, this))
 | 
			
		||||
 , launcherFront(new LauncherFront("org.deepin.dde.Launcher1", "/org/deepin/dde/Launcher1", 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))
 | 
			
		||||
 , kwaylandManager(nullptr)
 | 
			
		||||
 , bamfMatcher(new org::ayatana::bamf::BamfMatcher("org.ayatana.bamf.matcher", "/org/ayatana/bamf/matcher", session, this))
 | 
			
		||||
    : QObject(parent)
 | 
			
		||||
    , dock(_dock)
 | 
			
		||||
    , session(QDBusConnection::sessionBus())
 | 
			
		||||
    , launcherEnd(new LauncherBackEnd("org.deepin.dde.daemon.Launcher1", "/org/deepin/dde/daemon/Launcher1", session, this))
 | 
			
		||||
    , launcherFront(new LauncherFront("org.deepin.dde.Launcher1", "/org/deepin/dde/Launcher1", 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))
 | 
			
		||||
    , kwaylandManager(nullptr)
 | 
			
		||||
{
 | 
			
		||||
    // 关联org.deepin.dde.daemon.Launcher1事件 ItemChanged
 | 
			
		||||
    connect(launcherEnd, &LauncherBackEnd::ItemChanged, this, &DBusHandler::handleLauncherItemChanged);
 | 
			
		||||
@ -200,17 +199,22 @@ void DBusHandler::presentWindows(QList<uint> windows)
 | 
			
		||||
    wm->PresentWindows(windows);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO: 待优化点, 查看Bamf根据windowId获取对应应用desktopFile路径实现方式, 移除bamf依赖
 | 
			
		||||
QString DBusHandler::getDesktopFromWindowByBamf(XWindow windowId)
 | 
			
		||||
{
 | 
			
		||||
    QDBusPendingReply<QString> reply = bamfMatcher->ApplicationForXid(windowId);
 | 
			
		||||
    if (!reply.isValid())
 | 
			
		||||
    QDBusInterface interface0 = QDBusInterface("org.ayatana.bamf", "/org/ayatana/bamf/matcher", "org.ayatana.bamf.matcher");
 | 
			
		||||
    QDBusReply<QString> replyApplication = interface0.call("ApplicationForXid", windowId);
 | 
			
		||||
    QString appObjPath = replyApplication.value();
 | 
			
		||||
    if (!replyApplication.isValid() || appObjPath.isEmpty())
 | 
			
		||||
        return "";
 | 
			
		||||
 | 
			
		||||
    QString appObjPath = reply.value();
 | 
			
		||||
 | 
			
		||||
    org::ayatana::bamf::BamfApplication  bamfApp("org.ayatana.bamf.application", appObjPath, session, this);
 | 
			
		||||
    if (bamfApp.isValid())
 | 
			
		||||
        return bamfApp.DesktopFile();
 | 
			
		||||
    QDBusInterface interface = QDBusInterface("org.ayatana.bamf", appObjPath, "org.ayatana.bamf.application");
 | 
			
		||||
    QDBusReply<QString> replyDesktopFile = interface.call("DesktopFile");
 | 
			
		||||
 | 
			
		||||
    if (replyDesktopFile.isValid())
 | 
			
		||||
        return replyDesktopFile.value();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    return "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -29,7 +29,6 @@
 | 
			
		||||
#include "dbuskwaylandwindowmanager.h"
 | 
			
		||||
#include "windowinfok.h"
 | 
			
		||||
#include "dbusplasmawindow.h"
 | 
			
		||||
#include "dbusbamfmatcher.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
#include <QDBusConnection>
 | 
			
		||||
@ -86,7 +85,6 @@ private:
 | 
			
		||||
    com::deepin::WM *wm;
 | 
			
		||||
    com::deepin::WMSwitcher *wmSwitcher;
 | 
			
		||||
    com::deepin::daemon::kwayland::WindowManager *kwaylandManager;
 | 
			
		||||
    org::ayatana::bamf::BamfMatcher *bamfMatcher;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // DBUSHANDLER_H
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,11 @@ int ProcessInfo::getPpid()
 | 
			
		||||
    return process.getPpid();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ProcessInfo::initWithPid()
 | 
			
		||||
{
 | 
			
		||||
    return hasPid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string ProcessInfo::getExe()
 | 
			
		||||
{
 | 
			
		||||
    return exe;
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,7 @@ public:
 | 
			
		||||
    std::vector<std::string> getArgs();
 | 
			
		||||
    int getPid();
 | 
			
		||||
    int getPpid();
 | 
			
		||||
    bool initWithPid();
 | 
			
		||||
    std::string getExe();
 | 
			
		||||
    std::string getOneCommandLine();
 | 
			
		||||
    std::string getShellScriptLines();
 | 
			
		||||
 | 
			
		||||
@ -34,8 +34,6 @@
 | 
			
		||||
 | 
			
		||||
#define XCB XCBUtils::instance()
 | 
			
		||||
 | 
			
		||||
WindowPatterns WindowIdentify::patterns;
 | 
			
		||||
 | 
			
		||||
static QMap<QString, QString> crxAppIdMap = {
 | 
			
		||||
    {"crx_onfalgmmmaighfmjgegnamdjmhpjpgpi", "apps.com.aiqiyi"},
 | 
			
		||||
    {"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)
 | 
			
		||||
{
 | 
			
		||||
    static WindowPatterns patterns;
 | 
			
		||||
    qInfo() << "identifyWindowByRule: windowId=" << winInfo->getXid();
 | 
			
		||||
    AppInfo *ret = nullptr;
 | 
			
		||||
    QString matchStr = patterns.match(winInfo);
 | 
			
		||||
@ -417,13 +416,11 @@ AppInfo *WindowIdentify::identifyWindowByBamf(Dock *_dock, WindowInfoX *winInfo,
 | 
			
		||||
    XWindow xid = winInfo->getXid();
 | 
			
		||||
    qInfo() << "identifyWindowByBamf:  windowId=" << xid;
 | 
			
		||||
    QString desktopFile;
 | 
			
		||||
    // 重试 bamf 识别,yozo office 的窗口经常要第二次时才能识别到。
 | 
			
		||||
    for (int i=0; i<3; i++) {
 | 
			
		||||
    // 重试 bamf 识别,部分的窗口经常要多次调用才能识别到。
 | 
			
		||||
    for (int i = 0; i < 3; i++) {
 | 
			
		||||
        desktopFile = _dock->getDesktopFromWindowByBamf(xid);
 | 
			
		||||
        if (!desktopFile.isEmpty())
 | 
			
		||||
            break;
 | 
			
		||||
 | 
			
		||||
       QThread::msleep(100);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!desktopFile.isEmpty()) {
 | 
			
		||||
 | 
			
		||||
@ -67,7 +67,6 @@ private:
 | 
			
		||||
    static int32_t getAndroidUengineId(XWindow winId);
 | 
			
		||||
    static QString getAndroidUengineName(XWindow winId);
 | 
			
		||||
 | 
			
		||||
    static WindowPatterns patterns;    // 根据rule识别
 | 
			
		||||
    Dock *dock;
 | 
			
		||||
    QMap<QString, IdentifyFunc> identifyWindowFuns;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -350,7 +350,7 @@ void WindowInfoX::updateHasWmTransientFor()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief WindowInfoX::update 更新窗口信息(仅仅执行一次)
 | 
			
		||||
 * @brief WindowInfoX::update 更新窗口信息(在识别窗口时执行一次)
 | 
			
		||||
 */
 | 
			
		||||
void WindowInfoX::update()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -21,6 +21,9 @@
 | 
			
		||||
 | 
			
		||||
#include "windowpatterns.h"
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "processinfo.h"
 | 
			
		||||
#include "dfile.h"
 | 
			
		||||
#include "dstring.h"
 | 
			
		||||
 | 
			
		||||
#include <QJsonDocument>
 | 
			
		||||
#include <QJsonObject>
 | 
			
		||||
@ -56,53 +59,123 @@ bool equalIgnoreCase(QString key, QString value) {
 | 
			
		||||
 | 
			
		||||
bool regexMatch(QString key, QString 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) {
 | 
			
		||||
    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()
 | 
			
		||||
 : negative(0)
 | 
			
		||||
 : negative(false)
 | 
			
		||||
 , type(0)
 | 
			
		||||
 , flags(0)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool RuleValueParse::parse(QString parsedKey)
 | 
			
		||||
bool RuleValueParse::match(const WindowInfoX *winInfo)
 | 
			
		||||
{
 | 
			
		||||
    QString parsedKey = parseRuleKey(const_cast<WindowInfoX *>(winInfo), key);
 | 
			
		||||
    if (!fn)
 | 
			
		||||
        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()
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
    loadWindowPatterns();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief WindowPatterns::match 匹配窗口
 | 
			
		||||
 * @brief WindowPatterns::match 匹配窗口类型
 | 
			
		||||
 * @param winInfo
 | 
			
		||||
 * @return
 | 
			
		||||
 */
 | 
			
		||||
QString WindowPatterns::match(WindowInfoX *winInfo)
 | 
			
		||||
{
 | 
			
		||||
    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 "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -193,6 +266,7 @@ RuleValueParse WindowPatterns::parseRule(QVector<QString> rule)
 | 
			
		||||
    strncpy(orig, ret.original.toStdString().c_str(), size_t(len));
 | 
			
		||||
    switch (orig[1]) {
 | 
			
		||||
    case ':':
 | 
			
		||||
        break;
 | 
			
		||||
    case '!':
 | 
			
		||||
        ret.flags |= parsedFlagNegative;
 | 
			
		||||
        ret.negative = true;
 | 
			
		||||
@ -227,9 +301,10 @@ RuleValueParse WindowPatterns::parseRule(QVector<QString> rule)
 | 
			
		||||
        ret.fn = regexMatchIgnoreCase;
 | 
			
		||||
        break;
 | 
			
		||||
    default:
 | 
			
		||||
        return ret;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    free(orig);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -30,8 +30,8 @@
 | 
			
		||||
 | 
			
		||||
struct RuleValueParse {
 | 
			
		||||
    RuleValueParse();
 | 
			
		||||
    bool parse(QString parsedKey);
 | 
			
		||||
    bool match(const WindowInfoX *winInfo);
 | 
			
		||||
    static QString parseRuleKey(WindowInfoX *winInfo, const QString &ruleKey);
 | 
			
		||||
    QString key;
 | 
			
		||||
    bool negative;
 | 
			
		||||
    bool (*fn)(QString, QString);
 | 
			
		||||
 | 
			
		||||
@ -153,7 +153,11 @@ void X11Manager::listenXEventUseXCB()
 | 
			
		||||
    */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// 注册X11窗口
 | 
			
		||||
/**
 | 
			
		||||
 * @brief X11Manager::registerWindow 注册X11窗口
 | 
			
		||||
 * @param xid
 | 
			
		||||
 * @return
 | 
			
		||||
 */
 | 
			
		||||
WindowInfoX *X11Manager::registerWindow(XWindow xid)
 | 
			
		||||
{
 | 
			
		||||
    qInfo() << "registWindow: windowId=" << xid;
 | 
			
		||||
@ -249,6 +253,10 @@ void X11Manager::listenRootWindowXEvent()
 | 
			
		||||
    handleClientListChanged();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief X11Manager::listenWindowXEvent 监听窗口事件
 | 
			
		||||
 * @param 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;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user