feat: 增加适配控制中心设置是否使用最近区域的功能

增加获取是否显示最近使用应用的接口,相应相关的功能

Log:
Influence: 开关是否显示最近使用应用,时尚模式下观察最近使用应用是否显示或隐藏
Bug: https://pms.uniontech.com/bug-view-147717.html
Change-Id: I5de2f978da6f5911a8c873b903095ef9f7bbd14e
This commit is contained in:
donghualin 2022-08-15 18:07:14 +00:00
parent 766d6dfcfd
commit 90a076a043
10 changed files with 177 additions and 48 deletions

View File

@ -24,10 +24,15 @@
#include <QWidget>
RecentAppHelper::RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, QObject *parent)
#define ENTRY_NONE 0
#define ENTRY_NORMAL 1
#define ENTRY_RECENT 2
RecentAppHelper::RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, DockInter *dockInter, QObject *parent)
: QObject(parent)
, m_appWidget(appWidget)
, m_recentWidget(recentWidget)
, m_dockInter(dockInter)
{
m_appWidget->installEventFilter(this);
m_recentWidget->installEventFilter(this);
@ -37,7 +42,9 @@ void RecentAppHelper::setDisplayMode(Dock::DisplayMode displayMode)
{
bool lastVisible = dockAppIsVisible();
m_displayMode = displayMode;
#ifndef USE_AM
resetDockItems();
#endif
updateRecentVisible();
updateDockAppVisible(lastVisible);
}
@ -45,8 +52,9 @@ void RecentAppHelper::setDisplayMode(Dock::DisplayMode displayMode)
// 当在应用区域调整位置的时候,需要重新设置索引
void RecentAppHelper::resetAppInfo()
{
#ifndef USE_AM
// 获取应用区域和最近打开区域的app图标
QList<DockItem *> appDockItem = dockItems(false);
QList<AppItem *> appDockItem = appItems(m_appWidget);
// 获取应用区域图标在原来列表中的位置
QList<int> dockIndex;
@ -72,6 +80,7 @@ void RecentAppHelper::resetAppInfo()
else
m_sequentDockItems << appItem;
}
#endif
}
void RecentAppHelper::addAppItem(int index, DockItem *dockItem)
@ -85,30 +94,35 @@ void RecentAppHelper::addAppItem(int index, DockItem *dockItem)
updateDockAppVisible(lastVisible);
}
AppItem *appItem = qobject_cast<AppItem *>(dockItem);
#ifdef USE_AM
connect(appItem, &AppItem::modeChanged, this, &RecentAppHelper::onModeChanged);
#else
connect(dockItem, &QWidget::destroyed, this, [ this, dockItem ] {
if (m_sequentDockItems.contains(dockItem))
m_sequentDockItems.removeOne(dockItem);
});
AppItem *appItem = qobject_cast<AppItem *>(dockItem);
connect(appItem, &AppItem::isDockChanged, this, &RecentAppHelper::onIsDockChanged);
connect(appItem, &AppItem::isDockChanged, this, &RecentAppHelper::onItemChanged);
// 如果索引值大于0说明它是插入到固定位置的否则则认为它是顺序排列的
if (index >= 0 && index < m_sequentDockItems.size())
m_sequentDockItems.insert(index, dockItem);
else
m_sequentDockItems << dockItem;
#endif
}
void RecentAppHelper::removeAppItem(DockItem *dockItem)
{
if (appInRecent(dockItem))
if (m_recentWidget->children().contains(dockItem))
removeRecentAreaItem(dockItem);
else
removeAppAreaItem(dockItem);
#ifndef USE_AM
AppItem *appItem = qobject_cast<AppItem *>(dockItem);
disconnect(appItem, &AppItem::isDockChanged, this, &RecentAppHelper::onIsDockChanged);
disconnect(appItem, &AppItem::isDockChanged, this, &RecentAppHelper::onItemChanged);
#endif
}
bool RecentAppHelper::recentIsVisible() const
@ -145,25 +159,55 @@ bool RecentAppHelper::eventFilter(QObject *watched, QEvent *event)
return QObject::eventFilter(watched, event);
}
void RecentAppHelper::onIsDockChanged()
#ifdef USE_AM
void RecentAppHelper::onModeChanged(int mode)
{
AppItem *appItem = qobject_cast<AppItem *>(sender());
if (!appItem)
return;
auto moveItemToWidget = [ = ](QWidget *widget) {
int index = getEntryIndex(appItem, widget);
removeAppItem(appItem);
QBoxLayout *layout = static_cast<QBoxLayout *>(widget->layout());
layout->insertWidget(index, appItem);
};
if (mode == ENTRY_NORMAL) {
// 添加到应用区域
moveItemToWidget(m_appWidget);
} else if (mode == ENTRY_RECENT) {
// 添加到最近打开应用区域
moveItemToWidget(m_recentWidget);
}
updateRecentVisible();
}
#else
void RecentAppHelper::onItemChanged()
{
bool lastVisible = dockAppIsVisible();
resetDockItems();
updateRecentVisible();
updateDockAppVisible(lastVisible);
}
#endif
bool RecentAppHelper::appInRecent(DockItem *item) const
{
#ifdef USE_AM
AppItem *appItem = qobject_cast<AppItem *>(item);
if (!appItem)
return false;
return (appItem->mode() == ENTRY_RECENT);
#else
// 先判断当前是否为时尚模式,只有时尚模式下才支持最近打开的应用
if (m_displayMode != Dock::DisplayMode::Fashion)
return false;
// TODO 当控制中心不开启最近打开应用的功能的时候,则始终让其显示在应用区域
// 只有当应用没有固定到任务栏上才认为它是最新打开的应用
AppItem *appItem = qobject_cast<AppItem *>(item);
return (appItem && !appItem->isDocked());
#endif
}
void RecentAppHelper::addAppAreaItem(int index, DockItem *wdg)
@ -180,7 +224,7 @@ void RecentAppHelper::addRecentAreaItem(int index, DockItem *wdg)
void RecentAppHelper::updateRecentVisible()
{
bool lastRecentVisible = recentIsVisible();
bool lastRecentVisible = m_recentWidget->isVisible();
bool recentVisible = lastRecentVisible;
if (m_displayMode == Dock::DisplayMode::Efficient) {
@ -190,7 +234,7 @@ void RecentAppHelper::updateRecentVisible()
} else {
QBoxLayout *recentLayout = static_cast<QBoxLayout *>(m_recentWidget->layout());
qInfo() << "recent Widget count:" << recentLayout->count() << ", app Widget count" << m_appWidget->layout()->count();
// 如果是特效模式则判断当前打开应用数量是否为0为0则不显示否则显示
// 如果是时尚模式则判断当前打开应用数量是否为0为0则不显示否则显示
recentVisible = (recentLayout->count() > 0);
m_recentWidget->setVisible(recentVisible);
}
@ -221,6 +265,7 @@ void RecentAppHelper::removeAppAreaItem(DockItem *wdg)
updateDockAppVisible(lastVisible);
}
#ifndef USE_AM
QList<DockItem *> RecentAppHelper::dockItemToAppArea() const
{
QList<DockItem *> dockItems;
@ -311,29 +356,59 @@ int RecentAppHelper::getDockItemIndex(DockItem *dockItem, bool isRecent) const
return appItem1->appOpenMSecs() < appItem2->appOpenMSecs();
});
}
int index = sequeDockItems.indexOf(dockItem);
// 查找所有在应用区域的图标
QList<DockItem *> dockApps = dockItems(isRecent);
QList<AppItem *> dockApps = appItems(isRecent ? m_recentWidget : m_appWidget);
for (int i = index + 1; i < sequeDockItems.size(); i++) {
DockItem *item = sequeDockItems[i];
if (dockApps.contains(item))
return dockApps.indexOf(item);
int itemIndex = dockApps.indexOf(static_cast<AppItem *>(item));
if (itemIndex >= 0)
return itemIndex;
}
return -1;
}
#endif
QList<DockItem *> RecentAppHelper::dockItems(bool isRecent) const
int RecentAppHelper::getEntryIndex(DockItem *dockItem, QWidget *widget) const
{
QLayout *layout = nullptr;
if (isRecent)
layout = m_recentWidget->layout();
else
layout = m_appWidget->layout();
AppItem *appItem = qobject_cast<AppItem *>(dockItem);
if (!appItem)
return -1;
QList<DockItem *> dockItems;
// 查找当前的应用在所有的应用中的排序
QStringList entryIds = m_dockInter->GetEntryIDs();
int index = entryIds.indexOf(appItem->appId());
if (index < 0)
return -1;
QList<AppItem *> filterAppItems = appItems(widget);
// 获取当前在最近应用中的所有的APP并计算它的位置
int lastIndex = -1;
// 从后面向前面遍历,找到对应的位置,插入
for (int i = filterAppItems.size() - 1; i >= 0; i--) {
AppItem *item = filterAppItems[i];
// 如果所在的索引在要查找的APP索引的后面说明当前的索引在要查找的索引之后跳过即可
// 如果所在索引不在列表中(一般情况下不存在,这里是容错处理),也跳过
int curIndex = entryIds.indexOf(item->appId());
if (item == appItem || curIndex < 0 || curIndex >= index)
continue;
if (lastIndex < curIndex)
lastIndex = curIndex;
}
return ++lastIndex;
}
QList<AppItem *> RecentAppHelper::appItems(QWidget *widget) const
{
QLayout *layout = widget->layout();
QList<AppItem *> dockItems;
for (int i = 0; i < layout->count(); i++) {
DockItem *dockItem = qobject_cast<DockItem *>(layout->itemAt(i)->widget());
AppItem *dockItem = qobject_cast<AppItem *>(layout->itemAt(i)->widget());
if (!dockItem)
continue;

View File

@ -23,10 +23,12 @@
#define RECENTAPPHELPER_H
#include "constants.h"
#include "dbusutil.h"
#include <QObject>
class DockItem;
class AppItem;
class QWidget;
/** 用来管理最近打开区域和APP应用区域交互的类
@ -38,7 +40,7 @@ class RecentAppHelper : public QObject
Q_OBJECT
public:
explicit RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, QObject *parent = nullptr);
explicit RecentAppHelper(QWidget *appWidget, QWidget *recentWidget, DockInter *dockInter, QObject *parent = nullptr);
void setDisplayMode(Dock::DisplayMode displayMode);
void resetAppInfo();
void addAppItem(int index, DockItem *appItem);
@ -64,22 +66,29 @@ private:
void removeRecentAreaItem(DockItem *wdg);
void removeAppAreaItem(DockItem *wdg);
#ifndef USE_AM
QList<DockItem *> dockItemToAppArea() const;
void resetDockItems();
int getDockItemIndex(DockItem *dockItem, bool isRecent) const;
#endif
int getEntryIndex(DockItem *dockItem, QWidget *widget) const;
QList<DockItem *> dockItems(bool isRecent) const;
QList<AppItem *> appItems(QWidget *widget) const;
private Q_SLOTS:
void onIsDockChanged();
#ifdef USE_AM
void onModeChanged(int mode);
#else
void onItemChanged();
#endif
private:
QWidget *m_appWidget;
QWidget *m_recentWidget;
#ifndef USE_AM
QList<DockItem *> m_sequentDockItems;
#endif
Dock::DisplayMode m_displayMode;
DockInter *m_dockInter;
};
#endif // RECENTAPPHELPER_H

View File

@ -323,6 +323,11 @@ void Dde_Dock::setWindowSizeFashion(uint value)
setProperty("WindowSizeFashion", QVariant::fromValue(value));
}
bool Dde_Dock::showRecent() const
{
return qvariant_cast<bool>(property("ShowRecent"));
}
QDBusPendingReply<> Dde_Dock::ActivateWindow(uint in0)
{
return m_wm->ActivateWindow(in0);

View File

@ -125,6 +125,9 @@ public:
uint windowSizeFashion();
void setWindowSizeFashion(uint value);
Q_PROPERTY(bool ShowRecent READ showRecent NOTIFY showRecentChanged)
bool showRecent() const;
public Q_SLOTS: // METHODS
QDBusPendingReply<> ActivateWindow(uint in0);
@ -263,6 +266,14 @@ public Q_SLOTS: // METHODS
return asyncCallWithArgumentList(QStringLiteral("RequestUndock"), argumentList);
}
inline void SetShowRecent(bool in0)
{
QList<QVariant> argumentList;
argumentList << QVariant::fromValue(in0);
CallQueued(QStringLiteral("SetShowRecent"), argumentList);
}
inline QDBusPendingReply<> SetFrontendWindowRect(int in0, int in1, uint in2, uint in3)
{
QList<QVariant> argumentList;
@ -314,6 +325,7 @@ Q_SIGNALS: // SIGNALS
void WindowSizeChanged(uint value) const;
void WindowSizeEfficientChanged(uint value) const;
void WindowSizeFashionChanged(uint value) const;
void showRecentChanged(bool) const;
public Q_SLOTS:
void CallQueued(const QString &callName, const QList<QVariant> &args);

View File

@ -86,6 +86,7 @@ public:
: CurrentWindow(0)
, IsActive(false)
, IsDocked(false)
, mode(0)
{}
// begin member variables
@ -99,6 +100,7 @@ public:
QString Name;
WindowInfoMap WindowInfos;
int mode;
public:
QMap<QString, QDBusPendingCallWatcher *> m_processingCalls;
@ -131,8 +133,7 @@ void Dock_Entry::onPropertyChanged(const QString &propName, const QVariant &valu
{
if (propName == QStringLiteral("CurrentWindow")) {
const uint &CurrentWindow = qvariant_cast<uint>(value);
if (d_ptr->CurrentWindow != CurrentWindow)
{
if (d_ptr->CurrentWindow != CurrentWindow) {
d_ptr->CurrentWindow = CurrentWindow;
Q_EMIT CurrentWindowChanged(d_ptr->CurrentWindow);
}
@ -158,15 +159,6 @@ void Dock_Entry::onPropertyChanged(const QString &propName, const QVariant &valu
return;
}
if (propName == QStringLiteral("Id")) {
const QString &Id = qvariant_cast<QString>(value);
if (d_ptr->Id != Id) {
d_ptr->Id = Id;
Q_EMIT IdChanged(d_ptr->Id);
}
return;
}
if (propName == QStringLiteral("IsActive")) {
const bool &IsActive = qvariant_cast<bool>(value);
if (d_ptr->IsActive != IsActive) {
@ -212,6 +204,14 @@ void Dock_Entry::onPropertyChanged(const QString &propName, const QVariant &valu
return;
}
if (propName == QStringLiteral("Mode")) {
const int mode = qvariant_cast<int>(value);
if (d_ptr->mode != mode) {
d_ptr->mode = mode;
Q_EMIT ModeChanged(d_ptr->mode);
}
}
qWarning() << "property not handle: " << propName;
return;
}
@ -246,6 +246,11 @@ bool Dock_Entry::isDocked()
return qvariant_cast<bool>(property("IsDocked"));
}
int Dock_Entry::mode() const
{
return qvariant_cast<int>(property("Mode"));
}
QString Dock_Entry::menu()
{
return qvariant_cast<QString>(property("Menu"));

View File

@ -91,7 +91,7 @@ public:
Q_PROPERTY(QString Icon READ icon NOTIFY IconChanged)
QString icon();
Q_PROPERTY(QString Id READ id NOTIFY IdChanged)
Q_PROPERTY(QString Id READ id)
QString id();
Q_PROPERTY(bool IsActive READ isActive NOTIFY IsActiveChanged)
@ -109,6 +109,9 @@ public:
Q_PROPERTY(WindowInfoMap WindowInfos READ windowInfos NOTIFY WindowInfosChanged)
WindowInfoMap windowInfos();
Q_PROPERTY(int Mode READ mode NOTIFY ModeChanged)
int mode() const;
public Q_SLOTS: // METHODS
inline QDBusPendingReply<> Activate(uint in0)
{
@ -243,7 +246,7 @@ Q_SIGNALS: // SIGNALS
void CurrentWindowChanged(uint32_t value) const;
void WindowInfosChanged(WindowInfoMap value) const;
void IdChanged(const QString &value) const;
void ModeChanged(int value) const;
private:
QVariant asyncProperty(const QString &propertyName);

View File

@ -97,8 +97,11 @@ AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSetti
connect(m_itemEntryInter, &DockEntryInter::IsActiveChanged, this, static_cast<void (AppItem::*)()>(&AppItem::update));
connect(m_itemEntryInter, &DockEntryInter::WindowInfosChanged, this, &AppItem::updateWindowInfos, Qt::QueuedConnection);
connect(m_itemEntryInter, &DockEntryInter::IconChanged, this, &AppItem::refreshIcon);
#ifdef USE_AM
connect(m_itemEntryInter, &DockEntryInter::ModeChanged, this, &AppItem::modeChanged);
#else
connect(m_itemEntryInter, &DockEntryInter::IsDockedChanged, this, &AppItem::isDockChanged);
#endif
connect(m_updateIconGeometryTimer, &QTimer::timeout, this, &AppItem::updateWindowIconGeometries, Qt::QueuedConnection);
connect(m_retryObtainIconTimer, &QTimer::timeout, this, &AppItem::refreshIcon, Qt::QueuedConnection);
@ -208,6 +211,13 @@ bool AppItem::splitWindowOnScreen(ScreenSpliter::SplitDirection direction)
return m_screenSpliter->split(direction);
}
#ifdef USE_AM
int AppItem::mode() const
{
return m_itemEntryInter->mode();
}
#endif
QString AppItem::accessibleName()
{
return m_itemEntryInter->name();

View File

@ -76,7 +76,11 @@ signals:
void dragReady(QWidget *dragWidget);
void requestUpdateEntryGeometries() const;
#ifdef USE_AM
void modeChanged(int) const;
#else
void isDockChanged(bool) const;
#endif
private:
void moveEvent(QMoveEvent *e) override;

View File

@ -99,7 +99,8 @@ MainPanelControl::MainPanelControl(QWidget *parent)
, m_displayMode(Efficient)
, m_tray(nullptr)
, m_dockScreen(nullptr)
, m_recentHelper(new RecentAppHelper(m_appAreaSonWidget, m_recentAreaWidget, this))
, m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
, m_recentHelper(new RecentAppHelper(m_appAreaSonWidget, m_recentAreaWidget, m_dockInter, this))
, m_toolHelper(new ToolAppHelper(m_pluginAreaWidget, m_toolAreaWidget, this))
{
initUI();
@ -359,8 +360,11 @@ void MainPanelControl::dockRecentApp(DockItem *dockItem)
if (!appItem)
return;
// TODO 如果控制中心设置不开启最近应用,则不让其驻留
// 如果控制中心设置不开启最近应用,则不让其驻留
#ifdef USE_AM
if (!m_dockInter->showRecent())
return;
#endif
// 如果控制中心开启了最近应用并且当前应用是未驻留应用,则可以驻留
if (!appItem->isDocked())
appItem->requestDock();

View File

@ -23,6 +23,7 @@
#define MAINPANELCONTROL_H
#include "constants.h"
#include "dbusutil.h"
#include <QWidget>
@ -148,6 +149,7 @@ private:
int m_dragIndex = -1; // 记录应用区域被拖拽图标的位置
DockScreen *m_dockScreen;
DockInter *m_dockInter;
RecentAppHelper *m_recentHelper;
ToolAppHelper *m_toolHelper;
};