From 90a076a0435a12c8a79dcc4265c0386dd26a84aa Mon Sep 17 00:00:00 2001 From: donghualin Date: Mon, 15 Aug 2022 18:07:14 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E9=80=82=E9=85=8D?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E4=B8=AD=E5=BF=83=E8=AE=BE=E7=BD=AE=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E4=BD=BF=E7=94=A8=E6=9C=80=E8=BF=91=E5=8C=BA=E5=9F=9F?= =?UTF-8?q?=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 增加获取是否显示最近使用应用的接口,相应相关的功能 Log: Influence: 开关是否显示最近使用应用,时尚模式下观察最近使用应用是否显示或隐藏 Bug: https://pms.uniontech.com/bug-view-147717.html Change-Id: I5de2f978da6f5911a8c873b903095ef9f7bbd14e --- frame/controller/recentapphelper.cpp | 125 +++++++++++++++++++++------ frame/controller/recentapphelper.h | 21 +++-- frame/dbus/dockinterface.cpp | 5 ++ frame/dbus/dockinterface.h | 12 +++ frame/dbus/entryinterface.cpp | 27 +++--- frame/dbus/entryinterface.h | 7 +- frame/item/appitem.cpp | 12 ++- frame/item/appitem.h | 4 + frame/window/mainpanelcontrol.cpp | 10 ++- frame/window/mainpanelcontrol.h | 2 + 10 files changed, 177 insertions(+), 48 deletions(-) diff --git a/frame/controller/recentapphelper.cpp b/frame/controller/recentapphelper.cpp index 1d7440810..fdeb1ec15 100644 --- a/frame/controller/recentapphelper.cpp +++ b/frame/controller/recentapphelper.cpp @@ -24,10 +24,15 @@ #include -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 appDockItem = dockItems(false); + QList appDockItem = appItems(m_appWidget); // 获取应用区域图标在原来列表中的位置 QList 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(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(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(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(sender()); + if (!appItem) + return; + + auto moveItemToWidget = [ = ](QWidget *widget) { + int index = getEntryIndex(appItem, widget); + removeAppItem(appItem); + QBoxLayout *layout = static_cast(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(item); + if (!appItem) + return false; + + return (appItem->mode() == ENTRY_RECENT); +#else // 先判断当前是否为时尚模式,只有时尚模式下才支持最近打开的应用 if (m_displayMode != Dock::DisplayMode::Fashion) return false; - - // TODO 当控制中心不开启最近打开应用的功能的时候,则始终让其显示在应用区域 - // 只有当应用没有固定到任务栏上才认为它是最新打开的应用 AppItem *appItem = qobject_cast(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(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 RecentAppHelper::dockItemToAppArea() const { QList dockItems; @@ -311,29 +356,59 @@ int RecentAppHelper::getDockItemIndex(DockItem *dockItem, bool isRecent) const return appItem1->appOpenMSecs() < appItem2->appOpenMSecs(); }); } + int index = sequeDockItems.indexOf(dockItem); // 查找所有在应用区域的图标 - QList dockApps = dockItems(isRecent); + QList 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(item)); + if (itemIndex >= 0) + return itemIndex; } return -1; } +#endif -QList 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(dockItem); + if (!appItem) + return -1; - QList dockItems; + // 查找当前的应用在所有的应用中的排序 + QStringList entryIds = m_dockInter->GetEntryIDs(); + int index = entryIds.indexOf(appItem->appId()); + if (index < 0) + return -1; + + QList 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 RecentAppHelper::appItems(QWidget *widget) const +{ + QLayout *layout = widget->layout(); + + QList dockItems; for (int i = 0; i < layout->count(); i++) { - DockItem *dockItem = qobject_cast(layout->itemAt(i)->widget()); + AppItem *dockItem = qobject_cast(layout->itemAt(i)->widget()); if (!dockItem) continue; diff --git a/frame/controller/recentapphelper.h b/frame/controller/recentapphelper.h index e515cb256..5b69c51af 100644 --- a/frame/controller/recentapphelper.h +++ b/frame/controller/recentapphelper.h @@ -23,10 +23,12 @@ #define RECENTAPPHELPER_H #include "constants.h" +#include "dbusutil.h" #include 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 dockItemToAppArea() const; void resetDockItems(); int getDockItemIndex(DockItem *dockItem, bool isRecent) const; +#endif + int getEntryIndex(DockItem *dockItem, QWidget *widget) const; - QList dockItems(bool isRecent) const; + QList 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 m_sequentDockItems; - +#endif Dock::DisplayMode m_displayMode; + DockInter *m_dockInter; }; #endif // RECENTAPPHELPER_H diff --git a/frame/dbus/dockinterface.cpp b/frame/dbus/dockinterface.cpp index d02b6fe9c..dfdb7b98b 100644 --- a/frame/dbus/dockinterface.cpp +++ b/frame/dbus/dockinterface.cpp @@ -323,6 +323,11 @@ void Dde_Dock::setWindowSizeFashion(uint value) setProperty("WindowSizeFashion", QVariant::fromValue(value)); } +bool Dde_Dock::showRecent() const +{ + return qvariant_cast(property("ShowRecent")); +} + QDBusPendingReply<> Dde_Dock::ActivateWindow(uint in0) { return m_wm->ActivateWindow(in0); diff --git a/frame/dbus/dockinterface.h b/frame/dbus/dockinterface.h index 1734bea2c..5f04ccd3c 100644 --- a/frame/dbus/dockinterface.h +++ b/frame/dbus/dockinterface.h @@ -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 argumentList; + argumentList << QVariant::fromValue(in0); + + CallQueued(QStringLiteral("SetShowRecent"), argumentList); + } + inline QDBusPendingReply<> SetFrontendWindowRect(int in0, int in1, uint in2, uint in3) { QList 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 &args); diff --git a/frame/dbus/entryinterface.cpp b/frame/dbus/entryinterface.cpp index 8b3242446..dd292f4f5 100644 --- a/frame/dbus/entryinterface.cpp +++ b/frame/dbus/entryinterface.cpp @@ -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 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(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(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(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(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(property("IsDocked")); } +int Dock_Entry::mode() const +{ + return qvariant_cast(property("Mode")); +} + QString Dock_Entry::menu() { return qvariant_cast(property("Menu")); diff --git a/frame/dbus/entryinterface.h b/frame/dbus/entryinterface.h index 4cce4fef6..cc9ad3ccf 100644 --- a/frame/dbus/entryinterface.h +++ b/frame/dbus/entryinterface.h @@ -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); diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index 6958e8c5a..b02a97e8f 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -97,8 +97,11 @@ AppItem::AppItem(const QGSettings *appSettings, const QGSettings *activeAppSetti connect(m_itemEntryInter, &DockEntryInter::IsActiveChanged, this, static_cast(&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(); diff --git a/frame/item/appitem.h b/frame/item/appitem.h index e9d6b0c3c..0414a3499 100644 --- a/frame/item/appitem.h +++ b/frame/item/appitem.h @@ -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; diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index d6b367983..cd7e78da7 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -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(); diff --git a/frame/window/mainpanelcontrol.h b/frame/window/mainpanelcontrol.h index c265af2ce..35c0bdd9f 100755 --- a/frame/window/mainpanelcontrol.h +++ b/frame/window/mainpanelcontrol.h @@ -23,6 +23,7 @@ #define MAINPANELCONTROL_H #include "constants.h" +#include "dbusutil.h" #include @@ -148,6 +149,7 @@ private: int m_dragIndex = -1; // 记录应用区域被拖拽图标的位置 DockScreen *m_dockScreen; + DockInter *m_dockInter; RecentAppHelper *m_recentHelper; ToolAppHelper *m_toolHelper; };