fix: 修复任务栏应用图标右键失效问题

修复任务栏应用图标右键失效问题

Log:
Task: https://pms.uniontech.com/task-view-140805.html
Influence: 保证任务栏应用右键菜单功能正常
Change-Id: Iedb3e0394567c855f7760dc52a06d8ad1073001e
This commit is contained in:
weizhixiang 2022-05-31 17:20:39 +08:00
parent 602f7c55e1
commit 7cb147fb39
26 changed files with 288 additions and 224 deletions

View File

@ -1,51 +0,0 @@
#include "exportwindowinfo.h"
#include <QtDebug>
ExportWindowInfo::ExportWindowInfo()
: m_xid(0)
, m_flash(false)
{
}
ExportWindowInfo::ExportWindowInfo(uint32_t xid, const QString &title, bool flash)
: m_xid(xid)
, m_title(title)
, m_flash(flash)
{
}
QDebug operator<<(QDebug debug, const ExportWindowInfo &info)
{
debug << QString("ExportWindowInfo(%1, %2, %3)").arg(info.m_xid)
.arg(info.m_title)
.arg(info.m_flash);
return debug;
}
QDBusArgument &operator<<(QDBusArgument &arg, const ExportWindowInfo &info)
{
arg.beginStructure();
arg << info.m_xid << info.m_title << info.m_flash;
arg.endStructure();
return arg;
}
const QDBusArgument &operator>>(const QDBusArgument &arg, ExportWindowInfo &info)
{
arg.beginStructure();
arg >> info.m_xid >> info.m_title >> info.m_flash;
arg.endStructure();
return arg;
}
void registerExportWindowInfoMetaType()
{
qRegisterMetaType<ExportWindowInfo>("ExportWindowInfo");
qDBusRegisterMetaType<ExportWindowInfo>();
}

View File

@ -1,31 +0,0 @@
#ifndef EXPORTWINDOWINFO_H
#define EXPORTWINDOWINFO_H
#include <QRect>
#include <QDBusMetaType>
struct ExportWindowInfo
{
public:
ExportWindowInfo();
ExportWindowInfo(uint32_t xid, const QString &title, bool flash);
friend QDebug operator<<(QDebug debug, const ExportWindowInfo &rect);
friend const QDBusArgument &operator>>(const QDBusArgument &arg, ExportWindowInfo &rect);
friend QDBusArgument &operator<<(QDBusArgument &arg, const ExportWindowInfo &rect);
uint32_t getXid() {return m_xid;}
QString getTitle() {return m_title;}
bool getFlash() {return m_flash;}
private:
uint32_t m_xid;
QString m_title;
bool m_flash;
};
Q_DECLARE_METATYPE(ExportWindowInfo)
void registerExportWindowInfoMetaType();
#endif // EXPORTWINDOWINFO_H

View File

@ -1,18 +0,0 @@
#include "exportwindowinfolist.h"
void sortExprotWindowInfoList(ExportWindowInfoList &list)
{
qSort(list.begin(), list.end(), compareWindowXid);
}
void registerExportWindowInfoListMetaType()
{
qRegisterMetaType<ExportWindowInfoList>("ExportWindowInfoList");
qDBusRegisterMetaType<ExportWindowInfoList>();
}
// 按xid进行排序
bool compareWindowXid(ExportWindowInfo &info1, ExportWindowInfo &info2)
{
return info1.getXid() < info2.getXid();
}

View File

@ -1,18 +0,0 @@
#ifndef EXPORTWINDOWINFOLIST_H
#define EXPORTWINDOWINFOLIST_H
#include "exportwindowinfo.h"
#include <QtCore/QList>
#include <QDBusMetaType>
typedef QList<ExportWindowInfo> ExportWindowInfoList;
bool compareWindowXid(ExportWindowInfo &info1, ExportWindowInfo &info2);
void sortExprotWindowInfoList(ExportWindowInfoList &list);
Q_DECLARE_METATYPE(ExportWindowInfoList)
void registerExportWindowInfoListMetaType();
#endif // EXPORTWINDOWINFOLIST_H

View File

@ -0,0 +1,48 @@
#include "windowinfomap.h"
#include <QDBusMetaType>
void registerWindowInfoMapMetaType()
{
registerWindowInfoMetaType();
qRegisterMetaType<WindowInfoMap>("WindowInfoMap");
qDBusRegisterMetaType<WindowInfoMap>();
}
void registerWindowInfoMetaType()
{
qRegisterMetaType<WindowInfo>("WindowInfo");
qDBusRegisterMetaType<WindowInfo>();
}
QDebug operator<<(QDebug argument, const WindowInfo &info)
{
argument << '(' << info.title << ',' << info.attention << ')';
return argument;
}
QDBusArgument &operator<<(QDBusArgument &argument, const WindowInfo &info)
{
argument.beginStructure();
argument << info.title << info.attention;
argument.endStructure();
return argument;
}
const QDBusArgument &operator>>(const QDBusArgument &argument, WindowInfo &info)
{
argument.beginStructure();
argument >> info.title >> info.attention;
argument.endStructure();
return argument;
}
bool WindowInfo::operator==(const WindowInfo &rhs) const
{
return attention == rhs.attention &&
title == rhs.title;
}

View File

@ -0,0 +1,29 @@
#ifndef WINDOWINFOLIST_H
#define WINDOWINFOLIST_H
#include <QDebug>
#include <QList>
#include <QDBusArgument>
class WindowInfo
{
public:
friend QDebug operator<<(QDebug argument, const WindowInfo &info);
friend QDBusArgument &operator<<(QDBusArgument &argument, const WindowInfo &info);
friend const QDBusArgument &operator>>(const QDBusArgument &argument, WindowInfo &info);
bool operator==(const WindowInfo &rhs) const;
public:
bool attention;
QString title;
};
Q_DECLARE_METATYPE(WindowInfo)
typedef QMap<quint32, WindowInfo> WindowInfoMap;
Q_DECLARE_METATYPE(WindowInfoMap)
void registerWindowInfoMetaType();
void registerWindowInfoMapMetaType();
#endif // WINDOWINFOLIST_H

View File

@ -204,6 +204,7 @@ std::vector<DesktopAction> DesktopInfo::getActions()
DesktopAction action; DesktopAction action;
action.name = m_keyFile.getLocaleStr(mainKey, KeyName, ""); action.name = m_keyFile.getLocaleStr(mainKey, KeyName, "");
action.exec = m_keyFile.getStr(mainKey, KeyExec); action.exec = m_keyFile.getStr(mainKey, KeyExec);
action.section = mainKey;
actions.push_back(action); actions.push_back(action);
} }
} }

View File

@ -1,3 +1,24 @@
/*
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: weizhixiang <weizhixiang@uniontech.com>
*
* Maintainer: weizhixiang <weizhixiang@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 "gsetting.h" #include "gsetting.h"
#include <iostream> #include <iostream>

View File

@ -1,3 +1,24 @@
/*
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: weizhixiang <weizhixiang@uniontech.com>
*
* Maintainer: weizhixiang <weizhixiang@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 GSETTING_H #ifndef GSETTING_H
#define GSETTING_H #define GSETTING_H

View File

@ -301,23 +301,29 @@ std::string XCBUtils::getWMIconName(XWindow xid)
std::vector<WMIcon> XCBUtils::getWMIcon(XWindow xid) std::vector<WMIcon> XCBUtils::getWMIcon(XWindow xid)
{ {
std::vector<WMIcon> ret; std::vector<WMIcon> ret;
/* xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon(&m_ewmh, xid);
xcb_get_property_cookie_t cookie = xcb_ewmh_get_wm_icon(&ewmh, xid);
xcb_ewmh_get_wm_icon_reply_t reply; xcb_ewmh_get_wm_icon_reply_t reply;
if (xcb_ewmh_get_wm_icon_reply(&ewmh, cookie, &reply, nullptr)) { if (xcb_ewmh_get_wm_icon_reply(&m_ewmh, cookie, &reply, nullptr)) {
xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply); xcb_ewmh_wm_icon_iterator_t iter = xcb_ewmh_get_wm_icon_iterator(&reply);
auto fcn = [](xcb_ewmh_wm_icon_iterator_t it) { auto fcn = [](xcb_ewmh_wm_icon_iterator_t it) {
std::vector<BYTE> data; std::vector<BYTE> ret;
uint32_t *dat = it.data; // data数据是按行从左至右从上至下排列
int area = it.width * it.height; uint32_t *data = it.data;
for (int i = 0; i < (2 + area) * 4; i++, dat++) { // TODO check data accuracy if (!data) {
data.push_back(*dat); return ret;
} }
return data;
// 根据宽高获取每个位置的数据每行前有两个位置offset
int area = it.width * it.height;
for (int i = 0; i < (2 + area) * 4; i++, data++) {
ret.push_back(*data);
}
return ret;
}; };
ret.push_back({iter.width, iter.height, fcn(iter)}); ret.push_back({iter.width, iter.height, fcn(iter)});
// 获取不同size图标数据
while (iter.rem >= 1) { while (iter.rem >= 1) {
xcb_ewmh_get_wm_icon_next(&iter); xcb_ewmh_get_wm_icon_next(&iter);
ret.push_back({iter.width, iter.height, fcn(iter)}); ret.push_back({iter.width, iter.height, fcn(iter)});
@ -325,7 +331,7 @@ std::vector<WMIcon> XCBUtils::getWMIcon(XWindow xid)
xcb_ewmh_get_wm_icon_reply_wipe(&reply); // clear xcb_ewmh_get_wm_icon_reply_wipe(&reply); // clear
} }
*/
return ret; return ret;
} }

View File

@ -206,7 +206,7 @@ public:
// 获取窗口图标 _NET_WM_ICON_NAME // 获取窗口图标 _NET_WM_ICON_NAME
std::string getWMIconName(XWindow xid); std::string getWMIconName(XWindow xid);
// _NET_WM_ICON // 获取窗口图标信息 _NET_WM_ICON
std::vector<WMIcon> getWMIcon(XWindow xid); std::vector<WMIcon> getWMIcon(XWindow xid);
// WM_CLIENT_LEADER // WM_CLIENT_LEADER

View File

@ -29,10 +29,8 @@ DBusAdaptorDock::DBusAdaptorDock(QObject *parent)
Dock *dock = static_cast<Dock *>(QObject::parent()); Dock *dock = static_cast<Dock *>(QObject::parent());
if (dock) { if (dock) {
connect(dock, &Dock::serviceRestarted, this, [&] { connect(dock, &Dock::serviceRestarted, this, &DBusAdaptorDock::ServiceRestarted);
Q_EMIT ServiceRestarted();}); connect(dock, &Dock::entryAdded, this, &DBusAdaptorDock::EntryAdded);
connect(dock, &Dock::entryAdded, this, [&](QString entryObjPath, int32_t index){
Q_EMIT EntryAdded(QDBusObjectPath(entryObjPath), index);});
connect(dock, &Dock::entryRemoved, this, &DBusAdaptorDock::EntryRemoved); connect(dock, &Dock::entryRemoved, this, &DBusAdaptorDock::EntryRemoved);
connect(dock, &Dock::hideStateChanged, this, &DBusAdaptorDock::HideStateChanged); connect(dock, &Dock::hideStateChanged, this, &DBusAdaptorDock::HideStateChanged);
connect(dock, &Dock::frontendWindowRectChanged, this, &DBusAdaptorDock::FrontendWindowRectChanged); connect(dock, &Dock::frontendWindowRectChanged, this, &DBusAdaptorDock::FrontendWindowRectChanged);

View File

@ -27,11 +27,12 @@ DBusAdaptorEntry::DBusAdaptorEntry(QObject *parent)
// constructor // constructor
setAutoRelaySignals(true); setAutoRelaySignals(true);
if (QMetaType::type("ExportWindowInfo") == QMetaType::UnknownType)
registerExportWindowInfoMetaType();
if (QMetaType::type("ExportWindowInfoList") == QMetaType::UnknownType) if (QMetaType::type("WindowInfo") == QMetaType::UnknownType)
registerExportWindowInfoListMetaType(); registerWindowInfoMetaType();
if (QMetaType::type("WindowInfoMap") == QMetaType::UnknownType)
registerWindowInfoMapMetaType();
Entry *entry = static_cast<Entry *>(QObject::parent()); Entry *entry = static_cast<Entry *>(QObject::parent());
if (entry) { if (entry) {
@ -90,7 +91,7 @@ QString DBusAdaptorEntry::name() const
return parent()->getName(); return parent()->getName();
} }
ExportWindowInfoList DBusAdaptorEntry::windowInfos() WindowInfoMap DBusAdaptorEntry::windowInfos()
{ {
return parent()->getExportWindowInfos(); return parent()->getExportWindowInfos();
} }

View File

@ -23,7 +23,7 @@
#define DBUSADAPTORENTRY_H #define DBUSADAPTORENTRY_H
#include "entry.h" #include "entry.h"
#include "exportwindowinfolist.h" #include "windowinfomap.h"
#include <QtCore/QObject> #include <QtCore/QObject>
#include <QtCore/QMetaObject> #include <QtCore/QMetaObject>
@ -77,8 +77,8 @@ class DBusAdaptorEntry: public QDBusAbstractAdaptor
" <property access=\"read\" type=\"b\" name=\"IsDocked\"/>\n" " <property access=\"read\" type=\"b\" name=\"IsDocked\"/>\n"
" <property access=\"read\" type=\"s\" name=\"Menu\"/>\n" " <property access=\"read\" type=\"s\" name=\"Menu\"/>\n"
" <property access=\"read\" type=\"s\" name=\"DesktopFile\"/>\n" " <property access=\"read\" type=\"s\" name=\"DesktopFile\"/>\n"
" <property access=\"read\" type=\"a(usb)\" name=\"WindowInfos\"/>\n" " <property access=\"read\" type=\"a{u(sb)}\" name=\"WindowInfos\"/>\n"
" <annotation value=\"ExportWindowInfoList\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n" " <annotation value=\"WindowInfoMap\" name=\"org.qtproject.QtDBus.QtTypeName\"/>\n"
" </interface>\n" " </interface>\n"
"") "")
@ -111,8 +111,8 @@ public: // PROPERTIES
Q_PROPERTY(QString Name READ name NOTIFY NameChanged) Q_PROPERTY(QString Name READ name NOTIFY NameChanged)
QString name() const; QString name() const;
Q_PROPERTY(ExportWindowInfoList WindowInfos READ windowInfos NOTIFY WindowInfosChanged) Q_PROPERTY(WindowInfoMap WindowInfos READ windowInfos NOTIFY WindowInfosChanged)
ExportWindowInfoList windowInfos(); WindowInfoMap windowInfos();
Entry *parent() const; Entry *parent() const;
@ -136,7 +136,7 @@ Q_SIGNALS: // SIGNALS
void NameChanged(QString value); void NameChanged(QString value);
void DesktopFileChanged(QString value); void DesktopFileChanged(QString value);
void CurrentWindowChanged(uint32_t value); void CurrentWindowChanged(uint32_t value);
void WindowInfosChanged(ExportWindowInfoList value); void WindowInfosChanged(WindowInfoMap value);
}; };
#endif #endif

View File

@ -409,6 +409,14 @@ QList<XWindow> Dock::getClientList()
return QList<XWindow>(clientList); return QList<XWindow>(clientList);
} }
/**
* @brief Dock::setClientList client列表
*/
void Dock::setClientList(QList<XWindow> value)
{
clientList = value;
}
/** /**
* @brief Dock::closeWindow * @brief Dock::closeWindow
* @param windowId id * @param windowId id

View File

@ -128,6 +128,7 @@ public:
WindowInfoBase *getActiveWindow(); WindowInfoBase *getActiveWindow();
void doActiveWindow(XWindow xid); void doActiveWindow(XWindow xid);
QList<XWindow> getClientList(); QList<XWindow> getClientList();
void setClientList(QList<XWindow> value);
void closeWindow(XWindow windowId); void closeWindow(XWindow windowId);
QStringList getEntryIDs(); QStringList getEntryIDs();
@ -148,7 +149,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void serviceRestarted(); void serviceRestarted();
void entryAdded(QString entryObjPath, int32_t index); void entryAdded(QDBusObjectPath entryObjPath, int index);
void entryRemoved(QString id); void entryRemoved(QString id);
void hideStateChanged(int); void hideStateChanged(int);
void frontendWindowRectChanged(); void frontendWindowRectChanged();

View File

@ -59,6 +59,7 @@ void Entries::insert(Entry *entry, int index)
{ {
if (index < 0 || index >= items.size()) { if (index < 0 || index >= items.size()) {
// append // append
index = items.size();
items.push_back(entry); items.push_back(entry);
} else { } else {
// insert // insert
@ -70,11 +71,13 @@ void Entries::insert(Entry *entry, int index)
void Entries::remove(Entry *entry) void Entries::remove(Entry *entry)
{ {
for (auto iter = items.begin(); iter != items.end(); iter++) { for (auto iter = items.begin(); iter != items.end();) {
if ((*iter)->getId() == entry->getId()) { if ((*iter)->getId() == entry->getId()) {
items.erase(iter); iter = items.erase(iter);
removeCb(entry); removeCb(entry);
delete entry; delete entry;
} else {
iter++;
} }
} }
} }
@ -205,7 +208,7 @@ void Entries::updateEntriesMenu()
void Entries::insertCb(Entry *entry, int index) void Entries::insertCb(Entry *entry, int index)
{ {
QString objPath = entryDBusObjPathPrefix + entry->getId(); QString objPath = entryDBusObjPathPrefix + entry->getId();
Q_EMIT dock->entryAdded(objPath, index); Q_EMIT dock->entryAdded(QDBusObjectPath(objPath), index);
} }
void Entries::removeCb(Entry *entry) void Entries::removeCb(Entry *entry)
@ -213,3 +216,4 @@ void Entries::removeCb(Entry *entry)
Q_EMIT dock->entryRemoved(entry->getId()); Q_EMIT dock->entryRemoved(entry->getId());
entry->stopExport(); entry->stopExport();
} }

View File

@ -52,11 +52,11 @@ Entry::Entry(Dock *_dock, AppInfo *_app, QString _innerId, QObject *parent)
Entry::~Entry() Entry::~Entry()
{ {
for (auto winInfo : windowInfos) { for (auto winInfo : windowInfoMap) {
if (winInfo) if (winInfo)
delete winInfo; delete winInfo;
} }
windowInfos.clear(); windowInfoMap.clear();
if (app) { if (app) {
delete app; delete app;
@ -196,7 +196,7 @@ void Entry::setIsDocked(bool value)
} }
} }
// 导出Dbus服务 // 导出DBus服务
void Entry::startExport() void Entry::startExport()
{ {
if (getId().isEmpty()) { if (getId().isEmpty()) {
@ -219,7 +219,7 @@ void Entry::startExport()
} }
} }
// 停止导出Dbus服务 // 停止导出DBus服务
void Entry::stopExport() void Entry::stopExport()
{ {
if (getId().isEmpty()) { if (getId().isEmpty()) {
@ -291,8 +291,10 @@ void Entry::updateIsActive()
{ {
bool isActive = false; bool isActive = false;
auto activeWin = dock->getActiveWindow(); auto activeWin = dock->getActiveWindow();
if (activeWin) if (activeWin) {
isActive = windowInfos.find(activeWin->getXid()) != windowInfos.end(); // 判断活跃窗口是否属于当前应用
isActive = windowInfoMap.find(activeWin->getXid()) != windowInfoMap.end();
}
setPropIsActive(isActive); setPropIsActive(isActive);
} }
@ -300,7 +302,7 @@ void Entry::updateIsActive()
WindowInfoBase *Entry::getWindowInfoByPid(int pid) WindowInfoBase *Entry::getWindowInfoByPid(int pid)
{ {
WindowInfoBase *ret = nullptr; WindowInfoBase *ret = nullptr;
for (const auto &windowInfo : windowInfos) { for (const auto &windowInfo : windowInfoMap) {
if (windowInfo->getPid() == pid) { if (windowInfo->getPid() == pid) {
ret = windowInfo; ret = windowInfo;
break; break;
@ -313,8 +315,8 @@ WindowInfoBase *Entry::getWindowInfoByPid(int pid)
WindowInfoBase *Entry::getWindowInfoByWinId(XWindow windowId) WindowInfoBase *Entry::getWindowInfoByWinId(XWindow windowId)
{ {
WindowInfoBase *ret = nullptr; WindowInfoBase *ret = nullptr;
if (windowInfos.find(windowId) != windowInfos.end()) { if (windowInfoMap.find(windowId) != windowInfoMap.end()) {
ret = windowInfos[windowId]; ret = windowInfoMap[windowId];
} }
return ret; return ret;
@ -377,7 +379,7 @@ WindowInfoBase *Entry::getCurrentWindowInfo()
*/ */
WindowInfoBase *Entry::findNextLeader() WindowInfoBase *Entry::findNextLeader()
{ {
auto xids = windowInfos.keys(); auto xids = windowInfoMap.keys();
qSort(xids); qSort(xids);
XWindow curWinId = current->getXid(); XWindow curWinId = current->getXid();
int index = xids.indexOf(curWinId); int index = xids.indexOf(curWinId);
@ -389,7 +391,7 @@ WindowInfoBase *Entry::findNextLeader()
if (index < xids.size() - 1) if (index < xids.size() - 1)
nextIndex = index + 1; nextIndex = index + 1;
return windowInfos[xids[nextIndex]]; return windowInfoMap[xids[nextIndex]];
} }
QString Entry::getExec(bool oneLine) QString Entry::getExec(bool oneLine)
@ -410,7 +412,7 @@ QString Entry::getExec(bool oneLine)
bool Entry::hasWindow() bool Entry::hasWindow()
{ {
return windowInfos.size() > 0; return windowInfoMap.size() > 0;
} }
/** /**
@ -418,22 +420,21 @@ bool Entry::hasWindow()
*/ */
void Entry::updateExportWindowInfos() void Entry::updateExportWindowInfos()
{ {
ExportWindowInfoList infos; WindowInfoMap infos;
for (auto info : windowInfos) { for (auto info : windowInfoMap) {
WindowInfo winInfo;
XWindow xid = info->getXid(); XWindow xid = info->getXid();
QString title = info->getTitle(); winInfo.title = info->getTitle();
bool flash = info->isDemandingAttention(); winInfo.attention = info->isDemandingAttention();
infos.push_back({xid, title, flash}); infos[xid] = winInfo;
} }
bool changed = false; bool changed = false;
if (infos.size() == exportWindowInfos.size()) { if (infos.size() == exportWindowInfos.size()) {
sortExprotWindowInfoList(infos); for (auto iter = infos.begin(); iter != infos.end(); iter++) {
sortExprotWindowInfoList(exportWindowInfos); XWindow xid = iter.key();
for (int i = 0; i < infos.size(); i++) { if (infos[xid].title != exportWindowInfos[xid].title ||
if (infos[i].getXid() != exportWindowInfos[i].getXid() infos[xid].attention != exportWindowInfos[xid].attention) {
|| infos[i].getFlash() != exportWindowInfos[i].getFlash()
|| infos[i].getTitle() != exportWindowInfos[i].getTitle()) {
changed = true; changed = true;
break; break;
} }
@ -456,13 +457,13 @@ bool Entry::detachWindow(WindowInfoBase *info)
XWindow winId = info->getXid(); XWindow winId = info->getXid();
deleteWindow(winId); deleteWindow(winId);
if (windowInfos.size() == 0) { if (windowInfoMap.size() == 0) {
if (!isDocked) // 既无窗口也非驻留应用,无需在任务栏显示 if (!isDocked) // 既无窗口也非驻留应用,无需在任务栏显示
return true; return true;
setCurrentWindowInfo(nullptr); setCurrentWindowInfo(nullptr);
} else { } else {
for (auto window : windowInfos) { for (auto window : windowInfoMap) {
if (window) { // 选择第一个窗口作为当前窗口 if (window) { // 选择第一个窗口作为当前窗口
setCurrentWindowInfo(window); setCurrentWindowInfo(window);
break; break;
@ -484,12 +485,12 @@ bool Entry::attachWindow(WindowInfoBase *info)
qInfo() << "attatchWindow: window id:" << winId; qInfo() << "attatchWindow: window id:" << winId;
info->setEntry(this); info->setEntry(this);
if (windowInfos.find(winId) != windowInfos.end()) { if (windowInfoMap.find(winId) != windowInfoMap.end()) {
qInfo() << "attachWindow: window " << winId << " is already attached"; qInfo() << "attachWindow: window " << winId << " is already attached";
return false; return false;
} }
windowInfos[winId] = info; windowInfoMap[winId] = info;
updateExportWindowInfos(); updateExportWindowInfos();
updateIsActive(); updateIsActive();
@ -510,19 +511,14 @@ void Entry::launchApp(uint32_t timestamp)
bool Entry::containsWindow(XWindow xid) bool Entry::containsWindow(XWindow xid)
{ {
return windowInfos.find(xid) != windowInfos.end(); return windowInfoMap.find(xid) != windowInfoMap.end();
} }
void Entry::deleteWindow(XWindow xid) void Entry::deleteWindow(XWindow xid)
{ {
WindowInfoBase *info = windowInfos[xid]; WindowInfoBase *info = windowInfoMap[xid];
windowInfos.remove(xid); windowInfoMap.remove(xid);
for (int i = 0; i < exportWindowInfos.size(); i++) { exportWindowInfos.remove(xid);
if (exportWindowInfos[i].getXid() == xid) {
exportWindowInfos.removeAt(i);
break;
}
}
if (info) { if (info) {
delete info; delete info;
@ -564,7 +560,7 @@ void Entry::newInstance(uint32_t timestamp)
// 检查应用窗口分离、合并状态 // 检查应用窗口分离、合并状态
void Entry::check() void Entry::check()
{ {
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) { for (auto iter = windowInfoMap.begin(); iter != windowInfoMap.end(); iter++) {
dock->attachOrDetachWindow(iter.value()); dock->attachOrDetachWindow(iter.value());
} }
} }
@ -573,28 +569,29 @@ void Entry::check()
void Entry::forceQuit() void Entry::forceQuit()
{ {
QMap<int, QVector<WindowInfoBase*>> pidWinInfoMap; QMap<int, QVector<WindowInfoBase*>> pidWinInfoMap;
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) { for (auto iter = windowInfoMap.begin(); iter != windowInfoMap.end(); iter++) {
int pid = iter.value()->getPid(); int pid = iter.value()->getPid();
if (pid != 0) { if (pid != 0) {
pidWinInfoMap[pid].push_back(iter.value()); pidWinInfoMap[pid].push_back(iter.value());
} else { } else {
iter.value()->killClient(); iter.value()->killClient();
} }
}
for (auto iter = pidWinInfoMap.begin(); iter != pidWinInfoMap.end(); iter++) { for (auto iter = pidWinInfoMap.begin(); iter != pidWinInfoMap.end(); iter++) {
if (!killProcess(iter.key())) { // kill pid if (!killProcess(iter.key())) { // kill pid
for (auto &info : iter.value()) { // kill window for (auto &info : iter.value()) { // kill window
info->killClient(); info->killClient();
}
} }
} }
} }
} }
void Entry::presentWindows() void Entry::presentWindows()
{ {
QList<uint> windows; QList<uint> windows;
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) for (auto iter = windowInfoMap.begin(); iter != windowInfoMap.end(); iter++)
windows.push_back(iter.key()); windows.push_back(iter.key());
dock->presentWindows(windows); dock->presentWindows(windows);
@ -632,7 +629,7 @@ void Entry::active(uint32_t timestamp)
if (showing || winInfo->isMinimized()) { if (showing || winInfo->isMinimized()) {
winInfo->activate(); winInfo->activate();
} else { } else {
if (windowInfos.size() == 1) { if (windowInfoMap.size() == 1) {
winInfo->minimize(); winInfo->minimize();
} else { } else {
WindowInfoBase *nextWin = findNextLeader(); WindowInfoBase *nextWin = findNextLeader();
@ -662,7 +659,7 @@ void Entry::active(uint32_t timestamp)
// 激活隐藏窗口 // 激活隐藏窗口
dock->doActiveWindow(xid); dock->doActiveWindow(xid);
} else { } else {
if (windowInfos.size() == 1) { if (windowInfoMap.size() == 1) {
XCB->minimizeWindow(xid); XCB->minimizeWindow(xid);
} else if (dock->getActiveWindow()->getXid() == xid) { } else if (dock->getActiveWindow()->getXid() == xid) {
WindowInfoBase *nextWin = findNextLeader(); WindowInfoBase *nextWin = findNextLeader();
@ -698,7 +695,7 @@ QString Entry::getMenu()
QVector<XWindow> Entry::getAllowedClosedWindowIds() QVector<XWindow> Entry::getAllowedClosedWindowIds()
{ {
QVector<XWindow> ret; QVector<XWindow> ret;
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) { for (auto iter = windowInfoMap.begin(); iter != windowInfoMap.end(); iter++) {
WindowInfoBase *info = iter.value(); WindowInfoBase *info = iter.value();
if (info && info->allowClose()) if (info && info->allowClose())
ret.push_back(iter.key()); ret.push_back(iter.key());
@ -707,7 +704,7 @@ QVector<XWindow> Entry::getAllowedClosedWindowIds()
return ret; return ret;
} }
ExportWindowInfoList Entry::getExportWindowInfos() WindowInfoMap Entry::getExportWindowInfos()
{ {
return exportWindowInfos; return exportWindowInfos;
} }
@ -715,7 +712,7 @@ ExportWindowInfoList Entry::getExportWindowInfos()
QVector<WindowInfoBase *> Entry::getAllowedCloseWindows() QVector<WindowInfoBase *> Entry::getAllowedCloseWindows()
{ {
QVector<WindowInfoBase *> ret; QVector<WindowInfoBase *> ret;
for (auto iter = windowInfos.begin(); iter != windowInfos.end(); iter++) { for (auto iter = windowInfoMap.begin(); iter != windowInfoMap.end(); iter++) {
WindowInfoBase *info = iter.value(); WindowInfoBase *info = iter.value();
if (info && info->allowClose()) if (info && info->allowClose())
ret.push_back(info); ret.push_back(info);
@ -772,7 +769,7 @@ AppMenuItem Entry::getMenuItemCloseAll()
qInfo() << "do MenuItem: Close All"; qInfo() << "do MenuItem: Close All";
auto winInfos = getAllowedCloseWindows(); auto winInfos = getAllowedCloseWindows();
// 从大到小排序, 方便后面关闭窗口 // 根据创建时间从大到小排序, 方便后续关闭窗口
for (int i = 0; i < winInfos.size() - 1; i++) { for (int i = 0; i < winInfos.size() - 1; i++) {
for (int j = i + 1; j < winInfos.size(); j++) { for (int j = i + 1; j < winInfos.size(); j++) {
if (winInfos[i]->getCreatedTime() < winInfos[j]->getCreatedTime()) { if (winInfos[i]->getCreatedTime() < winInfos[j]->getCreatedTime()) {

View File

@ -25,7 +25,7 @@
#include "appinfo.h" #include "appinfo.h"
#include "appmenu.h" #include "appmenu.h"
#include "windowinfobase.h" #include "windowinfobase.h"
#include "exportwindowinfolist.h" #include "windowinfomap.h"
#include <QMap> #include <QMap>
#include <QVector> #include <QVector>
@ -93,7 +93,7 @@ public:
bool getIsActive(); bool getIsActive();
QString getMenu(); QString getMenu();
QVector<XWindow> getAllowedClosedWindowIds(); QVector<XWindow> getAllowedClosedWindowIds();
ExportWindowInfoList getExportWindowInfos(); WindowInfoMap getExportWindowInfos();
public Q_SLOTS: public Q_SLOTS:
QVector<WindowInfoBase *> getAllowedCloseWindows(); QVector<WindowInfoBase *> getAllowedCloseWindows();
@ -106,7 +106,7 @@ Q_SIGNALS:
void nameChanged(QString value); void nameChanged(QString value);
void desktopFileChanged(QString value); void desktopFileChanged(QString value);
void currentWindowChanged(uint32_t value); void currentWindowChanged(uint32_t value);
void windowInfosChanged(const ExportWindowInfoList &value); void windowInfosChanged(const WindowInfoMap &value);
private: private:
// 右键菜单项 // 右键菜单项
@ -135,8 +135,8 @@ private:
QString desktopFile; QString desktopFile;
// Dbus属性直接放到interface上 // Dbus属性直接放到interface上
QMap<XWindow, WindowInfoBase *> windowInfos; // 该应用所有窗口 QMap<XWindow, WindowInfoBase *> windowInfoMap; // 该应用所有窗口
ExportWindowInfoList exportWindowInfos; WindowInfoMap exportWindowInfos; // 该应用导出的窗口属性
WindowInfoBase *current; // 当前窗口 WindowInfoBase *current; // 当前窗口
XWindow currentWindow; //当前窗口Id XWindow currentWindow; //当前窗口Id
bool winIconPreferred; bool winIconPreferred;

View File

@ -65,16 +65,16 @@ public:
bool containAtom(QVector<XCBAtom> supports, XCBAtom ty) {return supports.indexOf(ty) != -1;} bool containAtom(QVector<XCBAtom> supports, XCBAtom ty) {return supports.indexOf(ty) != -1;}
protected: protected:
XWindow xid; XWindow xid; // 窗口id
QString title; QString title; // 窗口标题
QString icon; QString icon; // 窗口图标
int pid; int pid; // 窗口所属应用进程
QString entryInnerId; QString entryInnerId; // 窗口所属应用对应的innerId
QString innerId; QString innerId; // 窗口对应的innerId
Entry *entry; Entry *entry; // 窗口所属应用
AppInfo *app; AppInfo *app; // 窗口所属应用对应的desktopFile信息
ProcessInfo *processInfo; ProcessInfo *processInfo; // 窗口所属应用的进程信息
int64_t createdTime; int64_t createdTime; // 创建时间
}; };
#endif // WINDOWINFOBASE_H #endif // WINDOWINFOBASE_H

View File

@ -29,6 +29,8 @@
#include <QDebug> #include <QDebug>
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QTimer> #include <QTimer>
#include <QImage>
#include <QIcon>
#define XCB XCBUtils::instance() #define XCB XCBUtils::instance()
@ -367,9 +369,7 @@ void WindowInfoX::update()
// TODO 从窗口中获取图标, 并设置best size be used in Entry // TODO 从窗口中获取图标, 并设置best size be used in Entry
QString WindowInfoX::getIconFromWindow() QString WindowInfoX::getIconFromWindow()
{ {
QString ret; return QString();
return ret;
} }
bool WindowInfoX::isActionMinimizeAllowed() bool WindowInfoX::isActionMinimizeAllowed()

View File

@ -209,7 +209,9 @@ void X11Manager::handleClientListChanged()
addClientList = newClientList - oldClientList; addClientList = newClientList - oldClientList;
rmClientList = oldClientList - newClientList; rmClientList = oldClientList - newClientList;
dock->setClientList(newClientList.toList());
// 处理新增窗口
for (auto xid : addClientList) { for (auto xid : addClientList) {
WindowInfoX *info = registerWindow(xid); WindowInfoX *info = registerWindow(xid);
if (!XCB->isGoodWindow(xid)) if (!XCB->isGoodWindow(xid))
@ -220,9 +222,10 @@ void X11Manager::handleClientListChanged()
QString wmName(XCB->getWMName(xid).c_str()); QString wmName(XCB->getWMName(xid).c_str());
if (pid != 0 || (wmClass.className.size() > 0 && wmClass.instanceName.size() > 0) if (pid != 0 || (wmClass.className.size() > 0 && wmClass.instanceName.size() > 0)
|| wmName.size() > 0 || XCB->getWMCommand(xid).size() > 0) || wmName.size() > 0 || XCB->getWMCommand(xid).size() > 0)
dock->attachWindow(info); dock->attachOrDetachWindow(info);
} }
// 处理需要移除的窗口
for (auto xid : rmClientList) { for (auto xid : rmClientList) {
WindowInfoX *info = windowInfoMap[xid]; WindowInfoX *info = windowInfoMap[xid];
if (info) { if (info) {
@ -370,7 +373,7 @@ void X11Manager::handlePropertyNotifyEvent(XWindow xid, XCBAtom atom)
} }
if (needAttachOrDetach) if (needAttachOrDetach)
dock->attachWindow(winInfo); dock->attachOrDetachWindow(winInfo);
Entry *entry = dock->getEntryByWindowId(xid); Entry *entry = dock->getEntryByWindowId(xid);
if (!entry) if (!entry)

View File

@ -1,9 +1,29 @@
/*
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: weizhixiang <weizhixiang@uniontech.com>
*
* Maintainer: weizhixiang <weizhixiang@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 "dbusadaptorlauncher.h" #include "dbusadaptorlauncher.h"
DBusAdaptorLauncher::DBusAdaptorLauncher(QObject *parent) DBusAdaptorLauncher::DBusAdaptorLauncher(QObject *parent)
: QDBusAbstractAdaptor(parent) : QDBusAbstractAdaptor(parent)
{ {
// constructor
setAutoRelaySignals(true); setAutoRelaySignals(true);
Launcher *launcher = static_cast<Launcher *>(QObject::parent()); Launcher *launcher = static_cast<Launcher *>(QObject::parent());

View File

@ -1,3 +1,24 @@
/*
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: weizhixiang <weizhixiang@uniontech.com>
*
* Maintainer: weizhixiang <weizhixiang@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 DBUSADAPTORLAUNCHER_H #ifndef DBUSADAPTORLAUNCHER_H
#define DBUSADAPTORLAUNCHER_H #define DBUSADAPTORLAUNCHER_H
@ -88,7 +109,7 @@ class DBusAdaptorLauncher: public QDBusAbstractAdaptor
" </interface>\n" " </interface>\n"
"") "")
public: public:
DBusAdaptorLauncher(QObject *parent); explicit DBusAdaptorLauncher(QObject *parent);
virtual ~DBusAdaptorLauncher(); virtual ~DBusAdaptorLauncher();
Launcher *parent() const; Launcher *parent() const;

View File

@ -168,7 +168,7 @@ LauncherItemInfoList Launcher::getAllItemInfos()
* @brief Launcher::getAllNewInstalledApps * @brief Launcher::getAllNewInstalledApps
* @return * @return
*/ */
QStringList Launcher::getAllNewInstalledApps() QStringList Launcher::getAllNewInstalledApps()
{ {
QStringList ret; QStringList ret;
QMap<QString, QStringList> newApps; QMap<QString, QStringList> newApps;
@ -185,7 +185,7 @@ LauncherItemInfoList Launcher::getAllItemInfos()
return ret; return ret;
} }
/** /**
* @brief Launcher::getDisableScaling * @brief Launcher::getDisableScaling
* @param appId * @param appId
* @return * @return
@ -1193,8 +1193,9 @@ Item Launcher:: NewItemWithDesktopInfo(DesktopInfo &info)
item.exec = info.getCommandLine().c_str(); item.exec = info.getCommandLine().c_str();
item.genericName = info.getGenericName().c_str(); item.genericName = info.getGenericName().c_str();
item.comment = enComment; item.comment = enComment;
if (!info.getIcon().empty()) if (!info.getIcon().empty()) {
item.info.icon = info.getIcon().c_str(); item.info.icon = info.getIcon().c_str();
}
xDeepinCategory = xDeepinCategory.toLower(); xDeepinCategory = xDeepinCategory.toLower();

View File

@ -2,7 +2,7 @@ set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON) set(CMAKE_AUTORCC ON)
find_package(Qt5 REQUIRED COMPONENTS Core DBus Concurrent) find_package(Qt5 REQUIRED COMPONENTS Core DBus Concurrent Gui)
find_package(DtkCore REQUIRED) find_package(DtkCore REQUIRED)
pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-icccm xcb-ewmh xcb) pkg_check_modules(XCB REQUIRED IMPORTED_TARGET xcb-icccm xcb-ewmh xcb)
@ -45,6 +45,7 @@ target_link_libraries(deepin-application-manager
PkgConfig::XCB PkgConfig::XCB
PkgConfig::X11 PkgConfig::X11
PkgConfig::GIO PkgConfig::GIO
${Qt5Gui_LIBRARIES}
) )
target_include_directories(deepin-application-manager PUBLIC target_include_directories(deepin-application-manager PUBLIC
@ -55,6 +56,7 @@ target_include_directories(deepin-application-manager PUBLIC
../frameworkdbus ../frameworkdbus
../frameworkdbus/qtdbusextended ../frameworkdbus/qtdbusextended
../frameworkdbus/types ../frameworkdbus/types
${Qt5Gui_PRIVATE_INCLUDE_DIRS}
) )
install(TARGETS deepin-application-manager DESTINATION bin) install(TARGETS deepin-application-manager DESTINATION bin)