feat: 加载基本插件

加载pluginmanager插件,其他的插件由pluginmanager插件来加载

Log:
Influence: 插件加载
Task: https://pms.uniontech.com/task-view-222353.html
Change-Id: Ibe3cb59c5e3da27d7547d9bea8e05ebcd03c5a87
This commit is contained in:
donghualin 2023-01-12 11:06:36 +08:00
parent 4a2847f03f
commit bc840d233d
20 changed files with 134 additions and 1102 deletions

View File

@ -16,8 +16,8 @@
"permissions":"readwrite",
"visibility":"public"
},
"Dock_Quick_Plugin_Name": {
"value": ["network", "sound", "power", "shutdown", "trash"],
"Dock_Quick_Plugins": {
"value": ["shutdown", "trash"],
"serial": 0,
"flags": [],
"name": "显示在任务栏上的快捷插件",

View File

@ -27,7 +27,6 @@
#include "utils.h"
#include "appmultiitem.h"
#include "quicksettingcontroller.h"
#include "proxyplugincontroller.h"
#include <QDebug>
#include <QGSettings>
@ -74,7 +73,7 @@ DockItemManager::DockItemManager(QObject *parent)
connect(quickController, &QuickSettingController::pluginRemoved, this, &DockItemManager::onPluginItemRemoved);
connect(quickController, &QuickSettingController::pluginUpdated, this, &DockItemManager::onPluginUpdate);
connect(ProxyPluginController::instance(), &ProxyPluginController::pluginLoaderFinished, this, &DockItemManager::onPluginLoadFinished, Qt::QueuedConnection);
connect(quickController, &QuickSettingController::pluginLoaderFinished, this, &DockItemManager::onPluginLoadFinished, Qt::QueuedConnection);
// 应用信号
connect(m_appInter, &DockInter::EntryAdded, this, &DockItemManager::appItemAdded);

View File

@ -1,288 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "proxyplugincontroller.h"
#include "pluginsiteminterface.h"
#include "constants.h"
#include <QSettings>
#ifndef QT_DEBUG
static QStringList getPathFromConf(const QString &key) {
QSettings set("/etc/deepin/dde-dock.conf", QSettings::IniFormat);
auto value = set.value(key).toString();
if (!value.isEmpty()) {
return value.split(':');
}
return QStringList();
}
#endif
// 该方法用来设置所有的需要加载的插件的路径信息
static QMap<PluginType, QStringList> getPluginPaths()
{
QMap<PluginType, QStringList> plugins;
// 添加快捷插件目录
{
QStringList pluginPaths;
#ifdef QT_DEBUG
pluginPaths << QString("%1/..%2").arg(qApp->applicationDirPath()).arg(QUICK_PATH)
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(PLUGIN_PATH)
<< QString("%1/..%2").arg(qApp->applicationDirPath()).arg(TRAY_PATH);
#else
pluginPaths << QString("/usr/lib/dde-dock%1").arg(QUICK_PATH)
<< QString("/usr/lib/dde-dock%1").arg(PLUGIN_PATH)
<< QString("/usr/lib/dde-dock%1").arg(TRAY_PATH);
const QStringList pluginsDirs = (getPathFromConf("QUICK_TRAY_PATH") << getPathFromConf("PATH") << getPathFromConf("SYSTEM_TRAY_PATH"));
if (!pluginsDirs.isEmpty())
pluginPaths << pluginsDirs;
#endif
plugins[PluginType::QuickPlugin] = pluginPaths;
}
// 添加系统插件目录
{
QStringList pluginPaths;
#ifdef QT_DEBUG
pluginPaths << qApp->applicationDirPath() + "/../plugins/system-trays";
#else
pluginPaths << "/usr/lib/dde-dock/plugins/system-trays";
const QStringList &pluginsDirs = getPathFromConf("SYSTEM_TRAY_PATH");
if (!pluginsDirs.isEmpty())
pluginPaths << pluginsDirs;
#endif
plugins[PluginType::SystemTrays] = pluginPaths;
}
return plugins;
}
// 该方法根据当前加载插件的类型来生成对应的单例的类
ProxyPluginController *ProxyPluginController::instance(PluginType instanceKey)
{
// 此处将这些单例对象存储到了qApp里面而没有存储到本地的静态变量是因为这个对象会在dock进程和tray插件中同时调用
// 如果存储到内存的临时变量中,他们就是不同的内存地址,获取到的变量就是多个,这样就会导致相同的插件加载多次,
// 而qApp是dock和插件共用的因此将对象存储到这里是保证能获取到相同的指针对象
QMap<PluginType, ProxyPluginController *> proxyInstances = qApp->property("proxyController").value<QMap<PluginType, ProxyPluginController *>>();
if (proxyInstances.contains(instanceKey))
return proxyInstances.value(instanceKey);
// 生成单例类,获取加载插件的路径信息
static QMap<PluginType, QStringList> pluginLoadInfos = getPluginPaths();
ProxyPluginController *controller = new ProxyPluginController();
controller->m_dirs = pluginLoadInfos.contains(instanceKey) ? pluginLoadInfos[instanceKey] : QStringList();
proxyInstances[instanceKey] = controller;
qApp->setProperty("proxyController", QVariant::fromValue(proxyInstances));
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)
{
if (!m_interfaces.contains(interface))
m_interfaces << interface;
}
void ProxyPluginController::removeProxyInterface(AbstractPluginsController *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);
}
bool ProxyPluginController::pluginIsLoaded(PluginsItemInterface *itemInter)
{
return m_pluginsItems.contains(itemInter);
}
QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const itemInter)
{
QMap<PluginsItemInterface *, QMap<QString, QObject *> > &plugin = pluginsMap();
if (plugin.contains(itemInter))
return qobject_cast<QPluginLoader *>(plugin[itemInter].value("pluginloader"));
return nullptr;
}
QString ProxyPluginController::itemKey(PluginsItemInterface *itemInter) const
{
if (m_pluginsItemKeys.contains(itemInter))
return m_pluginsItemKeys.value(itemInter);
return QString();
}
void ProxyPluginController::pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
if (!addPluginItems(itemInter, itemKey))
return;
// 获取需要加载当前插件的监听者,然后将当前插件添加到监听者
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->pluginItemAdded(itemInter, itemKey);
}
void ProxyPluginController::pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->pluginItemUpdate(itemInter, itemKey);
}
void ProxyPluginController::pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{
// 先获取可执行的controller再移除因为在判断当前插件是否加载的时候需要用到当前容器中的插件来获取当前代理
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->pluginItemRemoved(itemInter, itemKey);
removePluginItem(itemInter);
}
void ProxyPluginController::requestPluginWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestPluginWindowAutoHide(itemInter, itemKey, autoHide);
}
void ProxyPluginController::requestRefreshPluginWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestRefreshPluginWindowVisible(itemInter, itemKey);
}
void ProxyPluginController::requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
QList<AbstractPluginsController *> validController = getValidController(itemInter);
for (AbstractPluginsController *interface : validController)
interface->requestSetPluginAppletVisible(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 AbstractPluginsController::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;
}
bool ProxyPluginController::addPluginItems(PluginsItemInterface * const itemInter, const QString &itemKey)
{
// 如果该插件已经存在,则无需再次插入
if (m_pluginsItems.contains(itemInter))
return false;
m_pluginsItems << itemInter;
m_pluginsItemKeys[itemInter] = itemKey;
return true;
}
void ProxyPluginController::removePluginItem(PluginsItemInterface * const itemInter)
{
if (m_pluginsItems.contains(itemInter))
m_pluginsItems.removeOne(itemInter);
if (m_pluginsItemKeys.contains(itemInter))
m_pluginsItemKeys.remove(itemInter);
}
void ProxyPluginController::startLoader()
{
QDir dir;
for (const QString &path : m_dirs) {
if (!dir.exists(path))
continue;
AbstractPluginsController::startLoader(new PluginLoader(path, 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

@ -1,93 +0,0 @@
/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef PROXYPLUGINCONTROLLER_H
#define PROXYPLUGINCONTROLLER_H
#include "abstractpluginscontroller.h"
class PluginsItemInterface;
// 加载的插件的类型(1 根目录下的插件 2 快捷设置插件 3 系统插件)
enum class PluginType {
QuickPlugin = 0,
SystemTrays
};
// 该类是一个底层用来加载系统插件的类DockPluginsController和
// FixedPluginController类都是通过这个类来加载系统插件的
// 该类做成一个多例,因为理论上一个插件只允许被加载一次,但是对于电源插件来说,
// 电源插件在高效模式和特效模式下都需要显示,因此,此类用于加载插件,然后分发到不同的
// 上层控制器中
class ProxyPluginController : public AbstractPluginsController
{
Q_OBJECT
public:
static ProxyPluginController *instance(PluginType instanceKey = PluginType::QuickPlugin);
static ProxyPluginController *instance(PluginsItemInterface *itemInter);
void addProxyInterface(AbstractPluginsController *interface);
void removeProxyInterface(AbstractPluginsController *interface);
QPluginLoader *pluginLoader(PluginsItemInterface * const itemInter);
QString itemKey(PluginsItemInterface *itemInter) const;
protected:
explicit ProxyPluginController(QObject *parent = nullptr);
~ProxyPluginController() override {}
bool pluginIsLoaded(PluginsItemInterface *itemInter) override;
void pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestPluginWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override;
void requestRefreshPluginWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestSetPluginAppletVisible(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:
QList<AbstractPluginsController *> getValidController(PluginsItemInterface *itemInter) const;
bool addPluginItems(PluginsItemInterface * const itemInter, const QString &itemKey);
void removePluginItem(PluginsItemInterface * const itemInter);
void startLoader();
private:
QList<AbstractPluginsController *> m_interfaces;
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

View File

@ -20,42 +20,46 @@
*/
#include "quicksettingcontroller.h"
#include "quicksettingitem.h"
#include "proxyplugincontroller.h"
#include "pluginsitem.h"
#include "pluginmanagerinterface.h"
#include <QMetaObject>
QuickSettingController::QuickSettingController(QObject *parent)
: AbstractPluginsController(parent)
{
// 加载本地插件
ProxyPluginController *contoller = ProxyPluginController::instance(PluginType::QuickPlugin);
contoller->addProxyInterface(this);
connect(contoller, &ProxyPluginController::pluginLoaderFinished, this, &QuickSettingController::pluginLoaderFinished);
// 只有在非安全模式下才加载插件,安全模式会在等退出安全模式后通过接受事件的方式来加载插件
if (!qApp->property("safeMode").toBool())
QMetaObject::invokeMethod(this, [ = ] {
#ifdef QT_DEBUG
AbstractPluginsController::startLoader(new PluginLoader(QString("%1/..%2").arg(qApp->applicationDirPath()).arg("/plugins/loader"), this));
#else
AbstractPluginsController::startLoader(new PluginLoader("/usr/lib/dde-dock/plugins/loader", this));
#endif
}, Qt::QueuedConnection);
}
QuickSettingController::~QuickSettingController()
{
ProxyPluginController::instance(PluginType::QuickPlugin)->removeProxyInterface(this);
}
void QuickSettingController::pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
void QuickSettingController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
// 根据读取到的metaData数据获取当前插件的类型提供给外部
PluginAttribute pluginAttr = pluginAttribute(itemInter);
m_quickPlugins[pluginAttr] << itemInter;
m_quickPluginsMap[itemInter] = itemKey;
emit pluginInserted(itemInter, pluginAttr);
}
void QuickSettingController::pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &)
void QuickSettingController::itemUpdate(PluginsItemInterface * const itemInter, const QString &)
{
updateDockInfo(itemInter, DockPart::QuickPanel);
updateDockInfo(itemInter, DockPart::QuickShow);
updateDockInfo(itemInter, DockPart::SystemPanel);
}
void QuickSettingController::pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &)
void QuickSettingController::itemRemoved(PluginsItemInterface * const itemInter, const QString &)
{
for (auto it = m_quickPlugins.begin(); it != m_quickPlugins.end(); it++) {
QList<PluginsItemInterface *> &plugins = m_quickPlugins[it.key()];
@ -71,15 +75,13 @@ void QuickSettingController::pluginItemRemoved(PluginsItemInterface * const item
break;
}
m_quickPluginsMap.remove(itemInter);
Q_EMIT pluginRemoved(itemInter);
}
void QuickSettingController::requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool show)
void QuickSettingController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
// 设置插件列表可见事件
if (show)
Q_EMIT requestAppletShow(itemInter, itemKey);
Q_EMIT requestAppletVisible(itemInter, itemKey, visible);
}
void QuickSettingController::updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part)
@ -90,32 +92,36 @@ void QuickSettingController::updateDockInfo(PluginsItemInterface * const itemInt
QuickSettingController::PluginAttribute QuickSettingController::pluginAttribute(PluginsItemInterface * const itemInter) const
{
// 工具插件,例如回收站
if (hasFlag(itemInter, PluginFlag::Type_Tool))
if (itemInter->flags() & PluginFlag::Type_Tool)
return PluginAttribute::Tool;
// 系统插件,例如关机按钮
if (hasFlag(itemInter, PluginFlag::Type_System))
if (itemInter->flags() & PluginFlag::Type_System)
return PluginAttribute::System;
// 托盘插件,例如磁盘图标
if (hasFlag(itemInter, PluginFlag::Type_Tray))
if (itemInter->flags() & PluginFlag::Type_Tray)
return PluginAttribute::Tray;
// 固定插件,例如显示桌面和多任务试图
if (hasFlag(itemInter, PluginFlag::Type_Fixed))
if (itemInter->flags() & PluginFlag::Type_Fixed)
return PluginAttribute::Fixed;
// 通用插件,一般的插件都是通用插件,就是放在快捷插件区域的那些插件
if (hasFlag(itemInter, PluginFlag::Type_Common))
if (itemInter->flags() & PluginFlag::Type_Common)
return PluginAttribute::Quick;
// 基本插件,不在任务栏上显示的插件
return PluginAttribute::None;
}
bool QuickSettingController::hasFlag(PluginsItemInterface *itemInter, PluginFlag flag) const
QString QuickSettingController::itemKey(PluginsItemInterface *pluginItem) const
{
return itemInter->flags() & flag;
PluginManagerInterface *pManager = pluginManager();
if (pManager)
return pManager->itemKey(pluginItem);
return QString();
}
QuickSettingController *QuickSettingController::instance()
@ -129,18 +135,13 @@ QList<PluginsItemInterface *> QuickSettingController::pluginItems(const PluginAt
return m_quickPlugins.value(pluginClass);
}
QString QuickSettingController::itemKey(PluginsItemInterface *pluginItem) const
QJsonObject QuickSettingController::metaData(PluginsItemInterface *pluginItem)
{
return m_quickPluginsMap.value(pluginItem);
}
PluginManagerInterface *pManager = pluginManager();
if (pManager)
return pManager->metaData(pluginItem);
QJsonObject QuickSettingController::metaData(PluginsItemInterface *pluginItem) const
{
QPluginLoader *pluginLoader = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginLoader(pluginItem);
if (!pluginLoader)
return QJsonObject();
return pluginLoader->metaData().value("MetaData").toObject();
return QJsonObject();
}
PluginsItem *QuickSettingController::pluginItemWidget(PluginsItemInterface *pluginItem)
@ -155,16 +156,10 @@ PluginsItem *QuickSettingController::pluginItemWidget(PluginsItemInterface *plug
QList<PluginsItemInterface *> QuickSettingController::pluginInSettings()
{
QList<PluginsItemInterface *> settingPlugins;
// 用于在控制中心显示可改变位置的插件,这里只提供
QList<PluginsItemInterface *> allPlugins = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginCurrent();
for (PluginsItemInterface *plugin : allPlugins) {
if (plugin->pluginDisplayName().isEmpty())
continue;
PluginManagerInterface *pManager = pluginManager();
if (!pManager)
return QList<PluginsItemInterface *>();
if (hasFlag(plugin, PluginFlag::Attribute_CanSetting))
settingPlugins << plugin;
}
return settingPlugins;
// 返回可用于在控制中心显示的插件
return pManager->pluginsInSetting();
}

View File

@ -44,36 +44,32 @@ public:
public:
static QuickSettingController *instance();
QList<PluginsItemInterface *> pluginItems(const PluginAttribute &pluginClass) const;
QString itemKey(PluginsItemInterface *pluginItem) const;
QJsonObject metaData(PluginsItemInterface *pluginItem) const;
QJsonObject metaData(PluginsItemInterface *pluginItem);
PluginsItem *pluginItemWidget(PluginsItemInterface *pluginItem);
QList<PluginsItemInterface *> pluginInSettings();
PluginAttribute pluginAttribute(PluginsItemInterface * const itemInter) const;
bool hasFlag(PluginsItemInterface *itemInter, PluginFlag flag) const;
QString itemKey(PluginsItemInterface *pluginItem) const;
Q_SIGNALS:
void pluginInserted(PluginsItemInterface *itemInter, const PluginAttribute);
void pluginRemoved(PluginsItemInterface *itemInter);
void pluginUpdated(PluginsItemInterface *, const DockPart);
void requestAppletShow(PluginsItemInterface * itemInter, const QString &itemKey);
void requestAppletVisible(PluginsItemInterface * itemInter, const QString &itemKey, bool visible);
protected:
explicit QuickSettingController(QObject *parent = Q_NULLPTR);
~QuickSettingController() override;
protected:
void pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &) override;
void pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &) override;
void requestPluginWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) override {}
void requestRefreshPluginWindowVisible(PluginsItemInterface * const, const QString &) override {}
void requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool show) override;
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 requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override;
void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override;
private:
QMap<PluginAttribute, QList<PluginsItemInterface *>> m_quickPlugins;
QMap<PluginsItemInterface *, QString> m_quickPluginsMap;
QMap<PluginsItemInterface *, PluginsItem *> m_pluginItemWidgetMap;
};

View File

@ -1,172 +0,0 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "systemplugincontroller.h"
#include "pluginsiteminterface.h"
#include "utils.h"
#include "systempluginitem.h"
#include <QDebug>
#include <QDir>
SystemPluginController::SystemPluginController(QObject *parent)
: AbstractPluginsController(parent)
{
setObjectName("SystemTray");
}
void SystemPluginController::pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &mPluginsMap = pluginsMap();
// check if same item added
if (mPluginsMap.contains(itemInter))
if (mPluginsMap[itemInter].contains(itemKey))
return;
SystemPluginItem *item = new SystemPluginItem(itemInter, itemKey);
connect(item, &SystemPluginItem::itemVisibleChanged, this, [ = ] (bool visible){
emit visible ? pluginItemAdded(itemKey, item) : pluginItemRemoved(itemKey, item);
}, Qt::QueuedConnection);
mPluginsMap[itemInter][itemKey] = item;
// 隐藏的插件不加入到布局中
if (Utils::SettingValue(QString("com.deepin.dde.dock.module.") + itemInter->pluginName(), QByteArray(), "enable", true).toBool())
emit pluginItemAdded(itemKey, item);
}
void SystemPluginController::pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemPluginItem *item = static_cast<SystemPluginItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
item->update();
emit pluginItemUpdated(itemKey, item);
}
void SystemPluginController::pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemPluginItem *item = static_cast<SystemPluginItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
item->detachPluginWidget();
emit pluginItemRemoved(itemKey, item);
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &mPluginsMap = pluginsMap();
mPluginsMap[itemInter].remove(itemKey);
// do not delete the itemWidget object(specified in the plugin interface)
item->centralWidget()->setParent(nullptr);
// just delete our wrapper object(PluginsItem)
item->deleteLater();
}
void SystemPluginController::requestPluginWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
SystemPluginItem *item = static_cast<SystemPluginItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestWindowAutoHide(autoHide);
}
void SystemPluginController::requestRefreshPluginWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemPluginItem *item = static_cast<SystemPluginItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestRefershWindowVisible();
}
void SystemPluginController::requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
SystemPluginItem *item = static_cast<SystemPluginItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
if (visible) {
item->showPopupApplet(itemInter->itemPopupApplet(itemKey));
} else {
item->hidePopup();
}
}
int SystemPluginController::systemTrayItemSortKey(const QString &itemKey)
{
auto inter = pluginInterAt(itemKey);
if (!inter) {
return -1;
}
return inter->itemSortKey(itemKey);
}
void SystemPluginController::setSystemTrayItemSortKey(const QString &itemKey, const int order)
{
auto inter = pluginInterAt(itemKey);
if (!inter) {
return;
}
inter->setSortKey(itemKey, order);
}
const QVariant SystemPluginController::getValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &fallback)
{
auto inter = pluginInterAt(itemKey);
if (!inter) {
return QVariant();
}
return getPluginValue(inter, key, fallback);
}
void SystemPluginController::saveValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &value)
{
auto inter = pluginInterAt(itemKey);
if (!inter) {
return;
}
savePluginValue(inter, key, value);
}
void SystemPluginController::startLoader()
{
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));
}

View File

@ -1,66 +0,0 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
*
* Maintainer: sbw <sbw@sbw.so>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef SYSTEMTRAYSCONTROLLER_H
#define SYSTEMTRAYSCONTROLLER_H
#include "pluginproxyinterface.h"
#include "abstractpluginscontroller.h"
#include "abstractpluginscontroller.h"
#include <QPluginLoader>
#include <QList>
#include <QMap>
#include <QDBusConnectionInterface>
class PluginsItemInterface;
class SystemPluginItem;
class SystemPluginController : public AbstractPluginsController
{
Q_OBJECT
public:
explicit SystemPluginController(QObject *parent = nullptr);
// implements PluginProxyInterface
void pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void pluginItemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void pluginItemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestPluginWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override;
void requestRefreshPluginWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override;
void requestSetPluginAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) override;
int systemTrayItemSortKey(const QString &itemKey);
void setSystemTrayItemSortKey(const QString &itemKey, const int order);
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, SystemPluginItem *pluginItem);
void pluginItemRemoved(const QString &itemKey, SystemPluginItem *pluginItem);
void pluginItemUpdated(const QString &itemKey, SystemPluginItem *pluginItem);
};
#endif // SYSTEMTRAYSCONTROLLER_H

View File

@ -23,10 +23,10 @@
#include "utils.h"
#include "dockitemmanager.h"
#include "windowmanager.h"
#include "proxyplugincontroller.h"
#include "quicksettingcontroller.h"
#include "pluginsitem.h"
#include "settingconfig.h"
#include "customevent.h"
#include <DGuiApplicationHelper>
@ -170,16 +170,17 @@ QStringList DBusDockAdaptors::GetLoadedPlugins()
DockItemInfos DBusDockAdaptors::plugins()
{
#define DOCK_QUICK_PLUGINS "Dock_Quick_Plugins"
// 获取本地加载的插件
QList<PluginsItemInterface *> allPlugin = localPlugins();
DockItemInfos pluginInfos;
QStringList quickSettingKeys = SETTINGCONFIG->value("Dock_Quick_Plugin_Name").toStringList();
QStringList quickSettingKeys = SETTINGCONFIG->value(DOCK_QUICK_PLUGINS).toStringList();
for (PluginsItemInterface *plugin : allPlugin) {
DockItemInfo info;
info.name = plugin->pluginName();
info.displayName = plugin->pluginDisplayName();
info.itemKey = plugin->pluginName();
info.settingKey = "Dock_Quick_Plugin_Name";
info.settingKey = DOCK_QUICK_PLUGINS;
info.visible = quickSettingKeys.contains(info.itemKey);
QSize pixmapSize;
QIcon lightIcon = getSettingIcon(plugin, pixmapSize, DGuiApplicationHelper::ColorType::LightType);

View File

@ -111,18 +111,17 @@ QColor QuickSettingItem::foregroundColor() const
QuickSettingItem *QuickSettingFactory::createQuickWidget(PluginsItemInterface * const pluginInter)
{
QuickSettingController *quickController = QuickSettingController::instance();
// 如果显示在面板的图标或者Widget为空则不让显示(例如电池插件)
if (!quickController->hasFlag(pluginInter, PluginFlag::Type_Common))
if (!(pluginInter->flags() & PluginFlag::Type_Common))
return nullptr;
if (quickController->hasFlag(pluginInter, PluginFlag::Quick_Multi))
if (pluginInter->flags() & PluginFlag::Quick_Multi)
return new MultiQuickItem(pluginInter);
if (quickController->hasFlag(pluginInter, PluginFlag::Quick_Full))
if (pluginInter->flags() & PluginFlag::Quick_Full)
return new FullQuickItem(pluginInter);
if (quickController->hasFlag(pluginInter, PluginFlag::Quick_Single))
if (pluginInter->flags() & PluginFlag::Quick_Single)
return new SingleQuickItem(pluginInter);
return nullptr;

View File

@ -21,10 +21,9 @@
#include "abstractpluginscontroller.h"
#include "pluginsiteminterface.h"
#include "pluginsiteminterface_v20.h"
#include "pluginadapter.h"
#include "utils.h"
#include "settingconfig.h"
#include "pluginmanagerinterface.h"
#include <DNotifySender>
#include <DSysInfo>
@ -43,15 +42,9 @@ static const QStringList CompatiblePluginApiList {
AbstractPluginsController::AbstractPluginsController(QObject *parent)
: QObject(parent)
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
, m_dockDaemonInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this))
, m_pluginManager(nullptr)
{
qApp->installEventFilter(this);
refreshPluginSettings();
connect(SETTINGCONFIG, &SettingConfig::valueChanged, this, &AbstractPluginsController::onConfigChanged);
connect(m_dockDaemonInter, &DockInter::PluginSettingsSynced, this, &AbstractPluginsController::refreshPluginSettings, Qt::QueuedConnection);
}
AbstractPluginsController::~AbstractPluginsController()
@ -65,183 +58,6 @@ AbstractPluginsController::~AbstractPluginsController()
}
}
QList<PluginsItemInterface *> AbstractPluginsController::pluginCurrent() const
{
return m_pluginExists;
}
void AbstractPluginsController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value)
{
savePluginValue(getPluginInterface(itemInter), key, value);
}
const QVariant AbstractPluginsController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &fallback)
{
return getPluginValue(getPluginInterface(itemInter), key, fallback);
}
void AbstractPluginsController::removeValue(PluginsItemInterface *const itemInter, const QStringList &keyList)
{
removePluginValue(getPluginInterface(itemInter), keyList);
}
void AbstractPluginsController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
PluginsItemInterface *pluginItem = getPluginInterface(itemInter);
if (m_pluginExists.contains(pluginItem))
return;
PluginAdapter *pluginAdapter = dynamic_cast<PluginAdapter *>(pluginItem);
if (pluginAdapter)
pluginAdapter->setItemKey(itemKey);
m_pluginExists << pluginItem;
m_pluginItemKeyMap[pluginItem] = itemKey;
if (canAddedPlugin(pluginItem))
pluginItemAdded(pluginItem, itemKey);
}
void AbstractPluginsController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{
pluginItemUpdate(getPluginInterface(itemInter), itemKey);
}
void AbstractPluginsController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{
m_pluginExists.removeOne(itemInter);
m_pluginItemKeyMap.remove(itemInter);
pluginItemRemoved(getPluginInterface(itemInter), itemKey);
}
void AbstractPluginsController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
requestPluginWindowAutoHide(getPluginInterface(itemInter), itemKey, autoHide);
}
void AbstractPluginsController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
requestRefreshPluginWindowVisible(getPluginInterface(itemInter), itemKey);
}
void AbstractPluginsController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
requestSetPluginAppletVisible(getPluginInterface(itemInter), itemKey, visible);
}
PluginsItemInterface *AbstractPluginsController::getPluginInterface(PluginsItemInterface * const itemInter)
{
// 先从事先定义好的map中查找如果没有找到就是v23插件直接返回当前插件的指针
qulonglong pluginAddr = (qulonglong)itemInter;
if (m_pluginAdapterMap.contains(pluginAddr))
return m_pluginAdapterMap[pluginAddr];
return itemInter;
}
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &AbstractPluginsController::pluginsMap()
{
return m_pluginsMap;
}
void AbstractPluginsController::savePluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &value)
{
// is it necessary?
// refreshPluginSettings();
// save to local cache
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
localObject.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
// save to daemon
QJsonObject remoteObject, remoteObjectInter;
remoteObjectInter.insert(key, QJsonValue::fromVariant(value)); //Note: QVariant::toJsonValue() not work in Qt 5.7
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
if (itemInter->type() == PluginsItemInterface::Fixed && key == "enable" && !value.toBool()) {
int fixedPluginCount = 0;
// 遍历FixPlugin插件个数
for (auto it(m_pluginsMap.begin()); it != m_pluginsMap.end();) {
if (it.key()->type() == PluginsItemInterface::Fixed) {
fixedPluginCount++;
}
++it;
}
// 修改插件的order值位置为队尾
QString name = localObject.keys().last();
// 此次做一下判断有可能初始数据不存在pos_*字段会导致enable字段被修改。或者此处可以循环所有字段是否存在pos_开头的字段
if (name != key) {
localObject.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
// daemon中同样修改
remoteObjectInter.insert(name, QJsonValue::fromVariant(fixedPluginCount)); //Note: QVariant::toJsonValue() not work in Qt 5.7
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
}
}
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
m_dockDaemonInter->MergePluginSettings(QJsonDocument(remoteObject).toJson(QJsonDocument::JsonFormat::Compact));
}
const QVariant AbstractPluginsController::getPluginValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &fallback)
{
// load from local cache
QVariant v = m_pluginSettingsObject.value(itemInter->pluginName()).toObject().value(key).toVariant();
if (v.isNull() || !v.isValid()) {
v = fallback;
}
return v;
}
void AbstractPluginsController::removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList)
{
if (keyList.isEmpty()) {
m_pluginSettingsObject.remove(itemInter->pluginName());
} else {
QJsonObject localObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
for (auto key : keyList) {
localObject.remove(key);
}
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
}
m_dockDaemonInter->RemovePluginSettings(itemInter->pluginName(), keyList);
}
QObject *AbstractPluginsController::pluginItemAt(PluginsItemInterface *const itemInter, const QString &itemKey) const
{
if (!m_pluginsMap.contains(itemInter))
return nullptr;
return m_pluginsMap[itemInter][itemKey];
}
PluginsItemInterface *AbstractPluginsController::pluginInterAt(const QString &itemKey)
{
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
while (it.hasNext()) {
it.next();
if (it.value().keys().contains(itemKey)) {
return it.key();
}
}
return nullptr;
}
PluginsItemInterface *AbstractPluginsController::pluginInterAt(QObject *destItem)
{
QMapIterator<PluginsItemInterface *, QMap<QString, QObject *>> it(m_pluginsMap);
while (it.hasNext()) {
it.next();
if (it.value().values().contains(destItem)) {
return it.key();
}
}
return nullptr;
}
void AbstractPluginsController::startLoader(PluginLoader *loader)
{
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
@ -291,19 +107,6 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
}
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
if (!interface) {
// 如果识别当前插件失败就认为这个插件是v20的插件将其转换为v20插件接口
PluginsItemInterface_V20 *interface_v20 = qobject_cast<PluginsItemInterface_V20 *>(pluginLoader->instance());
if (interface_v20) {
// 将v20插件接口通过适配器转换成v23的接口方便在后面识别
PluginAdapter *pluginAdapter = new PluginAdapter(interface_v20, pluginLoader);
// 将适配器的地址保存到map列表中因为适配器自己会调用itemAdded方法转换成PluginsItemInterface类但是实际上它
// 对应的是PluginAdapter类因此这个map用于在后面的itemAdded方法中用来查找
m_pluginAdapterMap[(qulonglong)(interface_v20)] = pluginAdapter;
interface = pluginAdapter;
}
}
if (!interface) {
qDebug() << objectName() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
@ -324,28 +127,6 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
return;
}
if (!needLoad(interface)) {
// 对于一些固定的插件是不需要加载的,例如在特效模式下,只需要加载电源插件,其他的是无需加载的
for (const QPair<QString, PluginsItemInterface *> &pair : m_pluginLoadMap.keys()) {
if (pair.first == pluginFile)
m_pluginLoadMap.remove(pair);
}
pluginLoader->unload();
pluginLoader->deleteLater();
return;
}
if (interface->pluginName() == "multitasking") {
if (Utils::IS_WAYLAND_DISPLAY || Dtk::Core::DSysInfo::deepinType() == Dtk::Core::DSysInfo::DeepinServer) {
for (auto &pair : m_pluginLoadMap.keys()) {
if (pair.first == pluginFile) {
m_pluginLoadMap.remove(pair);
}
}
return;
}
}
QMapIterator<QPair<QString, PluginsItemInterface *>, bool> it(m_pluginLoadMap);
while (it.hasNext()) {
it.next();
@ -363,20 +144,11 @@ void AbstractPluginsController::loadPlugin(const QString &pluginFile)
QMap<QString, QObject *> interfaceData;
interfaceData["pluginloader"] = pluginLoader;
m_pluginsMap.insert(interface, interfaceData);
QString dbusService = meta.value("depends-daemon-dbus-service").toString();
if (!dbusService.isEmpty() && !m_dbusDaemonInterface->isServiceRegistered(dbusService).value()) {
qDebug() << objectName() << dbusService << "daemon has not started, waiting for signal";
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[ = ](const QString & name, const QString & oldOwner, const QString & newOwner) {
Q_UNUSED(oldOwner);
if (name == dbusService && !newOwner.isEmpty()) {
qDebug() << objectName() << dbusService << "daemon started, init plugin and disconnect";
initPlugin(interface);
disconnect(m_dbusDaemonInterface);
}
}
);
return;
PluginManagerInterface * pluginManager = dynamic_cast<PluginManagerInterface *>(interface);
if (pluginManager) {
m_pluginManager = pluginManager;
connect(m_pluginManager, &PluginManagerInterface::pluginLoadFinished, this, &AbstractPluginsController::pluginLoaderFinished);
}
// NOTE(justforlxz): 插件的所有初始化工作都在init函数中进行
@ -408,77 +180,15 @@ void AbstractPluginsController::initPlugin(PluginsItemInterface *interface)
}
}
//插件全部加载完成
if (loaded) {
emit pluginLoaderFinished();
}
qDebug() << objectName() << "init plugin finished: " << interface->pluginName();
}
void AbstractPluginsController::refreshPluginSettings()
bool AbstractPluginsController::eventFilter(QObject *object, QEvent *event)
{
const QString &pluginSettings = m_dockDaemonInter->GetPluginSettings().value();
if (pluginSettings.isEmpty()) {
qDebug() << "Error! get plugin settings from dbus failed!";
return;
}
const QJsonObject &pluginSettingsObject = QJsonDocument::fromJson(pluginSettings.toLocal8Bit()).object();
if (pluginSettingsObject.isEmpty()) {
return;
}
// nothing changed
if (pluginSettingsObject == m_pluginSettingsObject) {
return;
}
for (auto pluginsIt = pluginSettingsObject.constBegin(); pluginsIt != pluginSettingsObject.constEnd(); ++pluginsIt) {
const QString &pluginName = pluginsIt.key();
const QJsonObject &settingsObject = pluginsIt.value().toObject();
QJsonObject newSettingsObject = m_pluginSettingsObject.value(pluginName).toObject();
for (auto settingsIt = settingsObject.constBegin(); settingsIt != settingsObject.constEnd(); ++settingsIt) {
newSettingsObject.insert(settingsIt.key(), settingsIt.value());
}
// TODO: remove not exists key-values
m_pluginSettingsObject.insert(pluginName, newSettingsObject);
}
// not notify plugins to refresh settings if this update is not emit by dock daemon
if (sender() != m_dockDaemonInter) {
return;
}
// notify all plugins to reload plugin settings
for (PluginsItemInterface *pluginInter : m_pluginsMap.keys()) {
pluginInter->pluginSettingsChanged();
}
// reload all plugin items for sort order or container
QMap<PluginsItemInterface *, QMap<QString, QObject *>> pluginsMapTemp = m_pluginsMap;
for (auto it = pluginsMapTemp.constBegin(); it != pluginsMapTemp.constEnd(); ++it) {
const QList<QString> &itemKeyList = it.value().keys();
for (auto key : itemKeyList) {
if (key != "pluginloader") {
itemRemoved(it.key(), key);
}
}
for (auto key : itemKeyList) {
if (key != "pluginloader") {
itemAdded(it.key(), key);
}
}
}
}
bool AbstractPluginsController::eventFilter(QObject *o, QEvent *e)
{
if (o != qApp)
return false;
if (e->type() != QEvent::DynamicPropertyChange)
if (object != qApp || event->type() != QEvent::DynamicPropertyChange)
return false;
QDynamicPropertyChangeEvent *const dpce = static_cast<QDynamicPropertyChangeEvent *>(e);
QDynamicPropertyChangeEvent *const dpce = static_cast<QDynamicPropertyChangeEvent *>(event);
const QString propertyName = dpce->propertyName();
if (propertyName == PROP_POSITION)
@ -489,55 +199,7 @@ bool AbstractPluginsController::eventFilter(QObject *o, QEvent *e)
return false;
}
bool AbstractPluginsController::canAddRemove(PluginsItemInterface *plugin) const
PluginManagerInterface *AbstractPluginsController::pluginManager() const
{
if (!plugin->flags() & PluginFlag::Attribute_CanSetting)
return false;
if (plugin->flags() & PluginFlag::Type_Tool)
return true;
if (plugin->flags() & PluginFlag::Type_System)
return true;
return false;
}
bool AbstractPluginsController::canAddedPlugin(PluginsItemInterface *plugin) const
{
if (!canAddRemove(plugin))
return true;
const QStringList configPlugins = SETTINGCONFIG->value("Dock_Quick_Plugin_Name").toStringList();
return configPlugins.contains(plugin->pluginName());
}
void AbstractPluginsController::onConfigChanged(const QString &key, const QVariant &value)
{
QStringList pluginNames = value.toStringList();
if (key == "Dock_Quick_Plugin_Name") {
// 这里只处理工具插件(回收站)和系统插件(电源插件)
for (PluginsItemInterface *plugin : pluginCurrent()) {
if (!canAddRemove(plugin))
continue;
const QString itemKey = m_pluginItemKeyMap.value(plugin);
if (!pluginNames.contains(plugin->pluginName()) && pluginIsLoaded(plugin)) {
// 如果当前配置中不包含当前插件,但是当前插件已经加载,那么就移除该插件
pluginItemRemoved(plugin, itemKey);
QWidget *itemWidget = plugin->itemWidget(itemKey);
if (itemWidget)
itemWidget->setVisible(false);
} else if (pluginNames.contains(plugin->pluginName()) && !pluginIsLoaded(plugin)) {
// 如果当前配置中包含当前插件,但是当前插件并未加载,那么就加载该插件
pluginItemAdded(plugin, itemKey);
// 只有工具插件是通过QWidget的方式进行显示的因此这里只处理工具插件
if (plugin->flags() & PluginFlag::Type_Tool) {
QWidget *itemWidget = plugin->itemWidget(itemKey);
if (itemWidget)
itemWidget->setVisible(true);
}
}
}
}
return m_pluginManager;
}

View File

@ -33,6 +33,7 @@
class PluginsItemInterface;
class PluginAdapter;
class PluginManagerInterface;
class AbstractPluginsController : public QObject, PluginProxyInterface
{
@ -43,49 +44,22 @@ public:
~ AbstractPluginsController() override;
void updateDockInfo(PluginsItemInterface *const, const DockPart &) override {}
virtual QList<PluginsItemInterface *> pluginCurrent() const;
virtual bool needLoad(PluginsItemInterface *) { return true; }
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap();
virtual void savePluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value);
virtual const QVariant getPluginValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant());
virtual void removePluginValue(PluginsItemInterface * const itemInter, const QStringList &keyList);
virtual void pluginItemAdded(PluginsItemInterface * const, const QString &) = 0;
virtual void pluginItemUpdate(PluginsItemInterface * const, const QString &) = 0;
virtual void pluginItemRemoved(PluginsItemInterface * const, const QString &) = 0;
virtual void requestPluginWindowAutoHide(PluginsItemInterface * const, const QString &, const bool) {}
virtual void requestRefreshPluginWindowVisible(PluginsItemInterface * const, const QString &) {}
virtual void requestSetPluginAppletVisible(PluginsItemInterface * const, const QString &, const bool) {}
Q_SIGNALS:
void pluginLoaderFinished();
protected:
virtual bool pluginIsLoaded(PluginsItemInterface *itemInter) { return true; }
bool eventFilter(QObject *object, QEvent *event) override;
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
PluginsItemInterface *pluginInterAt(const QString &itemKey);
PluginsItemInterface *pluginInterAt(QObject *destItem);
bool eventFilter(QObject *o, QEvent *e) override;
bool canAddRemove(PluginsItemInterface *plugin) const;
bool canAddedPlugin(PluginsItemInterface *plugin) const;
PluginManagerInterface *pluginManager() const;
private:
// implements PluginProxyInterface
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) override;
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 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 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;
PluginsItemInterface *getPluginInterface(PluginsItemInterface * const itemInter);
void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) override {}
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) override {}
void saveValue(PluginsItemInterface * const itemInter, const QString &key, const QVariant &value) override {}
void removeValue(PluginsItemInterface *const itemInter, const QStringList &keyList) override {}
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) override { return QVariant(); }
protected Q_SLOTS:
void startLoader(PluginLoader *loader);
@ -95,23 +69,15 @@ private slots:
void positionChanged();
void loadPlugin(const QString &pluginFile);
void initPlugin(PluginsItemInterface *interface);
void refreshPluginSettings();
void onConfigChanged(const QString &key, const QVariant &value);
private:
QDBusConnectionInterface *m_dbusDaemonInterface;
DockInter *m_dockDaemonInter;
// interface, "pluginloader", PluginLoader指针对象
QMap<PluginsItemInterface *, QMap<QString, QObject *>> m_pluginsMap;
// filepath, interface, loaded
QMap<QPair<QString, PluginsItemInterface *>, bool> m_pluginLoadMap;
QList<PluginsItemInterface *> m_pluginExists;
QMap<PluginsItemInterface *, QString> m_pluginItemKeyMap;
QJsonObject m_pluginSettingsObject;
QMap<qulonglong, PluginAdapter *> m_pluginAdapterMap;
PluginManagerInterface *m_pluginManager;
};
#endif // ABSTRACTPLUGINSCONTROLLER_H

View File

@ -0,0 +1,19 @@
#include "customevent.h"
// 注册事件类型
static QEvent::Type pluginEventType = (QEvent::Type)QEvent::registerEventType(QEvent::User + 1001);
// 事件处理,当收到该事件的时候,加载插件
PluginLoadEvent::PluginLoadEvent()
: QEvent(pluginEventType)
{
}
PluginLoadEvent::~PluginLoadEvent()
{
}
QEvent::Type PluginLoadEvent::eventType()
{
return pluginEventType;
}

16
frame/util/customevent.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef CUSTOMEVENT_H
#define CUSTOMEVENT_H
#include <QEvent>
// 该插件用于处理插件的延迟加载,当退出安全模式后,会收到该事件并加载插件
class PluginLoadEvent : public QEvent
{
public:
PluginLoadEvent();
~PluginLoadEvent() override;
static Type eventType();
};
#endif // CUSTOMEVENT_H

View File

@ -24,7 +24,6 @@
#include "mainpanelcontrol.h"
#include "dockitemmanager.h"
#include "menuworker.h"
#include "proxyplugincontroller.h"
#include "windowmanager.h"
#include "dockscreen.h"
#include "dragwidget.h"

View File

@ -25,7 +25,7 @@
#include <QWidget>
#define PLUGINNAMEKEY "Dock_Quick_Plugin_Name"
#define PLUGINNAMEKEY "Dock_Quick_Plugins"
QuickPluginModel *QuickPluginModel::instance()
{
@ -81,9 +81,9 @@ QList<PluginsItemInterface *> QuickPluginModel::dockedPluginItems() const
QList<PluginsItemInterface *> activedItems;
for (PluginsItemInterface *itemInter : m_dockedPluginsItems) {
if (isFixed(itemInter))
activedItems << itemInter;
else
dockedItems << itemInter;
else
activedItems << itemInter;
}
std::sort(dockedItems.begin(), dockedItems.end(), [ this ](PluginsItemInterface *item1, PluginsItemInterface *item2) {
return m_dockedPluginIndex.value(item1->pluginName()) < m_dockedPluginIndex.value(item2->pluginName());
@ -144,12 +144,8 @@ void QuickPluginModel::onSettingChanged(const QString &key, const QVariant &valu
}
// 2、将配置中已有的但是插件列表中没有的插件移动到任务栏上
QList<PluginsItemInterface *> plugins = QuickSettingController::instance()->pluginItems(QuickSettingController::PluginAttribute::Quick);
for (PluginsItemInterface *plugin : plugins) {
if (m_dockedPluginsItems.contains(plugin) || !localOrder.contains(plugin->pluginName()))
continue;
for (PluginsItemInterface *plugin : plugins)
m_dockedPluginsItems << plugin;
}
m_dockedPluginIndex.clear();
for (int i = 0; i < localOrder.size(); i++)
@ -161,7 +157,7 @@ void QuickPluginModel::onSettingChanged(const QString &key, const QVariant &valu
void QuickPluginModel::initConnection()
{
QuickSettingController *quickController = QuickSettingController::instance();
connect(quickController, &QuickSettingController::pluginInserted, this, [ this ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute plugAttr) {
connect(quickController, &QuickSettingController::pluginInserted, this, [ this, quickController ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute plugAttr) {
if (plugAttr != QuickSettingController::PluginAttribute::Quick)
return;
@ -169,9 +165,11 @@ void QuickPluginModel::initConnection()
if (quickWidget && !quickWidget->parentWidget())
quickWidget->setVisible(false);
// 用来读取已经固定在下方的插件或者强制显示的插件
if (!m_dockedPluginIndex.contains(itemInter->pluginName()) && !(itemInter->flags() & Attribute_ForceDock))
return;
if (!m_dockedPluginIndex.contains(itemInter->pluginName())) {
QJsonObject json = quickController->metaData(itemInter);
if (json.contains("order"))
m_dockedPluginIndex[itemInter->pluginName()] = json.value("order").toInt();
}
m_dockedPluginsItems << itemInter;

View File

@ -24,7 +24,6 @@
#include "pluginsiteminterface.h"
#include "quicksettingcontainer.h"
#include "appdrag.h"
#include "proxyplugincontroller.h"
#include "quickpluginmodel.h"
#include "quickdragcore.h"
@ -89,8 +88,6 @@ typedef struct DragInfo{
}
} DragInfo;
static QStringList fixedPluginNames{ "network", "sound", "power" };
QuickPluginWindow::QuickPluginWindow(QWidget *parent)
: QWidget(parent)
, m_mainLayout(new QBoxLayout(QBoxLayout::RightToLeft, this))
@ -420,9 +417,10 @@ void QuickPluginWindow::onUpdatePlugin(PluginsItemInterface *itemInter, const Do
}
}
void QuickPluginWindow::onRequestAppletShow(PluginsItemInterface *itemInter, const QString &itemKey)
void QuickPluginWindow::onRequestAppletVisible(PluginsItemInterface *itemInter, const QString &itemKey, bool visible)
{
showPopup(getDockItemByPlugin(itemInter), itemInter, itemInter->itemPopupApplet(itemKey), false);
if (visible)
showPopup(getDockItemByPlugin(itemInter), itemInter, itemInter->itemPopupApplet(itemKey), false);
}
void QuickPluginWindow::startDrag()
@ -589,7 +587,7 @@ void QuickPluginWindow::initConnection()
QuickPluginModel *model = QuickPluginModel::instance();
connect(model, &QuickPluginModel::requestUpdate, this, &QuickPluginWindow::onRequestUpdate);
connect(model, &QuickPluginModel::requestUpdatePlugin, this, &QuickPluginWindow::onUpdatePlugin);
connect(QuickSettingController::instance(), &QuickSettingController::requestAppletShow, this, &QuickPluginWindow::onRequestAppletShow);
connect(QuickSettingController::instance(), &QuickSettingController::requestAppletVisible, this, &QuickPluginWindow::onRequestAppletVisible);
}
/**
@ -800,10 +798,15 @@ bool QuickDockItem::eventFilter(QObject *watched, QEvent *event)
QPixmap QuickDockItem::iconPixmap() const
{
int pixmapSize = static_cast<int>(ICONHEIGHT * (QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1 : qApp->devicePixelRatio()));
QIcon icon = m_pluginItem->icon(DockPart::QuickShow);
if (!icon.isNull())
if (!icon.isNull()) {
if (icon.availableSizes().size() > 0) {
QSize size = icon.availableSizes().first();
return icon.pixmap(size);
}
int pixmapSize = static_cast<int>(ICONHEIGHT * (QCoreApplication::testAttribute(Qt::AA_UseHighDpiPixmaps) ? 1 : qApp->devicePixelRatio()));
return icon.pixmap(pixmapSize, pixmapSize);
}
return QPixmap();
}

View File

@ -69,7 +69,7 @@ protected:
private Q_SLOTS:
void onRequestUpdate();
void onUpdatePlugin(PluginsItemInterface *itemInter, const DockPart &dockPart);
void onRequestAppletShow(PluginsItemInterface * itemInter, const QString &itemKey);
void onRequestAppletVisible(PluginsItemInterface * itemInter, const QString &itemKey, bool visible);
private:
void initUi();

View File

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "systempluginwindow.h"
#include "systemplugincontroller.h"
#include "systempluginitem.h"
#include "quicksettingcontroller.h"
#include "utils.h"

View File

@ -26,7 +26,6 @@
#include "dockitemmanager.h"
#include "dockscreen.h"
#include "displaymanager.h"
#include "proxyplugincontroller.h"
#include <DWindowManagerHelper>
#include <DDBusSender>