From 9a81886b6a14a28c75d0fc7b1cd8fdc3bec052c8 Mon Sep 17 00:00:00 2001 From: donghualin Date: Fri, 27 May 2022 15:09:15 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=97=B6=E5=B0=9A?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E6=97=A0=E6=B3=95=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E7=94=B5=E6=BA=90=E6=8C=89=E9=92=AE=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原因:电源按钮只会加载一次,在时尚模式下已经加载过,导致在高效模式下没有加载到任务栏的controller中 解决方案:将加载电源按钮的controller用一个单例的代理类来实现,FixedPluginController和DockPluginsController同时引用这个类来加载同一个插件 Log: 解决时尚模式下无法显示电源按钮的问题 Influence: 任务栏-查看高效模式下电源插件是否加载 Bug: https://pms.uniontech.com/bug-view-132733.html Change-Id: I80d0cb9c87e6e1a478410f53a35ccfce344677ea --- frame/controller/dockpluginscontroller.cpp | 41 ++----- frame/controller/dockpluginscontroller.h | 5 +- frame/controller/fixedplugincontroller.cpp | 65 +++++++++++ frame/controller/fixedplugincontroller.h | 54 +++++++++ frame/controller/proxyplugincontroller.cpp | 127 +++++++++++++++++++++ frame/controller/proxyplugincontroller.h | 64 +++++++++++ frame/util/abstractpluginscontroller.h | 4 + frame/window/mainpanelcontrol.cpp | 10 ++ frame/window/systempluginwindow.cpp | 53 +-------- frame/window/systempluginwindow.h | 27 ----- 10 files changed, 338 insertions(+), 112 deletions(-) create mode 100644 frame/controller/fixedplugincontroller.cpp create mode 100644 frame/controller/fixedplugincontroller.h create mode 100644 frame/controller/proxyplugincontroller.cpp create mode 100644 frame/controller/proxyplugincontroller.h diff --git a/frame/controller/dockpluginscontroller.cpp b/frame/controller/dockpluginscontroller.cpp index 012a92f5c..9959290fe 100644 --- a/frame/controller/dockpluginscontroller.cpp +++ b/frame/controller/dockpluginscontroller.cpp @@ -20,6 +20,7 @@ */ #include "dockpluginscontroller.h" +#include "proxyplugincontroller.h" #include "pluginsiteminterface.h" #include "traypluginitem.h" @@ -31,6 +32,13 @@ DockPluginsController::DockPluginsController(QObject *parent) : AbstractPluginsController(parent) { setObjectName("DockPlugin"); + + ProxyPluginController::instance()->addProxyInterface(this); +} + +DockPluginsController::~DockPluginsController() +{ + ProxyPluginController::instance()->removeProxyInterface(this); } void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, const QString &itemKey) @@ -43,10 +51,10 @@ void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, con return; // 取 plugin api - QPluginLoader *pluginLoader = qobject_cast(mPluginsMap[itemInter].value("pluginloader")); - if (!pluginLoader) { + QPluginLoader *pluginLoader = ProxyPluginController::instance()->pluginLoader(itemInter); + if (!pluginLoader) return; - } + const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject(); const QString &pluginApi = meta.value("api").toString(); @@ -135,30 +143,5 @@ void DockPluginsController::requestSetAppletVisible(PluginsItemInterface *const void DockPluginsController::startLoader() { - loadLocalPlugins(); - loadSystemPlugins(); -} - -void DockPluginsController::loadLocalPlugins() -{ - QString pluginsDir(QString("%1/.local/lib/dde-dock/plugins/").arg(QDir::homePath())); - - if (!QDir(pluginsDir).exists()) { - return; - } - - qDebug() << "using dock local plugins dir:" << pluginsDir; - - AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this)); -} - -void DockPluginsController::loadSystemPlugins() -{ - QString pluginsDir(qApp->applicationDirPath() + "/../plugins"); -#ifndef QT_DEBUG - pluginsDir = "/usr/lib/dde-dock/plugins"; -#endif - qDebug() << "using dock plugins dir:" << pluginsDir; - - AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this)); + ProxyPluginController::instance()->startLoader(); } diff --git a/frame/controller/dockpluginscontroller.h b/frame/controller/dockpluginscontroller.h index af759c5de..7a948e516 100644 --- a/frame/controller/dockpluginscontroller.h +++ b/frame/controller/dockpluginscontroller.h @@ -43,6 +43,7 @@ class DockPluginsController : public AbstractPluginsController public: explicit DockPluginsController(QObject *parent = nullptr); + ~DockPluginsController() override; // implements PluginProxyInterface void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; @@ -59,10 +60,6 @@ signals: void pluginItemRemoved(PluginsItem *pluginItem) const; void pluginItemUpdated(PluginsItem *pluginItem) const; void trayVisableCountChanged(const int &count) const; - -private: - void loadLocalPlugins(); - void loadSystemPlugins(); }; #endif // DOCKPLUGINSCONTROLLER_H diff --git a/frame/controller/fixedplugincontroller.cpp b/frame/controller/fixedplugincontroller.cpp new file mode 100644 index 000000000..049fa9bec --- /dev/null +++ b/frame/controller/fixedplugincontroller.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#include "fixedplugincontroller.h" +#include "utils.h" +#include "proxyplugincontroller.h" +#include "systempluginwindow.h" + +FixedPluginController::FixedPluginController(QObject *parent) + : AbstractPluginsController(parent) +{ + setObjectName("FixedPluginController"); + ProxyPluginController::instance()->addProxyInterface(this, QStringList("shutdown")); +} + +FixedPluginController::~FixedPluginController() +{ + ProxyPluginController::instance()->removeProxyInterface(this); +} + +void FixedPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) +{ + StretchPluginsItem *item = new StretchPluginsItem(itemInter, itemKey); + m_pluginItems << item; + Q_EMIT pluginItemInserted(item); +} + +void FixedPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &) +{ + for (StretchPluginsItem *item : m_pluginItems) { + if (item->pluginInter() == itemInter) { + Q_EMIT pluginItemUpdated(item); + break; + } + } +} + +void FixedPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &) +{ + for (StretchPluginsItem *item : m_pluginItems) { + if (item->pluginInter() == itemInter) { + m_pluginItems.removeOne(item); + Q_EMIT pluginItemRemoved(item); + item->deleteLater(); + break; + } + } +} diff --git a/frame/controller/fixedplugincontroller.h b/frame/controller/fixedplugincontroller.h new file mode 100644 index 000000000..5b81be541 --- /dev/null +++ b/frame/controller/fixedplugincontroller.h @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#ifndef FIXEDPLUGINCONTROLLER_H +#define FIXEDPLUGINCONTROLLER_H + +#include "abstractpluginscontroller.h" + +class StretchPluginsItem; + +class FixedPluginController : public AbstractPluginsController +{ + Q_OBJECT + +public: + explicit FixedPluginController(QObject *parent = nullptr); + ~FixedPluginController() override; + +Q_SIGNALS: + void pluginItemInserted(StretchPluginsItem *); + void pluginItemRemoved(StretchPluginsItem *); + void pluginItemUpdated(StretchPluginsItem *); + +protected: + void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; + void itemUpdate(PluginsItemInterface * const itemInter, const QString &) override; + void itemRemoved(PluginsItemInterface * const itemInter, const QString &) override; + + void requestWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {} + void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} + void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} + +private: + QList m_pluginItems; +}; + +#endif // FIXEDPLUGINCONTROLLER_H diff --git a/frame/controller/proxyplugincontroller.cpp b/frame/controller/proxyplugincontroller.cpp new file mode 100644 index 000000000..289a2eee9 --- /dev/null +++ b/frame/controller/proxyplugincontroller.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#include "proxyplugincontroller.h" +#include "pluginsiteminterface.h" + +QMap ProxyPluginController::m_instances = {}; + +// 该方法用来设置所有的需要加载的插件的路径信息 +static QMap> getPluginPaths() +{ + QList pluginPaths; + pluginPaths << QStringList{ QString("%1/.local/lib/dde-dock/plugins/").arg(QDir::homePath()) } + << QStringList{ QString(qApp->applicationDirPath() + "/../plugins"), + QString("/usr/lib/dde-dock/plugins") }; + QMap> plugins; + plugins[FIXEDSYSTEMPLUGIN] = pluginPaths; + return plugins; +} + +// 该方法根据当前加载插件的类型来生成对应的单例的类 +ProxyPluginController *ProxyPluginController::instance(int instanceKey) +{ + static QMap> pluginLoadInfos = getPluginPaths(); + + if (m_instances.contains(instanceKey)) + return m_instances.value(instanceKey); + + // 生成单例类,获取加载插件的路径信息 + ProxyPluginController *controller = new ProxyPluginController(); + controller->m_dirs = (pluginLoadInfos.contains(instanceKey) ? pluginLoadInfos[instanceKey] : QList()); + m_instances[instanceKey] = controller; + return controller; +} + +// 新增要使用的控制器,第二个参数表示当前控制器需要加载的插件名称,为空表示加载所有插件 +void ProxyPluginController::addProxyInterface(AbstractPluginsController *interface, const QStringList &pluginNames) +{ + if (!m_interfaces.contains(interface)) + m_interfaces[interface] = pluginNames; +} + +void ProxyPluginController::removeProxyInterface(AbstractPluginsController *interface) +{ + if (m_interfaces.contains(interface)) + m_interfaces.remove(interface); +} + +ProxyPluginController::ProxyPluginController(QObject *parent) + : AbstractPluginsController(parent) +{ +} + +QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const itemInter) +{ + QMap > &plugin = pluginsMap(); + if (plugin.contains(itemInter)) + return qobject_cast(plugin[itemInter].value("pluginloader")); + + return nullptr; +} + +void ProxyPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) +{ + // 只有当前的controll设置的过滤名称包含当前插件的名称或者过滤名称为空,才新增当前插件 + QList pluginKeys = m_interfaces.keys(); + for (AbstractPluginsController *interface: pluginKeys) { + const QStringList &filterNames = m_interfaces[interface]; + if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName())) + interface->itemAdded(itemInter, itemKey); + } +} + +void ProxyPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) +{ + QList pluginKeys = m_interfaces.keys(); + for (AbstractPluginsController *interface: pluginKeys) { + const QStringList &filterNames = m_interfaces[interface]; + if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName())) + interface->itemUpdate(itemInter, itemKey); + } +} + +void ProxyPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) +{ + QList pluginKeys = m_interfaces.keys(); + for (AbstractPluginsController *interface: pluginKeys) { + const QStringList &filterNames = m_interfaces[interface]; + if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName())) + interface->itemRemoved(itemInter, itemKey); + } +} + +void ProxyPluginController::startLoader() +{ + QDir dir; + for (const QStringList &pluginPaths : m_dirs) { + QString loadPath; + for (const QString &pluginPath : pluginPaths) { + if (!dir.exists(pluginPath)) + continue; + + loadPath = pluginPath; + break; + } + + if (!loadPath.isEmpty()) + AbstractPluginsController::startLoader(new PluginLoader(loadPath, this)); + } +} diff --git a/frame/controller/proxyplugincontroller.h b/frame/controller/proxyplugincontroller.h new file mode 100644 index 000000000..5e9f1042e --- /dev/null +++ b/frame/controller/proxyplugincontroller.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd. + * + * Author: donghualin + * + * Maintainer: donghualin + * + * 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 . + */ +#ifndef PROXYPLUGINCONTROLLER_H +#define PROXYPLUGINCONTROLLER_H + +#include "abstractpluginscontroller.h" + +class PluginsItemInterface; +// 加载的插件的类型 +#define FIXEDSYSTEMPLUGIN 1 + +// 该类是一个底层用来加载系统插件的类,DockPluginsController和 +// FixedPluginController类都是通过这个类来加载系统插件的 +// 该类做成一个单例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说, +// 电源插件在高效模式和特效模式下都需要显示,因此,此类用于加载插件,然后分发到不同的 +// 上层控制器中 +class ProxyPluginController : public AbstractPluginsController +{ + Q_OBJECT + +public: + static ProxyPluginController *instance(int instanceKey = FIXEDSYSTEMPLUGIN); + void addProxyInterface(AbstractPluginsController *interface, const QStringList &pluginNames = QStringList()); + void removeProxyInterface(AbstractPluginsController *interface); + void startLoader(); + QPluginLoader *pluginLoader(PluginsItemInterface * const itemInter); + +protected: + explicit ProxyPluginController(QObject *parent = nullptr); + ~ProxyPluginController() override {} + + void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; + void itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) override; + void itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override; + + void requestWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {} + void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} + void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} + +private: + static QMap m_instances; + QMap m_interfaces; + QList m_dirs; +}; + +#endif // PROXYPLUGINCONTROLLER_H diff --git a/frame/util/abstractpluginscontroller.h b/frame/util/abstractpluginscontroller.h index 80e39a745..84c8e2c2e 100644 --- a/frame/util/abstractpluginscontroller.h +++ b/frame/util/abstractpluginscontroller.h @@ -48,6 +48,10 @@ public: const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) override; void removeValue(PluginsItemInterface * const itemInter, const QStringList &keyList) override; + void itemAdded(PluginsItemInterface * const, const QString &) override {} + void itemUpdate(PluginsItemInterface * const, const QString &) override {} + void itemRemoved(PluginsItemInterface * const, const QString &) override {} + signals: void pluginLoaderFinished(); diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index d8470d827..116f1cad4 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -275,6 +275,8 @@ void MainPanelControl::addTrayAreaItem(int index, QWidget *wdg) { m_tray = static_cast(wdg); m_trayAreaLayout->insertWidget(index, wdg); + if (m_tray) + m_tray->installEventFilter(this); } /**往插件区域添加应用,保存回收站插件指针对象 @@ -670,6 +672,14 @@ void MainPanelControl::dragMoveEvent(QDragMoveEvent *e) bool MainPanelControl::eventFilter(QObject *watched, QEvent *event) { + // 在从时尚模式切换到高效模式的时候, + // m_tray子部件会调整高度,此时会触发m_tray调整尺寸 + // 但是子部件的模式变化函数在FashionTrayItem部件中的 + // NormalContainer部件尺寸变化完成之前就已经结束,导致 + // NormalContainer没有更新自己的尺寸,引起插件区域拥挤 + if (m_tray && watched == m_tray && event->type() == QEvent::Resize) + m_tray->pluginItem()->displayModeChanged(m_dislayMode); + // 更新应用区域大小和任务栏图标大小 if (watched == m_appAreaSonWidget) { switch (event->type()) { diff --git a/frame/window/systempluginwindow.cpp b/frame/window/systempluginwindow.cpp index 827b6fd2c..80c951032 100644 --- a/frame/window/systempluginwindow.cpp +++ b/frame/window/systempluginwindow.cpp @@ -22,6 +22,7 @@ #include "systemplugincontroller.h" #include "systempluginitem.h" #include "dockpluginscontroller.h" +#include "fixedplugincontroller.h" #include #include @@ -43,7 +44,6 @@ SystemPluginWindow::SystemPluginWindow(QWidget *parent) connect(m_pluginController, &FixedPluginController::pluginItemInserted, this, &SystemPluginWindow::onPluginItemAdded); connect(m_pluginController, &FixedPluginController::pluginItemRemoved, this, &SystemPluginWindow::onPluginItemRemoved); connect(m_pluginController, &FixedPluginController::pluginItemUpdated, this, &SystemPluginWindow::onPluginItemUpdated); - QMetaObject::invokeMethod(m_pluginController, &FixedPluginController::startLoader, Qt::QueuedConnection); } SystemPluginWindow::~SystemPluginWindow() @@ -140,57 +140,6 @@ void SystemPluginWindow::onPluginItemUpdated(StretchPluginsItem *pluginItem) pluginItem->update(); } -// can loader plugins -FixedPluginController::FixedPluginController(QObject *parent) - : AbstractPluginsController(parent) -{ - setObjectName("FixedPluginController"); -} - -void FixedPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) -{ - StretchPluginsItem *item = new StretchPluginsItem(itemInter, itemKey); - m_pluginItems << item; - Q_EMIT pluginItemInserted(item); -} - -void FixedPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &) -{ - for (StretchPluginsItem *item : m_pluginItems) { - if (item->pluginInter() == itemInter) { - Q_EMIT pluginItemUpdated(item); - break; - } - } -} - -void FixedPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &) -{ - for (StretchPluginsItem *item : m_pluginItems) { - if (item->pluginInter() == itemInter) { - m_pluginItems.removeOne(item); - Q_EMIT pluginItemRemoved(item); - item->deleteLater(); - break; - } - } -} - -bool FixedPluginController::needLoad(PluginsItemInterface *itemInter) -{ - return (itemInter->pluginName().compare("shutdown") == 0); -} - -void FixedPluginController::startLoader() -{ - QString pluginsDir(qApp->applicationDirPath() + "/../plugins"); - QDir dir(pluginsDir); - if (!dir.exists()) - pluginsDir = "/usr/lib/dde-dock/plugins"; - - AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this)); -} - #define ICONSIZE 20 #define ICONTEXTSPACE 6 #define PLUGIN_ITEM_DRAG_THRESHOLD 20 diff --git a/frame/window/systempluginwindow.h b/frame/window/systempluginwindow.h index 3252f8081..31642cde8 100644 --- a/frame/window/systempluginwindow.h +++ b/frame/window/systempluginwindow.h @@ -65,33 +65,6 @@ private: QBoxLayout *m_mainLayout; }; -class FixedPluginController : public AbstractPluginsController -{ - Q_OBJECT - -public: - explicit FixedPluginController(QObject *parent); - void startLoader(); - -Q_SIGNALS: - void pluginItemInserted(StretchPluginsItem *); - void pluginItemRemoved(StretchPluginsItem *); - void pluginItemUpdated(StretchPluginsItem *); - -protected: - void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; - void itemUpdate(PluginsItemInterface * const itemInter, const QString &) override; - void itemRemoved(PluginsItemInterface * const itemInter, const QString &) override; - bool needLoad(PluginsItemInterface *itemInter) override; - - void requestWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {} - void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} - void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} - -private: - QList m_pluginItems; -}; - class StretchPluginsItem : public DockItem { Q_OBJECT