From 322623427da6664d4d6a5f9e76cd6206af4d8736 Mon Sep 17 00:00:00 2001 From: donghualin Date: Fri, 10 Jun 2022 16:18:15 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=AB=98=E6=95=88=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E4=B8=8B=E5=8A=A0=E8=BD=BD=E5=BF=AB=E6=8D=B7=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 高效模式下增加读取快捷插件并显示 Log: 高效模式显示快捷插件 Influence: 高效模式显示快捷设置插件 Task: https://pms.uniontech.com/task-view-110311.html Change-Id: I308e963b4816737b3f596bc9d4b93db06851f447 --- frame/controller/dockitemmanager.cpp | 6 - frame/controller/dockitemmanager.h | 1 - frame/controller/dockpluginscontroller.cpp | 15 +- frame/controller/dockpluginscontroller.h | 2 - frame/controller/fixedplugincontroller.cpp | 22 +- frame/controller/fixedplugincontroller.h | 2 + frame/controller/proxyplugincontroller.cpp | 196 ++++++++++++++---- frame/controller/proxyplugincontroller.h | 50 ++++- frame/controller/quicksettingcontroller.cpp | 15 +- frame/controller/quicksettingcontroller.h | 1 - frame/dbus/dbusdockadaptors.cpp | 2 +- frame/main.cpp | 8 +- frame/util/abstractpluginscontroller.h | 8 +- frame/window/mainwindow.cpp | 10 +- frame/window/mainwindow.h | 2 +- plugins/shutdown/shutdown.json | 3 +- plugins/tray/CMakeLists.txt | 3 +- .../system-trays/systemtrayscontroller.cpp | 45 ++-- .../tray/system-trays/systemtrayscontroller.h | 8 +- plugins/tray/trayplugin.cpp | 1 - 20 files changed, 288 insertions(+), 112 deletions(-) diff --git a/frame/controller/dockitemmanager.cpp b/frame/controller/dockitemmanager.cpp index af8589882..df5879c16 100644 --- a/frame/controller/dockitemmanager.cpp +++ b/frame/controller/dockitemmanager.cpp @@ -107,12 +107,6 @@ bool DockItemManager::appIsOnDock(const QString &appDesktop) const return m_appInter->IsOnDock(appDesktop); } -void DockItemManager::startLoadPlugins() const -{ - int delay = Utils::SettingValue("com.deepin.dde.dock", "/com/deepin/dde/dock/", "delay-plugins-time", 0).toInt(); - QTimer::singleShot(delay, m_pluginsInter, &DockPluginsController::startLoader); -} - void DockItemManager::refreshItemsIcon() { for (auto item : m_itemList) { diff --git a/frame/controller/dockitemmanager.h b/frame/controller/dockitemmanager.h index 2358f4ca3..2548728c2 100644 --- a/frame/controller/dockitemmanager.h +++ b/frame/controller/dockitemmanager.h @@ -47,7 +47,6 @@ public: const QList > itemList() const; const QList pluginList() const; bool appIsOnDock(const QString &appDesktop) const; - void startLoadPlugins() const; signals: void itemInserted(const int index, DockItem *item) const; diff --git a/frame/controller/dockpluginscontroller.cpp b/frame/controller/dockpluginscontroller.cpp index 9959290fe..623e7a34e 100644 --- a/frame/controller/dockpluginscontroller.cpp +++ b/frame/controller/dockpluginscontroller.cpp @@ -33,12 +33,12 @@ DockPluginsController::DockPluginsController(QObject *parent) { setObjectName("DockPlugin"); - ProxyPluginController::instance()->addProxyInterface(this); + ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this); } DockPluginsController::~DockPluginsController() { - ProxyPluginController::instance()->removeProxyInterface(this); + ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this); } void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, const QString &itemKey) @@ -51,7 +51,11 @@ void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, con return; // 取 plugin api - QPluginLoader *pluginLoader = ProxyPluginController::instance()->pluginLoader(itemInter); + ProxyPluginController *proxyController = ProxyPluginController::instance(itemInter); + if (!proxyController) + return; + + QPluginLoader *pluginLoader = proxyController->pluginLoader(itemInter); if (!pluginLoader) return; @@ -140,8 +144,3 @@ void DockPluginsController::requestSetAppletVisible(PluginsItemInterface *const item->hidePopup(); } } - -void DockPluginsController::startLoader() -{ - ProxyPluginController::instance()->startLoader(); -} diff --git a/frame/controller/dockpluginscontroller.h b/frame/controller/dockpluginscontroller.h index 7a948e516..7c740ab4b 100644 --- a/frame/controller/dockpluginscontroller.h +++ b/frame/controller/dockpluginscontroller.h @@ -53,8 +53,6 @@ public: void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override; void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override; - void startLoader(); - signals: void pluginItemInserted(PluginsItem *pluginItem) const; void pluginItemRemoved(PluginsItem *pluginItem) const; diff --git a/frame/controller/fixedplugincontroller.cpp b/frame/controller/fixedplugincontroller.cpp index 049fa9bec..5e4b5545a 100644 --- a/frame/controller/fixedplugincontroller.cpp +++ b/frame/controller/fixedplugincontroller.cpp @@ -27,12 +27,12 @@ FixedPluginController::FixedPluginController(QObject *parent) : AbstractPluginsController(parent) { setObjectName("FixedPluginController"); - ProxyPluginController::instance()->addProxyInterface(this, QStringList("shutdown")); + ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this); } FixedPluginController::~FixedPluginController() { - ProxyPluginController::instance()->removeProxyInterface(this); + ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this); } void FixedPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) @@ -63,3 +63,21 @@ void FixedPluginController::itemRemoved(PluginsItemInterface * const itemInter, } } } + +bool FixedPluginController::needLoad(PluginsItemInterface *itemInter) +{ + ProxyPluginController *controller = ProxyPluginController::instance(itemInter); + if (!controller) + return false; + + QPluginLoader *pluginLoader = controller->pluginLoader(itemInter); + if (!pluginLoader) + return false; + + // isFixed配置表示该插件在时尚模式下,显示在最右侧的图标,例如关机图标 + QJsonObject json = pluginLoader->metaData().value("MetaData").toObject(); + if (json.contains("fixed")) + return json.value("fixed").toBool(); + + return false; +} diff --git a/frame/controller/fixedplugincontroller.h b/frame/controller/fixedplugincontroller.h index 5b81be541..11ea4c227 100644 --- a/frame/controller/fixedplugincontroller.h +++ b/frame/controller/fixedplugincontroller.h @@ -47,6 +47,8 @@ protected: void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} + bool needLoad(PluginsItemInterface *itemInter) override; + private: QList m_pluginItems; }; diff --git a/frame/controller/proxyplugincontroller.cpp b/frame/controller/proxyplugincontroller.cpp index 289a2eee9..d2b1e4cc8 100644 --- a/frame/controller/proxyplugincontroller.cpp +++ b/frame/controller/proxyplugincontroller.cpp @@ -21,51 +21,92 @@ #include "proxyplugincontroller.h" #include "pluginsiteminterface.h" -QMap ProxyPluginController::m_instances = {}; - // 该方法用来设置所有的需要加载的插件的路径信息 -static QMap> getPluginPaths() +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; + QMap> plugins; + plugins[PluginType::FixedSystemPlugin] = pluginPaths; + + // 添加快捷插件目录 + pluginPaths.clear(); + pluginPaths << QStringList{ QString(qApp->applicationDirPath() + "/../plugins/quick-trays"), + QString("/usr/lib/dde-dock/plugins/quick-trays") }; + plugins[PluginType::QuickPlugin] = pluginPaths; + + // 添加系统插件目录 + pluginPaths.clear(); + pluginPaths << QStringList { QString(qApp->applicationDirPath() + "/../plugins/system-trays"), + QString("/usr/lib/dde-dock/plugins/system-trays") }; + plugins[PluginType::SystemTrays] = pluginPaths; + return plugins; } // 该方法根据当前加载插件的类型来生成对应的单例的类 -ProxyPluginController *ProxyPluginController::instance(int instanceKey) +ProxyPluginController *ProxyPluginController::instance(PluginType instanceKey) { - static QMap> pluginLoadInfos = getPluginPaths(); - - if (m_instances.contains(instanceKey)) - return m_instances.value(instanceKey); + // 此处将这些单例对象存储到了qApp里面,而没有存储到本地的静态变量是因为这个对象会在dock进程和tray插件中同时调用, + // 如果存储到内存的临时变量中,他们就是不同的内存地址,获取到的变量就是多个,这样就会导致相同的插件加载多次, + // 而qApp是dock和插件共用的,因此将对象存储到这里是保证能获取到相同的指针对象 + QMap proxyInstances = qApp->property("proxyController").value>(); + if (proxyInstances.contains(instanceKey)) + return proxyInstances.value(instanceKey); // 生成单例类,获取加载插件的路径信息 + static QMap> pluginLoadInfos = getPluginPaths(); ProxyPluginController *controller = new ProxyPluginController(); controller->m_dirs = (pluginLoadInfos.contains(instanceKey) ? pluginLoadInfos[instanceKey] : QList()); - m_instances[instanceKey] = controller; + proxyInstances[instanceKey] = controller; + qApp->setProperty("proxyController", QVariant::fromValue(proxyInstances)); return controller; } +ProxyPluginController *ProxyPluginController::instance(PluginsItemInterface *itemInter) +{ + // 根据插件指针获取对应的代理对象,因为在监听者里可能存在同时加载多个不同目录的插件,用到的就是多实例, + // 添加插件的时候,不知道当前插件是属于哪个实例,因此在此处添加获取对应插件的实例,方便监听者拿到正确的实例 + QVariant proxyProperty = qApp->property("proxyController"); + if (!proxyProperty.canConvert>()) + return nullptr; + + QMap proxyControllers = proxyProperty.value>(); + for (ProxyPluginController *proxyController : proxyControllers) { + const QList &pluginItems = proxyController->m_pluginsItems; + for (PluginsItemInterface *interPair : pluginItems) { + if (interPair == itemInter) + return proxyController; + } + } + + return nullptr; +} + // 新增要使用的控制器,第二个参数表示当前控制器需要加载的插件名称,为空表示加载所有插件 -void ProxyPluginController::addProxyInterface(AbstractPluginsController *interface, const QStringList &pluginNames) +void ProxyPluginController::addProxyInterface(AbstractPluginsController *interface) { if (!m_interfaces.contains(interface)) - m_interfaces[interface] = pluginNames; + m_interfaces << interface; } void ProxyPluginController::removeProxyInterface(AbstractPluginsController *interface) { - if (m_interfaces.contains(interface)) - m_interfaces.remove(interface); + Q_ASSERT(m_interfaces.contains(interface)); + m_interfaces.removeOne(interface); } ProxyPluginController::ProxyPluginController(QObject *parent) : AbstractPluginsController(parent) { + // 只有在非安全模式下才加载插件,安全模式会在等退出安全模式后通过接受事件的方式来加载插件 + if (!qApp->property("safeMode").toBool()) + QMetaObject::invokeMethod(this, &ProxyPluginController::startLoader, Qt::QueuedConnection); + + qApp->installEventFilter(this); } QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const itemInter) @@ -77,51 +118,130 @@ QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const return nullptr; } +QList ProxyPluginController::pluginsItems() const +{ + return m_pluginsItems; +} + +QString ProxyPluginController::itemKey(PluginsItemInterface *itemInter) const +{ + if (m_pluginsItemKeys.contains(itemInter)) + return m_pluginsItemKeys.value(itemInter); + + return QString(); +} + 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); - } + m_pluginsItems << itemInter; + m_pluginsItemKeys[itemInter] = itemKey; + + // 获取需要加载当前插件的监听者,然后将当前插件添加到监听者 + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + 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); - } + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + 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); + if (m_pluginsItems.contains(itemInter)) + m_pluginsItems.removeOne(itemInter); + + if (m_pluginsItemKeys.contains(itemInter)) + m_pluginsItemKeys.remove(itemInter); + + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + interface->itemRemoved(itemInter, itemKey); +} + +void ProxyPluginController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) +{ + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + interface->requestWindowAutoHide(itemInter, itemKey, autoHide); +} + +void ProxyPluginController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) +{ + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + interface->requestRefreshWindowVisible(itemInter, itemKey); +} + +void ProxyPluginController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) +{ + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + interface->requestSetAppletVisible(itemInter, itemKey, visible); +} + +void ProxyPluginController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) +{ + QList validController = getValidController(itemInter); + for (AbstractPluginsController *interface : validController) + interface->updateDockInfo(itemInter, part); +} + +bool ProxyPluginController::eventFilter(QObject *watched, QEvent *event) +{ + if (watched == qApp && event->type() == PluginLoadEvent::eventType()) { + // 如果收到的是重新加载插件的消息(一般是在退出安全模式后),则直接加载插件即可 + startLoader(); } + + return QObject::eventFilter(watched, event); +} + +QList ProxyPluginController::getValidController(PluginsItemInterface *itemInter) const +{ + QList validController; + for (AbstractPluginsController *interface : m_interfaces) { + if (!interface->needLoad(itemInter)) + continue; + + validController << interface; + } + + return validController; } 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; + AbstractPluginsController::startLoader(new PluginLoader(pluginPath, this)); break; } - - if (!loadPath.isEmpty()) - AbstractPluginsController::startLoader(new PluginLoader(loadPath, this)); } } + +// 注册事件类型 +static QEvent::Type pluginEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User + 1001); + +// 事件处理,当收到该事件的时候,加载插件 +PluginLoadEvent::PluginLoadEvent() + : QEvent(pluginEventType) +{ +} + +PluginLoadEvent::~PluginLoadEvent() +{ +} + +QEvent::Type PluginLoadEvent::eventType() +{ + return pluginEventType; +} diff --git a/frame/controller/proxyplugincontroller.h b/frame/controller/proxyplugincontroller.h index 5e9f1042e..bb928e861 100644 --- a/frame/controller/proxyplugincontroller.h +++ b/frame/controller/proxyplugincontroller.h @@ -24,12 +24,16 @@ #include "abstractpluginscontroller.h" class PluginsItemInterface; -// 加载的插件的类型 -#define FIXEDSYSTEMPLUGIN 1 +// 加载的插件的类型(1 根目录下的插件 2 快捷设置插件 3 系统插件) +enum class PluginType { + FixedSystemPlugin = 0, + QuickPlugin, + SystemTrays +}; // 该类是一个底层用来加载系统插件的类,DockPluginsController和 // FixedPluginController类都是通过这个类来加载系统插件的 -// 该类做成一个单例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说, +// 该类做成一个多例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说, // 电源插件在高效模式和特效模式下都需要显示,因此,此类用于加载插件,然后分发到不同的 // 上层控制器中 class ProxyPluginController : public AbstractPluginsController @@ -37,11 +41,13 @@ class ProxyPluginController : public AbstractPluginsController Q_OBJECT public: - static ProxyPluginController *instance(int instanceKey = FIXEDSYSTEMPLUGIN); - void addProxyInterface(AbstractPluginsController *interface, const QStringList &pluginNames = QStringList()); + static ProxyPluginController *instance(PluginType instanceKey); + static ProxyPluginController *instance(PluginsItemInterface *itemInter); + void addProxyInterface(AbstractPluginsController *interface); void removeProxyInterface(AbstractPluginsController *interface); - void startLoader(); QPluginLoader *pluginLoader(PluginsItemInterface * const itemInter); + QList pluginsItems() const; + QString itemKey(PluginsItemInterface *itemInter) const; protected: explicit ProxyPluginController(QObject *parent = nullptr); @@ -51,14 +57,36 @@ protected: 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 {} + void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override; + void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override; + void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override; + + void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override; + + bool eventFilter(QObject *watched, QEvent *event) override; private: - static QMap m_instances; - QMap m_interfaces; + QList getValidController(PluginsItemInterface *itemInter) const; + // 该方法可以由DockPluginsController类类调用,强制加载,因此,在此处给这个类加载了一个友元 + void startLoader(); + +private: + QList m_interfaces; QList m_dirs; + QList m_pluginsItems; + QMap m_pluginsItemKeys; }; +// 该插件用于处理插件的延迟加载,当退出安全模式后,会收到该事件并加载插件 +class PluginLoadEvent : public QEvent +{ +public: + PluginLoadEvent(); + ~PluginLoadEvent() override; + + static Type eventType(); +}; + +Q_DECLARE_METATYPE(PluginType) + #endif // PROXYPLUGINCONTROLLER_H diff --git a/frame/controller/quicksettingcontroller.cpp b/frame/controller/quicksettingcontroller.cpp index a5bdb523f..7d8d45bd3 100644 --- a/frame/controller/quicksettingcontroller.cpp +++ b/frame/controller/quicksettingcontroller.cpp @@ -21,16 +21,18 @@ #include "quicksettingcontroller.h" #include "quicksettingitem.h" #include "pluginsiteminterface.h" +#include "proxyplugincontroller.h" QuickSettingController::QuickSettingController(QObject *parent) : AbstractPluginsController(parent) { - // 异步加载本地插件 - QMetaObject::invokeMethod(this, &QuickSettingController::startLoader, Qt::QueuedConnection); + // 加载本地插件 + ProxyPluginController::instance(PluginType::QuickPlugin)->addProxyInterface(this); } QuickSettingController::~QuickSettingController() { + ProxyPluginController::instance(PluginType::QuickPlugin)->removeProxyInterface(this); } void QuickSettingController::sortPlugins() @@ -113,12 +115,3 @@ QuickSettingController *QuickSettingController::instance() static QuickSettingController instance; return &instance; } - -void QuickSettingController::startLoader() -{ - QString pluginsDir("../plugins/quick-trays"); - if (!QDir(pluginsDir).exists()) - pluginsDir = "/usr/lib/dde-dock/plugins/quick-trays"; - - AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this)); -} diff --git a/frame/controller/quicksettingcontroller.h b/frame/controller/quicksettingcontroller.h index 859aacbd8..fdd4a1936 100644 --- a/frame/controller/quicksettingcontroller.h +++ b/frame/controller/quicksettingcontroller.h @@ -39,7 +39,6 @@ Q_SIGNALS: void pluginUpdated(PluginsItemInterface *, const DockPart &); protected: - void startLoader(); explicit QuickSettingController(QObject *parent = Q_NULLPTR); ~QuickSettingController() override; diff --git a/frame/dbus/dbusdockadaptors.cpp b/frame/dbus/dbusdockadaptors.cpp index f466575f9..11d5f1ed2 100644 --- a/frame/dbus/dbusdockadaptors.cpp +++ b/frame/dbus/dbusdockadaptors.cpp @@ -86,7 +86,7 @@ void DBusDockAdaptors::callShow() void DBusDockAdaptors::ReloadPlugins() { - return parent()->relaodPlugins(); + return parent()->reloadPlugins(); } QStringList DBusDockAdaptors::GetLoadedPlugins() diff --git a/frame/main.cpp b/frame/main.cpp index 76f0700a6..f8e3530d6 100644 --- a/frame/main.cpp +++ b/frame/main.cpp @@ -218,6 +218,11 @@ int main(int argc, char *argv[]) QDir::setCurrent(QApplication::applicationDirPath()); #endif + // 在qApp中记录当前是否为安全模式,如果为安全模式,则无需加载插件,在退出安全模式下,才正常加载插件 + // 此处设置这个属性必须在MainWindow创建之前,因为在mainWindow中会创建加载插件的代理,会在代理中根据这个属性来判断是否需要加载插件 + bool isSafeMode = IsSaveMode(); + qApp->setProperty("safeMode", isSafeMode); + // 注册任务栏的DBus服务 MainWindow mw; DBusDockAdaptors adaptor(&mw); @@ -236,8 +241,7 @@ int main(int argc, char *argv[]) mw.launch(); // 判断是否进入安全模式,是否带有入参 -x - if (!IsSaveMode() && !parser.isSet(disablePlugOption)) { - DockItemManager::instance()->startLoadPlugins(); + if (!isSafeMode && !parser.isSet(disablePlugOption)) { qApp->setProperty("PLUGINSLOADED", true); } else { mw.sendNotifications(); diff --git a/frame/util/abstractpluginscontroller.h b/frame/util/abstractpluginscontroller.h index d0cd93c84..f98e183ce 100644 --- a/frame/util/abstractpluginscontroller.h +++ b/frame/util/abstractpluginscontroller.h @@ -51,15 +51,17 @@ public: void itemAdded(PluginsItemInterface * const, const QString &) override {} void itemUpdate(PluginsItemInterface * const, const QString &) override {} void itemRemoved(PluginsItemInterface * const, const QString &) override {} + void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override {} + void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override {} + void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override {} void updateDockInfo(PluginsItemInterface *const, const DockPart &) override {} + virtual bool needLoad(PluginsItemInterface *) { return true; } + signals: void pluginLoaderFinished(); -protected: - virtual bool needLoad(PluginsItemInterface *) { return true; } - protected: QMap> &pluginsMap(); QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const; diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index 9f895ef1a..15a94e7db 100755 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -24,6 +24,7 @@ #include "mainpanelcontrol.h" #include "dockitemmanager.h" #include "menuworker.h" +#include "proxyplugincontroller.h" #include #include @@ -186,14 +187,19 @@ void MainWindow::callShow() * @brief MainWindow::relaodPlugins * 需要重新加载插件时,此接口会被调用,目前是用于任务栏的安全模式退出时调用 */ -void MainWindow::relaodPlugins() +void MainWindow::reloadPlugins() { if (qApp->property("PLUGINSLOADED").toBool()) { return; } - DockItemManager::instance()->startLoadPlugins(); + // 发送事件,通知代理来加载插件 + PluginLoadEvent event; + QCoreApplication::sendEvent(qApp, &event); + qApp->setProperty("PLUGINSLOADED", true); + // 退出安全模式 + qApp->setProperty("safeMode", false); } /** diff --git a/frame/window/mainwindow.h b/frame/window/mainwindow.h index ea8856ed6..7bd249c72 100644 --- a/frame/window/mainwindow.h +++ b/frame/window/mainwindow.h @@ -172,7 +172,7 @@ public: public slots: void launch(); void callShow(); - void relaodPlugins(); + void reloadPlugins(); private: using QWidget::show; diff --git a/plugins/shutdown/shutdown.json b/plugins/shutdown/shutdown.json index bec81f0da..cdda5b480 100644 --- a/plugins/shutdown/shutdown.json +++ b/plugins/shutdown/shutdown.json @@ -1,3 +1,4 @@ { - "api": "2.0.0" + "api": "2.0.0", + "fixed": true } diff --git a/plugins/tray/CMakeLists.txt b/plugins/tray/CMakeLists.txt index 630151e2e..012e29b75 100644 --- a/plugins/tray/CMakeLists.txt +++ b/plugins/tray/CMakeLists.txt @@ -15,7 +15,8 @@ file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp" "../../widgets/*.h" "../../widgets/*.cpp" "../../frame/util/imageutil.h" "../../frame/util/imageutil.cpp" "../../frame/util/menudialog.h" "../../frame/util/menudialog.cpp" - "../../frame/util/touchsignalmanager.h" "../../frame/util/touchsignalmanager.cpp") + "../../frame/util/touchsignalmanager.h" "../../frame/util/touchsignalmanager.cpp" + "../../frame/controller/proxyplugincontroller.h" "../../frame/controller/proxyplugincontroller.cpp") find_package(PkgConfig REQUIRED) find_package(Qt5Widgets REQUIRED) diff --git a/plugins/tray/system-trays/systemtrayscontroller.cpp b/plugins/tray/system-trays/systemtrayscontroller.cpp index 4f33c682c..e2a2dba06 100644 --- a/plugins/tray/system-trays/systemtrayscontroller.cpp +++ b/plugins/tray/system-trays/systemtrayscontroller.cpp @@ -22,6 +22,7 @@ #include "systemtrayscontroller.h" #include "pluginsiteminterface.h" #include "utils.h" +#include "proxyplugincontroller.h" #include #include @@ -30,6 +31,22 @@ SystemTraysController::SystemTraysController(QObject *parent) : AbstractPluginsController(parent) { setObjectName("SystemTray"); + + // 将当前对象添加进代理对象列表中,代理对象在加载插件成功后,会调用列表中所有对象的itemAdded方法来添加插件 + ProxyPluginController::instance(PluginType::QuickPlugin)->addProxyInterface(this); + ProxyPluginController::instance(PluginType::SystemTrays)->addProxyInterface(this); + + QMetaObject::invokeMethod(this, [ this ] { + // 在加载当前的tray插件之前,所有的插件已经加载,因此此处需要获取代理中已经加载过的插件来加载到当前布局中 + loadPlugins(ProxyPluginController::instance(PluginType::QuickPlugin)); + loadPlugins(ProxyPluginController::instance(PluginType::SystemTrays)); + }, Qt::QueuedConnection); +} + +SystemTraysController::~SystemTraysController() +{ + ProxyPluginController::instance(PluginType::QuickPlugin)->removeProxyInterface(this); + ProxyPluginController::instance(PluginType::SystemTrays)->removeProxyInterface(this); } void SystemTraysController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) @@ -45,8 +62,7 @@ void SystemTraysController::itemAdded(PluginsItemInterface * const itemInter, co connect(item, &SystemTrayItem::itemVisibleChanged, this, [=] (bool visible){ if (visible) { emit pluginItemAdded(itemKey, item); - } - else { + } else { emit pluginItemRemoved(itemKey, item); } }, Qt::QueuedConnection); @@ -124,9 +140,8 @@ int SystemTraysController::systemTrayItemSortKey(const QString &itemKey) { auto inter = pluginInterAt(itemKey); - if (!inter) { + if (!inter) return -1; - } return inter->itemSortKey(itemKey); } @@ -135,9 +150,8 @@ void SystemTraysController::setSystemTrayItemSortKey(const QString &itemKey, con { auto inter = pluginInterAt(itemKey); - if (!inter) { + if (!inter) return; - } inter->setSortKey(itemKey, order); } @@ -146,9 +160,8 @@ const QVariant SystemTraysController::getValueSystemTrayItem(const QString &item { auto inter = pluginInterAt(itemKey); - if (!inter) { + if (!inter) return QVariant(); - } return getValue(inter, key, fallback); } @@ -157,20 +170,16 @@ void SystemTraysController::saveValueSystemTrayItem(const QString &itemKey, cons { auto inter = pluginInterAt(itemKey); - if (!inter) { + if (!inter) return; - } saveValue(inter, key, value); } -void SystemTraysController::startLoader() +void SystemTraysController::loadPlugins(ProxyPluginController *proxyController) { - QString pluginsDir("../plugins/system-trays"); - if (!QDir(pluginsDir).exists()) { - pluginsDir = "/usr/lib/dde-dock/plugins/system-trays"; - } - qDebug() << "using system tray plugins dir:" << pluginsDir; - - AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this)); + // 加载已有插件,并将其添加到当前的插件中 + const QList &pluginsItems = proxyController->pluginsItems(); + for (PluginsItemInterface *itemInter : pluginsItems) + itemAdded(itemInter, proxyController->itemKey(itemInter)); } diff --git a/plugins/tray/system-trays/systemtrayscontroller.h b/plugins/tray/system-trays/systemtrayscontroller.h index 1b248f9d4..0bd720941 100644 --- a/plugins/tray/system-trays/systemtrayscontroller.h +++ b/plugins/tray/system-trays/systemtrayscontroller.h @@ -34,12 +34,15 @@ #include class PluginsItemInterface; +class ProxyPluginController; + class SystemTraysController : public AbstractPluginsController { Q_OBJECT public: explicit SystemTraysController(QObject *parent = nullptr); + ~SystemTraysController() override; // implements PluginProxyInterface void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; @@ -55,12 +58,13 @@ public: const QVariant getValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant& fallback = QVariant()); void saveValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &value); - void startLoader(); - signals: void pluginItemAdded(const QString &itemKey, AbstractTrayWidget *pluginItem) const; void pluginItemRemoved(const QString &itemKey, AbstractTrayWidget *pluginItem) const; void pluginItemUpdated(const QString &itemKey, AbstractTrayWidget *pluginItem) const; + +private: + void loadPlugins(ProxyPluginController *proxyController); }; #endif // SYSTEMTRAYSCONTROLLER_H diff --git a/plugins/tray/trayplugin.cpp b/plugins/tray/trayplugin.cpp index 7915ba4f9..1060c963a 100644 --- a/plugins/tray/trayplugin.cpp +++ b/plugins/tray/trayplugin.cpp @@ -112,7 +112,6 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter) // 加载sni,xem,自定义indicator协议以及其他托盘插件 QTimer::singleShot(0, this, &TrayPlugin::loadIndicator); - QTimer::singleShot(0, m_systemTraysController, &SystemTraysController::startLoader); QTimer::singleShot(0, this, &TrayPlugin::initSNI); QTimer::singleShot(0, this, &TrayPlugin::initXEmbed); }