feat: 高效模式下加载快捷插件

高效模式下增加读取快捷插件并显示

Log: 高效模式显示快捷插件
Influence: 高效模式显示快捷设置插件
Task: https://pms.uniontech.com/task-view-110311.html
Change-Id: I308e963b4816737b3f596bc9d4b93db06851f447
This commit is contained in:
donghualin 2022-06-10 16:18:15 +00:00
parent 396f8153be
commit 322623427d
20 changed files with 288 additions and 112 deletions

View File

@ -107,12 +107,6 @@ bool DockItemManager::appIsOnDock(const QString &appDesktop) const
return m_appInter->IsOnDock(appDesktop); 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() void DockItemManager::refreshItemsIcon()
{ {
for (auto item : m_itemList) { for (auto item : m_itemList) {

View File

@ -47,7 +47,6 @@ public:
const QList<QPointer<DockItem> > itemList() const; const QList<QPointer<DockItem> > itemList() const;
const QList<PluginsItemInterface *> pluginList() const; const QList<PluginsItemInterface *> pluginList() const;
bool appIsOnDock(const QString &appDesktop) const; bool appIsOnDock(const QString &appDesktop) const;
void startLoadPlugins() const;
signals: signals:
void itemInserted(const int index, DockItem *item) const; void itemInserted(const int index, DockItem *item) const;

View File

@ -33,12 +33,12 @@ DockPluginsController::DockPluginsController(QObject *parent)
{ {
setObjectName("DockPlugin"); setObjectName("DockPlugin");
ProxyPluginController::instance()->addProxyInterface(this); ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this);
} }
DockPluginsController::~DockPluginsController() DockPluginsController::~DockPluginsController()
{ {
ProxyPluginController::instance()->removeProxyInterface(this); ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this);
} }
void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, const QString &itemKey) void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, const QString &itemKey)
@ -51,7 +51,11 @@ void DockPluginsController::itemAdded(PluginsItemInterface *const itemInter, con
return; return;
// 取 plugin api // 取 plugin api
QPluginLoader *pluginLoader = ProxyPluginController::instance()->pluginLoader(itemInter); ProxyPluginController *proxyController = ProxyPluginController::instance(itemInter);
if (!proxyController)
return;
QPluginLoader *pluginLoader = proxyController->pluginLoader(itemInter);
if (!pluginLoader) if (!pluginLoader)
return; return;
@ -140,8 +144,3 @@ void DockPluginsController::requestSetAppletVisible(PluginsItemInterface *const
item->hidePopup(); item->hidePopup();
} }
} }
void DockPluginsController::startLoader()
{
ProxyPluginController::instance()->startLoader();
}

View File

@ -53,8 +53,6 @@ public:
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override; void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override; void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override;
void startLoader();
signals: signals:
void pluginItemInserted(PluginsItem *pluginItem) const; void pluginItemInserted(PluginsItem *pluginItem) const;
void pluginItemRemoved(PluginsItem *pluginItem) const; void pluginItemRemoved(PluginsItem *pluginItem) const;

View File

@ -27,12 +27,12 @@ FixedPluginController::FixedPluginController(QObject *parent)
: AbstractPluginsController(parent) : AbstractPluginsController(parent)
{ {
setObjectName("FixedPluginController"); setObjectName("FixedPluginController");
ProxyPluginController::instance()->addProxyInterface(this, QStringList("shutdown")); ProxyPluginController::instance(PluginType::FixedSystemPlugin)->addProxyInterface(this);
} }
FixedPluginController::~FixedPluginController() FixedPluginController::~FixedPluginController()
{ {
ProxyPluginController::instance()->removeProxyInterface(this); ProxyPluginController::instance(PluginType::FixedSystemPlugin)->removeProxyInterface(this);
} }
void FixedPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) 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;
}

View File

@ -47,6 +47,8 @@ protected:
void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {}
void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {} void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) override {}
bool needLoad(PluginsItemInterface *itemInter) override;
private: private:
QList<StretchPluginsItem *> m_pluginItems; QList<StretchPluginsItem *> m_pluginItems;
}; };

View File

@ -21,51 +21,92 @@
#include "proxyplugincontroller.h" #include "proxyplugincontroller.h"
#include "pluginsiteminterface.h" #include "pluginsiteminterface.h"
QMap<int, ProxyPluginController *> ProxyPluginController::m_instances = {};
// 该方法用来设置所有的需要加载的插件的路径信息 // 该方法用来设置所有的需要加载的插件的路径信息
static QMap<int, QList<QStringList>> getPluginPaths() static QMap<PluginType, QList<QStringList>> getPluginPaths()
{ {
// 添加系统目录
QList<QStringList> pluginPaths; QList<QStringList> pluginPaths;
pluginPaths << QStringList{ QString("%1/.local/lib/dde-dock/plugins/").arg(QDir::homePath()) } pluginPaths << QStringList{ QString("%1/.local/lib/dde-dock/plugins/").arg(QDir::homePath()) }
<< QStringList{ QString(qApp->applicationDirPath() + "/../plugins"), << QStringList{ QString(qApp->applicationDirPath() + "/../plugins"),
QString("/usr/lib/dde-dock/plugins") }; QString("/usr/lib/dde-dock/plugins") };
QMap<int, QList<QStringList>> plugins; QMap<PluginType, QList<QStringList>> plugins;
plugins[FIXEDSYSTEMPLUGIN] = pluginPaths; 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; return plugins;
} }
// 该方法根据当前加载插件的类型来生成对应的单例的类 // 该方法根据当前加载插件的类型来生成对应的单例的类
ProxyPluginController *ProxyPluginController::instance(int instanceKey) ProxyPluginController *ProxyPluginController::instance(PluginType instanceKey)
{ {
static QMap<int, QList<QStringList>> pluginLoadInfos = getPluginPaths(); // 此处将这些单例对象存储到了qApp里面而没有存储到本地的静态变量是因为这个对象会在dock进程和tray插件中同时调用
// 如果存储到内存的临时变量中,他们就是不同的内存地址,获取到的变量就是多个,这样就会导致相同的插件加载多次,
if (m_instances.contains(instanceKey)) // 而qApp是dock和插件共用的因此将对象存储到这里是保证能获取到相同的指针对象
return m_instances.value(instanceKey); QMap<PluginType, ProxyPluginController *> proxyInstances = qApp->property("proxyController").value<QMap<PluginType, ProxyPluginController *>>();
if (proxyInstances.contains(instanceKey))
return proxyInstances.value(instanceKey);
// 生成单例类,获取加载插件的路径信息 // 生成单例类,获取加载插件的路径信息
static QMap<PluginType, QList<QStringList>> pluginLoadInfos = getPluginPaths();
ProxyPluginController *controller = new ProxyPluginController(); ProxyPluginController *controller = new ProxyPluginController();
controller->m_dirs = (pluginLoadInfos.contains(instanceKey) ? pluginLoadInfos[instanceKey] : QList<QStringList>()); controller->m_dirs = (pluginLoadInfos.contains(instanceKey) ? pluginLoadInfos[instanceKey] : QList<QStringList>());
m_instances[instanceKey] = controller; proxyInstances[instanceKey] = controller;
qApp->setProperty("proxyController", QVariant::fromValue(proxyInstances));
return controller; return controller;
} }
ProxyPluginController *ProxyPluginController::instance(PluginsItemInterface *itemInter)
{
// 根据插件指针获取对应的代理对象,因为在监听者里可能存在同时加载多个不同目录的插件,用到的就是多实例,
// 添加插件的时候,不知道当前插件是属于哪个实例,因此在此处添加获取对应插件的实例,方便监听者拿到正确的实例
QVariant proxyProperty = qApp->property("proxyController");
if (!proxyProperty.canConvert<QMap<PluginType, ProxyPluginController *>>())
return nullptr;
QMap<PluginType, ProxyPluginController *> proxyControllers = proxyProperty.value<QMap<PluginType, ProxyPluginController *>>();
for (ProxyPluginController *proxyController : proxyControllers) {
const QList<PluginsItemInterface *> &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)) if (!m_interfaces.contains(interface))
m_interfaces[interface] = pluginNames; m_interfaces << interface;
} }
void ProxyPluginController::removeProxyInterface(AbstractPluginsController *interface) void ProxyPluginController::removeProxyInterface(AbstractPluginsController *interface)
{ {
if (m_interfaces.contains(interface)) Q_ASSERT(m_interfaces.contains(interface));
m_interfaces.remove(interface); m_interfaces.removeOne(interface);
} }
ProxyPluginController::ProxyPluginController(QObject *parent) ProxyPluginController::ProxyPluginController(QObject *parent)
: AbstractPluginsController(parent) : AbstractPluginsController(parent)
{ {
// 只有在非安全模式下才加载插件,安全模式会在等退出安全模式后通过接受事件的方式来加载插件
if (!qApp->property("safeMode").toBool())
QMetaObject::invokeMethod(this, &ProxyPluginController::startLoader, Qt::QueuedConnection);
qApp->installEventFilter(this);
} }
QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const itemInter) QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const itemInter)
@ -77,51 +118,130 @@ QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const
return nullptr; return nullptr;
} }
QList<PluginsItemInterface *> 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) void ProxyPluginController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{ {
// 只有当前的controll设置的过滤名称包含当前插件的名称或者过滤名称为空才新增当前插件 m_pluginsItems << itemInter;
QList<AbstractPluginsController *> pluginKeys = m_interfaces.keys(); m_pluginsItemKeys[itemInter] = itemKey;
for (AbstractPluginsController *interface: pluginKeys) {
const QStringList &filterNames = m_interfaces[interface]; // 获取需要加载当前插件的监听者,然后将当前插件添加到监听者
if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName())) QList<AbstractPluginsController *> validController = getValidController(itemInter);
interface->itemAdded(itemInter, itemKey); for (AbstractPluginsController *interface : validController)
} interface->itemAdded(itemInter, itemKey);
} }
void ProxyPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) void ProxyPluginController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{ {
QList<AbstractPluginsController *> pluginKeys = m_interfaces.keys(); QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface: pluginKeys) { for (AbstractPluginsController *interface : validController)
const QStringList &filterNames = m_interfaces[interface]; interface->itemUpdate(itemInter, itemKey);
if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName()))
interface->itemUpdate(itemInter, itemKey);
}
} }
void ProxyPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) void ProxyPluginController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{ {
QList<AbstractPluginsController *> pluginKeys = m_interfaces.keys(); if (m_pluginsItems.contains(itemInter))
for (AbstractPluginsController *interface: pluginKeys) { m_pluginsItems.removeOne(itemInter);
const QStringList &filterNames = m_interfaces[interface];
if (filterNames.isEmpty() || filterNames.contains(itemInter->pluginName())) if (m_pluginsItemKeys.contains(itemInter))
interface->itemRemoved(itemInter, itemKey); m_pluginsItemKeys.remove(itemInter);
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->itemRemoved(itemInter, itemKey);
}
void ProxyPluginController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestWindowAutoHide(itemInter, itemKey, autoHide);
}
void ProxyPluginController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestRefreshWindowVisible(itemInter, itemKey);
}
void ProxyPluginController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestSetAppletVisible(itemInter, itemKey, visible);
}
void ProxyPluginController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part)
{
QList<AbstractPluginsController *> 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<AbstractPluginsController *> ProxyPluginController::getValidController(PluginsItemInterface *itemInter) const
{
QList<AbstractPluginsController *> validController;
for (AbstractPluginsController *interface : m_interfaces) {
if (!interface->needLoad(itemInter))
continue;
validController << interface;
}
return validController;
} }
void ProxyPluginController::startLoader() void ProxyPluginController::startLoader()
{ {
QDir dir; QDir dir;
for (const QStringList &pluginPaths : m_dirs) { for (const QStringList &pluginPaths : m_dirs) {
QString loadPath;
for (const QString &pluginPath : pluginPaths) { for (const QString &pluginPath : pluginPaths) {
if (!dir.exists(pluginPath)) if (!dir.exists(pluginPath))
continue; continue;
loadPath = pluginPath; AbstractPluginsController::startLoader(new PluginLoader(pluginPath, this));
break; 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;
}

View File

@ -24,12 +24,16 @@
#include "abstractpluginscontroller.h" #include "abstractpluginscontroller.h"
class PluginsItemInterface; class PluginsItemInterface;
// 加载的插件的类型 // 加载的插件的类型(1 根目录下的插件 2 快捷设置插件 3 系统插件)
#define FIXEDSYSTEMPLUGIN 1 enum class PluginType {
FixedSystemPlugin = 0,
QuickPlugin,
SystemTrays
};
// 该类是一个底层用来加载系统插件的类DockPluginsController和 // 该类是一个底层用来加载系统插件的类DockPluginsController和
// FixedPluginController类都是通过这个类来加载系统插件的 // FixedPluginController类都是通过这个类来加载系统插件的
// 该类做成一个单例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说, // 该类做成一个例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说,
// 电源插件在高效模式和特效模式下都需要显示,因此,此类用于加载插件,然后分发到不同的 // 电源插件在高效模式和特效模式下都需要显示,因此,此类用于加载插件,然后分发到不同的
// 上层控制器中 // 上层控制器中
class ProxyPluginController : public AbstractPluginsController class ProxyPluginController : public AbstractPluginsController
@ -37,11 +41,13 @@ class ProxyPluginController : public AbstractPluginsController
Q_OBJECT Q_OBJECT
public: public:
static ProxyPluginController *instance(int instanceKey = FIXEDSYSTEMPLUGIN); static ProxyPluginController *instance(PluginType instanceKey);
void addProxyInterface(AbstractPluginsController *interface, const QStringList &pluginNames = QStringList()); static ProxyPluginController *instance(PluginsItemInterface *itemInter);
void addProxyInterface(AbstractPluginsController *interface);
void removeProxyInterface(AbstractPluginsController *interface); void removeProxyInterface(AbstractPluginsController *interface);
void startLoader();
QPluginLoader *pluginLoader(PluginsItemInterface * const itemInter); QPluginLoader *pluginLoader(PluginsItemInterface * const itemInter);
QList<PluginsItemInterface *> pluginsItems() const;
QString itemKey(PluginsItemInterface *itemInter) const;
protected: protected:
explicit ProxyPluginController(QObject *parent = nullptr); explicit ProxyPluginController(QObject *parent = nullptr);
@ -51,14 +57,36 @@ protected:
void itemUpdate(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 itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {} void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override;
void requestRefreshWindowVisible(PluginsItemInterface * const, const QString &) override {} void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestSetAppletVisible(PluginsItemInterface * const, const QString &, const bool) 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: private:
static QMap<int, ProxyPluginController *> m_instances; QList<AbstractPluginsController *> getValidController(PluginsItemInterface *itemInter) const;
QMap<AbstractPluginsController *, QStringList> m_interfaces; // 该方法可以由DockPluginsController类类调用强制加载因此在此处给这个类加载了一个友元
void startLoader();
private:
QList<AbstractPluginsController *> m_interfaces;
QList<QStringList> m_dirs; QList<QStringList> m_dirs;
QList<PluginsItemInterface *> m_pluginsItems;
QMap<PluginsItemInterface *, QString> m_pluginsItemKeys;
}; };
// 该插件用于处理插件的延迟加载,当退出安全模式后,会收到该事件并加载插件
class PluginLoadEvent : public QEvent
{
public:
PluginLoadEvent();
~PluginLoadEvent() override;
static Type eventType();
};
Q_DECLARE_METATYPE(PluginType)
#endif // PROXYPLUGINCONTROLLER_H #endif // PROXYPLUGINCONTROLLER_H

View File

@ -21,16 +21,18 @@
#include "quicksettingcontroller.h" #include "quicksettingcontroller.h"
#include "quicksettingitem.h" #include "quicksettingitem.h"
#include "pluginsiteminterface.h" #include "pluginsiteminterface.h"
#include "proxyplugincontroller.h"
QuickSettingController::QuickSettingController(QObject *parent) QuickSettingController::QuickSettingController(QObject *parent)
: AbstractPluginsController(parent) : AbstractPluginsController(parent)
{ {
// 异步加载本地插件 // 加载本地插件
QMetaObject::invokeMethod(this, &QuickSettingController::startLoader, Qt::QueuedConnection); ProxyPluginController::instance(PluginType::QuickPlugin)->addProxyInterface(this);
} }
QuickSettingController::~QuickSettingController() QuickSettingController::~QuickSettingController()
{ {
ProxyPluginController::instance(PluginType::QuickPlugin)->removeProxyInterface(this);
} }
void QuickSettingController::sortPlugins() void QuickSettingController::sortPlugins()
@ -113,12 +115,3 @@ QuickSettingController *QuickSettingController::instance()
static QuickSettingController instance; static QuickSettingController instance;
return &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));
}

View File

@ -39,7 +39,6 @@ Q_SIGNALS:
void pluginUpdated(PluginsItemInterface *, const DockPart &); void pluginUpdated(PluginsItemInterface *, const DockPart &);
protected: protected:
void startLoader();
explicit QuickSettingController(QObject *parent = Q_NULLPTR); explicit QuickSettingController(QObject *parent = Q_NULLPTR);
~QuickSettingController() override; ~QuickSettingController() override;

View File

@ -86,7 +86,7 @@ void DBusDockAdaptors::callShow()
void DBusDockAdaptors::ReloadPlugins() void DBusDockAdaptors::ReloadPlugins()
{ {
return parent()->relaodPlugins(); return parent()->reloadPlugins();
} }
QStringList DBusDockAdaptors::GetLoadedPlugins() QStringList DBusDockAdaptors::GetLoadedPlugins()

View File

@ -218,6 +218,11 @@ int main(int argc, char *argv[])
QDir::setCurrent(QApplication::applicationDirPath()); QDir::setCurrent(QApplication::applicationDirPath());
#endif #endif
// 在qApp中记录当前是否为安全模式如果为安全模式则无需加载插件在退出安全模式下才正常加载插件
// 此处设置这个属性必须在MainWindow创建之前因为在mainWindow中会创建加载插件的代理会在代理中根据这个属性来判断是否需要加载插件
bool isSafeMode = IsSaveMode();
qApp->setProperty("safeMode", isSafeMode);
// 注册任务栏的DBus服务 // 注册任务栏的DBus服务
MainWindow mw; MainWindow mw;
DBusDockAdaptors adaptor(&mw); DBusDockAdaptors adaptor(&mw);
@ -236,8 +241,7 @@ int main(int argc, char *argv[])
mw.launch(); mw.launch();
// 判断是否进入安全模式,是否带有入参 -x // 判断是否进入安全模式,是否带有入参 -x
if (!IsSaveMode() && !parser.isSet(disablePlugOption)) { if (!isSafeMode && !parser.isSet(disablePlugOption)) {
DockItemManager::instance()->startLoadPlugins();
qApp->setProperty("PLUGINSLOADED", true); qApp->setProperty("PLUGINSLOADED", true);
} else { } else {
mw.sendNotifications(); mw.sendNotifications();

View File

@ -51,15 +51,17 @@ public:
void itemAdded(PluginsItemInterface * const, const QString &) override {} void itemAdded(PluginsItemInterface * const, const QString &) override {}
void itemUpdate(PluginsItemInterface * const, const QString &) override {} void itemUpdate(PluginsItemInterface * const, const QString &) override {}
void itemRemoved(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 {} void updateDockInfo(PluginsItemInterface *const, const DockPart &) override {}
virtual bool needLoad(PluginsItemInterface *) { return true; }
signals: signals:
void pluginLoaderFinished(); void pluginLoaderFinished();
protected:
virtual bool needLoad(PluginsItemInterface *) { return true; }
protected: protected:
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap(); QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap();
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const; QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;

View File

@ -24,6 +24,7 @@
#include "mainpanelcontrol.h" #include "mainpanelcontrol.h"
#include "dockitemmanager.h" #include "dockitemmanager.h"
#include "menuworker.h" #include "menuworker.h"
#include "proxyplugincontroller.h"
#include <DStyle> #include <DStyle>
#include <DPlatformWindowHandle> #include <DPlatformWindowHandle>
@ -186,14 +187,19 @@ void MainWindow::callShow()
* @brief MainWindow::relaodPlugins * @brief MainWindow::relaodPlugins
* 退 * 退
*/ */
void MainWindow::relaodPlugins() void MainWindow::reloadPlugins()
{ {
if (qApp->property("PLUGINSLOADED").toBool()) { if (qApp->property("PLUGINSLOADED").toBool()) {
return; return;
} }
DockItemManager::instance()->startLoadPlugins(); // 发送事件,通知代理来加载插件
PluginLoadEvent event;
QCoreApplication::sendEvent(qApp, &event);
qApp->setProperty("PLUGINSLOADED", true); qApp->setProperty("PLUGINSLOADED", true);
// 退出安全模式
qApp->setProperty("safeMode", false);
} }
/** /**

View File

@ -172,7 +172,7 @@ public:
public slots: public slots:
void launch(); void launch();
void callShow(); void callShow();
void relaodPlugins(); void reloadPlugins();
private: private:
using QWidget::show; using QWidget::show;

View File

@ -1,3 +1,4 @@
{ {
"api": "2.0.0" "api": "2.0.0",
"fixed": true
} }

View File

@ -15,7 +15,8 @@ file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp"
"../../widgets/*.h" "../../widgets/*.cpp" "../../widgets/*.h" "../../widgets/*.cpp"
"../../frame/util/imageutil.h" "../../frame/util/imageutil.cpp" "../../frame/util/imageutil.h" "../../frame/util/imageutil.cpp"
"../../frame/util/menudialog.h" "../../frame/util/menudialog.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(PkgConfig REQUIRED)
find_package(Qt5Widgets REQUIRED) find_package(Qt5Widgets REQUIRED)

View File

@ -22,6 +22,7 @@
#include "systemtrayscontroller.h" #include "systemtrayscontroller.h"
#include "pluginsiteminterface.h" #include "pluginsiteminterface.h"
#include "utils.h" #include "utils.h"
#include "proxyplugincontroller.h"
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@ -30,6 +31,22 @@ SystemTraysController::SystemTraysController(QObject *parent)
: AbstractPluginsController(parent) : AbstractPluginsController(parent)
{ {
setObjectName("SystemTray"); 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) 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){ connect(item, &SystemTrayItem::itemVisibleChanged, this, [=] (bool visible){
if (visible) { if (visible) {
emit pluginItemAdded(itemKey, item); emit pluginItemAdded(itemKey, item);
} } else {
else {
emit pluginItemRemoved(itemKey, item); emit pluginItemRemoved(itemKey, item);
} }
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@ -124,9 +140,8 @@ int SystemTraysController::systemTrayItemSortKey(const QString &itemKey)
{ {
auto inter = pluginInterAt(itemKey); auto inter = pluginInterAt(itemKey);
if (!inter) { if (!inter)
return -1; return -1;
}
return inter->itemSortKey(itemKey); return inter->itemSortKey(itemKey);
} }
@ -135,9 +150,8 @@ void SystemTraysController::setSystemTrayItemSortKey(const QString &itemKey, con
{ {
auto inter = pluginInterAt(itemKey); auto inter = pluginInterAt(itemKey);
if (!inter) { if (!inter)
return; return;
}
inter->setSortKey(itemKey, order); inter->setSortKey(itemKey, order);
} }
@ -146,9 +160,8 @@ const QVariant SystemTraysController::getValueSystemTrayItem(const QString &item
{ {
auto inter = pluginInterAt(itemKey); auto inter = pluginInterAt(itemKey);
if (!inter) { if (!inter)
return QVariant(); return QVariant();
}
return getValue(inter, key, fallback); return getValue(inter, key, fallback);
} }
@ -157,20 +170,16 @@ void SystemTraysController::saveValueSystemTrayItem(const QString &itemKey, cons
{ {
auto inter = pluginInterAt(itemKey); auto inter = pluginInterAt(itemKey);
if (!inter) { if (!inter)
return; return;
}
saveValue(inter, key, value); saveValue(inter, key, value);
} }
void SystemTraysController::startLoader() void SystemTraysController::loadPlugins(ProxyPluginController *proxyController)
{ {
QString pluginsDir("../plugins/system-trays"); // 加载已有插件,并将其添加到当前的插件中
if (!QDir(pluginsDir).exists()) { const QList<PluginsItemInterface *> &pluginsItems = proxyController->pluginsItems();
pluginsDir = "/usr/lib/dde-dock/plugins/system-trays"; for (PluginsItemInterface *itemInter : pluginsItems)
} itemAdded(itemInter, proxyController->itemKey(itemInter));
qDebug() << "using system tray plugins dir:" << pluginsDir;
AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this));
} }

View File

@ -34,12 +34,15 @@
#include <QDBusConnectionInterface> #include <QDBusConnectionInterface>
class PluginsItemInterface; class PluginsItemInterface;
class ProxyPluginController;
class SystemTraysController : public AbstractPluginsController class SystemTraysController : public AbstractPluginsController
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit SystemTraysController(QObject *parent = nullptr); explicit SystemTraysController(QObject *parent = nullptr);
~SystemTraysController() override;
// implements PluginProxyInterface // implements PluginProxyInterface
void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override; 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()); 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 saveValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &value);
void startLoader();
signals: signals:
void pluginItemAdded(const QString &itemKey, AbstractTrayWidget *pluginItem) const; void pluginItemAdded(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
void pluginItemRemoved(const QString &itemKey, AbstractTrayWidget *pluginItem) const; void pluginItemRemoved(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
void pluginItemUpdated(const QString &itemKey, AbstractTrayWidget *pluginItem) const; void pluginItemUpdated(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
private:
void loadPlugins(ProxyPluginController *proxyController);
}; };
#endif // SYSTEMTRAYSCONTROLLER_H #endif // SYSTEMTRAYSCONTROLLER_H

View File

@ -112,7 +112,6 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
// 加载snixem自定义indicator协议以及其他托盘插件 // 加载snixem自定义indicator协议以及其他托盘插件
QTimer::singleShot(0, this, &TrayPlugin::loadIndicator); QTimer::singleShot(0, this, &TrayPlugin::loadIndicator);
QTimer::singleShot(0, m_systemTraysController, &SystemTraysController::startLoader);
QTimer::singleShot(0, this, &TrayPlugin::initSNI); QTimer::singleShot(0, this, &TrayPlugin::initSNI);
QTimer::singleShot(0, this, &TrayPlugin::initXEmbed); QTimer::singleShot(0, this, &TrayPlugin::initXEmbed);
} }