2022-04-24 14:52:13 +08:00
|
|
|
|
/*
|
2022-05-15 12:10:42 +08:00
|
|
|
|
* Copyright (C) 2021 ~ 2022 Deepin Technology Co., Ltd.
|
2022-04-24 14:52:13 +08:00
|
|
|
|
*
|
|
|
|
|
* 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 "entries.h"
|
|
|
|
|
#include "dock.h"
|
|
|
|
|
|
|
|
|
|
Entries::Entries(Dock *_dock)
|
|
|
|
|
: dock(_dock)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVector<Entry *> Entries::filterDockedEntries()
|
|
|
|
|
{
|
|
|
|
|
QVector<Entry *> ret;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto &entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if (entry->isValid() && entry->getIsDocked())
|
|
|
|
|
ret.push_back(entry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *Entries::getByInnerId(QString innerId)
|
|
|
|
|
{
|
|
|
|
|
Entry *ret = nullptr;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto &entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if (entry->getInnerId() == innerId)
|
|
|
|
|
ret = entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::append(Entry *entry)
|
|
|
|
|
{
|
|
|
|
|
insert(entry, -1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::insert(Entry *entry, int index)
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
if (index < 0 || index >= m_items.size()) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
// append
|
2022-08-08 13:20:42 +08:00
|
|
|
|
index = m_items.size();
|
|
|
|
|
m_items.push_back(entry);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
} else {
|
|
|
|
|
// insert
|
2022-08-08 13:20:42 +08:00
|
|
|
|
m_items.insert(index, entry);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
insertCb(entry, index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::remove(Entry *entry)
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto iter = m_items.begin(); iter != m_items.end();) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if ((*iter)->getId() == entry->getId()) {
|
2022-08-08 13:20:42 +08:00
|
|
|
|
iter = m_items.erase(iter);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
removeCb(entry);
|
|
|
|
|
delete entry;
|
2022-05-31 17:20:39 +08:00
|
|
|
|
} else {
|
|
|
|
|
iter++;
|
2022-04-24 14:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::move(int oldIndex, int newIndex)
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
if (oldIndex == newIndex || oldIndex < 0 || newIndex < 0 || oldIndex >= m_items.size() || newIndex >= m_items.size())
|
2022-04-24 14:52:13 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2022-08-08 13:20:42 +08:00
|
|
|
|
m_items.swap(oldIndex, newIndex);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *Entries::getByWindowPid(int pid)
|
|
|
|
|
{
|
|
|
|
|
Entry *ret = nullptr;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto &entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if (entry->getWindowInfoByPid(pid)) {
|
|
|
|
|
ret = entry;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *Entries::getByWindowId(XWindow windowId)
|
|
|
|
|
{
|
|
|
|
|
Entry *ret = nullptr;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto &entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if (entry->getWindowInfoByWinId(windowId)) {
|
|
|
|
|
ret = entry;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *Entries::getByDesktopFilePath(QString filePath)
|
|
|
|
|
{
|
|
|
|
|
Entry *ret = nullptr;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto &entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
if (entry->getFileName() == filePath) {
|
|
|
|
|
ret = entry;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList Entries::getEntryIDs()
|
|
|
|
|
{
|
|
|
|
|
QStringList list;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto item : m_items)
|
2022-04-24 14:52:13 +08:00
|
|
|
|
list.push_back(item->getId());
|
|
|
|
|
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *Entries::getDockedEntryByDesktopFile(const QString &desktopFile)
|
|
|
|
|
{
|
|
|
|
|
Entry *ret = nullptr;
|
|
|
|
|
for (auto entry : filterDockedEntries()) {
|
|
|
|
|
if (!entry->isValid())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (desktopFile == entry->getFileName()) {
|
|
|
|
|
ret = entry;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString Entries::queryWindowIdentifyMethod(XWindow windowId)
|
|
|
|
|
{
|
|
|
|
|
QString ret;
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
auto window = entry->getWindowInfoByWinId(windowId);
|
|
|
|
|
if (window) {
|
|
|
|
|
auto app = window->getAppInfo();
|
|
|
|
|
if (app) {
|
|
|
|
|
ret = app->getIdentifyMethod();
|
|
|
|
|
} else {
|
|
|
|
|
ret = "Failed";
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::handleActiveWindowChanged(XWindow activeWindId)
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
auto windowInfo = entry->getWindowInfoByWinId(activeWindId);
|
|
|
|
|
if (windowInfo) {
|
|
|
|
|
entry->setPropIsActive(true);
|
|
|
|
|
entry->setCurrentWindowInfo(windowInfo);
|
|
|
|
|
entry->updateName();
|
|
|
|
|
entry->updateIcon();
|
|
|
|
|
} else {
|
|
|
|
|
entry->setPropIsActive(false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::updateEntriesMenu()
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
for (auto entry : m_items) {
|
2022-04-24 14:52:13 +08:00
|
|
|
|
entry->updateMenu();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-08-08 13:20:42 +08:00
|
|
|
|
const QList<Entry *> Entries::unDockedEntries() const
|
|
|
|
|
{
|
|
|
|
|
QList<Entry *> entrys;
|
|
|
|
|
for (Entry *entry : m_items) {
|
|
|
|
|
if (!entry->isValid() || entry->getIsDocked())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
entrys << entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return entrys;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::moveEntryToLast(Entry *entry)
|
|
|
|
|
{
|
|
|
|
|
if (m_items.contains(entry)) {
|
|
|
|
|
m_items.removeOne(entry);
|
|
|
|
|
m_items << entry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-24 14:52:13 +08:00
|
|
|
|
void Entries::insertCb(Entry *entry, int index)
|
|
|
|
|
{
|
2022-08-08 13:20:42 +08:00
|
|
|
|
Q_EMIT dock->entryAdded(QDBusObjectPath(entry->path()), index);
|
2022-04-24 14:52:13 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::removeCb(Entry *entry)
|
|
|
|
|
{
|
|
|
|
|
Q_EMIT dock->entryRemoved(entry->getId());
|
|
|
|
|
entry->stopExport();
|
|
|
|
|
}
|
2022-05-31 17:20:39 +08:00
|
|
|
|
|
2022-08-08 13:20:42 +08:00
|
|
|
|
bool Entries::shouldInRecent()
|
|
|
|
|
{
|
|
|
|
|
// 如果当前移除的应用是未驻留应用,则判断未驻留应用的数量是否小于等于3,则让其始终显示
|
|
|
|
|
QList<Entry *> unDocktrys;
|
|
|
|
|
for (Entry *entry : m_items) {
|
|
|
|
|
if (entry->isValid() && !entry->getIsDocked())
|
|
|
|
|
unDocktrys << entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果当前未驻留应用的数量小于3个,则认为后续的应用应该显示到最近打开应用
|
|
|
|
|
return (unDocktrys.size() <= MAX_UNOPEN_RECENT_COUNT);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::removeLastRecent()
|
|
|
|
|
{
|
|
|
|
|
// 先查找最近使用的应用,删除没有使用的
|
|
|
|
|
int unDockCount = 0;
|
|
|
|
|
QList<Entry *> unDockEntrys;
|
|
|
|
|
QList<Entry *> removeEntrys;
|
|
|
|
|
for (Entry *entry : m_items) {
|
|
|
|
|
if (entry->getIsDocked())
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
// 此处只移除没有子窗口的图标
|
|
|
|
|
if (!entry->hasWindow()) {
|
|
|
|
|
if (!entry->isValid())
|
|
|
|
|
removeEntrys << entry; // 如果应用已经被卸载,那么需要删除
|
|
|
|
|
else
|
|
|
|
|
unDockEntrys << entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unDockCount++;
|
|
|
|
|
}
|
|
|
|
|
if (unDockCount >= MAX_UNOPEN_RECENT_COUNT && unDockEntrys.size() > 0) {
|
|
|
|
|
// 只有当最近使用区域的图标大于等于某个数值(3)的时候,并且存在没有子窗口的Entry,那么就移除该Entry
|
|
|
|
|
Entry *entry = unDockEntrys[0];
|
|
|
|
|
m_items.removeOne(entry);
|
|
|
|
|
removeEntrys << entry;
|
|
|
|
|
}
|
|
|
|
|
for (Entry *entry : removeEntrys) {
|
|
|
|
|
removeCb(entry);
|
|
|
|
|
delete entry;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Entries::setDisplayMode(DisplayMode displayMode)
|
|
|
|
|
{
|
|
|
|
|
// 如果从时尚模式变成高效模式,对列表中所有的没有打开窗口的应用发送移除信号
|
|
|
|
|
if (displayMode == DisplayMode::Efficient) {
|
|
|
|
|
for (Entry *entry : m_items) {
|
|
|
|
|
if (!entry->getIsDocked() && !entry->hasWindow())
|
|
|
|
|
Q_EMIT dock->entryRemoved(entry->getId());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 如果从高效模式变成时尚模式,列表中所有的未驻留且不存在打开窗口的应用认为是最近打开应用,发送新增信号
|
|
|
|
|
for (Entry *entry : m_items) {
|
|
|
|
|
if (!entry->getIsDocked() && !entry->hasWindow()) {
|
|
|
|
|
QString objPath = entry->path();
|
|
|
|
|
int index = m_items.indexOf(entry);
|
|
|
|
|
Q_EMIT dock->entryAdded(QDBusObjectPath(objPath), index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|