dde-application-manager/src/modules/dock/entries.cpp
donghualin 6c06ed86b7 fix: 修复控制中心发送应用到任务栏不显示的问题
当应用打开的时候移除驻留,该应用作为最近打开应用,在取消驻留的时候,只是停止了服务,并未从列表中移除;下次驻留的时候,没有启动服务,导致任务栏图标没有驻留

Log: 修复控制中心无法发送应用到任务栏的问题
Influence: 从任务栏打开一个已经驻留的应用,对这个应用取消驻留,关闭应用,打开启动器,把这个应用发送到任务栏,观察任务栏是否有这个应用
Bug: https://pms.uniontech.com/bug-view-165891.html
Change-Id: I89fdaad6c33388dab67eb9c7d41dd372d36582bd
2022-10-28 12:15:42 +08:00

348 lines
9.4 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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 "entries.h"
#include "dock.h"
Entries::Entries(Dock *_dock)
: m_dock(_dock)
{
}
QVector<Entry *> Entries::filterDockedEntries()
{
QVector<Entry *> ret;
for (auto &entry : m_items) {
if (entry->isValid() && entry->getIsDocked())
ret.push_back(entry);
}
return ret;
}
Entry *Entries::getByInnerId(QString innerId)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getInnerId() == innerId)
ret = entry;
}
return ret;
}
void Entries::append(Entry *entry)
{
// 如果当前应用在列表中存在(通常是该应用为最近打开应用但是关闭了最近打开应用的接口或者当前为高效模式)
if (m_items.contains(entry))
m_items.removeOne(entry);
insert(entry, -1);
}
void Entries::insert(Entry *entry, int index)
{
if (index < 0 || index >= m_items.size()) {
// append
index = m_items.size();
m_items.push_back(entry);
} else {
// insert
m_items.insert(index, entry);
}
insertCb(entry, index);
}
void Entries::remove(Entry *entry)
{
for (auto iter = m_items.begin(); iter != m_items.end();) {
if ((*iter)->getId() == entry->getId()) {
iter = m_items.erase(iter);
removeCb(entry);
delete entry;
} else {
iter++;
}
}
}
void Entries::move(int oldIndex, int newIndex)
{
if (oldIndex == newIndex || oldIndex < 0 || newIndex < 0 || oldIndex >= m_items.size() || newIndex >= m_items.size())
return;
m_items.swap(oldIndex, newIndex);
}
Entry *Entries::getByWindowPid(int pid)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getWindowInfoByPid(pid)) {
ret = entry;
break;
}
}
return ret;
}
Entry *Entries::getByWindowId(XWindow windowId)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getWindowInfoByWinId(windowId)) {
ret = entry;
break;
}
}
return ret;
}
Entry *Entries::getByDesktopFilePath(QString filePath)
{
Entry *ret = nullptr;
for (auto &entry : m_items) {
if (entry->getFileName() == filePath) {
ret = entry;
break;
}
}
return ret;
}
QStringList Entries::getEntryIDs()
{
QStringList list;
if (static_cast<DisplayMode>(m_dock->getDisplayMode()) == DisplayMode::Fashion
&& m_dock->showRecent()) {
for (Entry *item : m_items)
list.push_back(item->getId());
} else {
// 如果是高效模式或者没有开启显示最近应用的功能,那么未驻留并且没有子窗口的就不显示
// 换句话说,只显示已经驻留或者有子窗口的应用
for (Entry *item : m_items) {
if (!item->getIsDocked() && !item->hasWindow())
continue;
list << 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;
for (auto entry : m_items) {
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)
{
for (auto entry : m_items) {
auto windowInfo = entry->getWindowInfoByWinId(activeWindId);
if (windowInfo) {
entry->setPropIsActive(true);
entry->setCurrentWindowInfo(windowInfo);
entry->updateName();
entry->updateIcon();
} else {
entry->setPropIsActive(false);
}
}
}
void Entries::updateEntriesMenu()
{
for (auto entry : m_items) {
entry->updateMenu();
}
}
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;
}
}
void Entries::insertCb(Entry *entry, int index)
{
if (entry->getIsDocked() || entry->hasWindow() ||
(static_cast<DisplayMode>(m_dock->getDisplayMode()) == DisplayMode::Fashion) && m_dock->showRecent())
Q_EMIT m_dock->entryAdded(QDBusObjectPath(entry->path()), index);
}
void Entries::removeCb(Entry *entry)
{
Q_EMIT m_dock->entryRemoved(entry->getId());
entry->stopExport();
}
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];
removeEntrys << entry;
}
for (Entry *entry : removeEntrys) {
m_items.removeOne(entry);
removeCb(entry);
delete entry;
}
}
void Entries::setDisplayMode(DisplayMode displayMode)
{
if (!m_dock->showRecent())
return;
// 如果从时尚模式变成高效模式,对列表中所有的没有打开窗口的应用发送移除信号
if (displayMode == DisplayMode::Efficient) {
for (Entry *entry : m_items) {
entry->updateMode();
if (!entry->getIsDocked() && !entry->hasWindow())
Q_EMIT m_dock->entryRemoved(entry->getId());
}
} else {
// 如果从高效模式变成时尚模式,列表中所有的未驻留且不存在打开窗口的应用认为是最近打开应用,发送新增信号
for (Entry *entry : m_items) {
entry->updateMode();
if (!entry->getIsDocked() && !entry->hasWindow()) {
QString objPath = entry->path();
int index = m_items.indexOf(entry);
Q_EMIT m_dock->entryAdded(QDBusObjectPath(objPath), index);
}
}
}
}
void Entries::updateShowRecent()
{
// 高效模式无需做任何操作
if (static_cast<DisplayMode>(m_dock->getDisplayMode()) != DisplayMode::Fashion)
return;
bool showRecent = m_dock->showRecent();
if (showRecent) {
// 如果显示最近打开应用,则发送新增信号
for (Entry *entry : m_items) {
// 已经驻留的或者有子窗口的本来就在任务栏上面,无需发送信号
entry->updateMode();
if (entry->getIsDocked() || entry->hasWindow())
continue;
QString objPath = entry->path();
int index = m_items.indexOf(entry);
Q_EMIT m_dock->entryAdded(QDBusObjectPath(objPath), index);
}
} else {
// 如果是隐藏最近打开的应用,则发送移除的信号
for (Entry *entry : m_items) {
// 已经驻留的或者有子窗口的本来就在任务栏上面,无需发送信号
entry->updateMode();
if (entry->getIsDocked() || entry->hasWindow())
continue;
Q_EMIT m_dock->entryRemoved(entry->getId());
}
}
}