Merge branch 'dev/daemon-plugin-settings' into daemon-plugin-settings

This commit is contained in:
listenerri 2019-04-04 17:31:31 +08:00
commit f4cbe1d2c8
35 changed files with 632 additions and 520 deletions

View File

@ -47,7 +47,7 @@ const QList<QPointer<DockItem>> DockItemController::itemList() const
const QList<PluginsItemInterface *> DockItemController::pluginList() const
{
return m_pluginsInter->m_pluginList.keys();
return m_pluginsInter->pluginsMap().keys();
}
bool DockItemController::appIsOnDock(const QString &appDesktop) const

View File

@ -21,28 +21,24 @@
#include "dockpluginscontroller.h"
#include "pluginsiteminterface.h"
#include "dockitemcontroller.h"
#include "dockpluginloader.h"
#include "item/traypluginitem.h"
#include <QDebug>
#include <QDir>
DockPluginsController::DockPluginsController(
DockItemController *itemControllerInter)
: QObject(itemControllerInter)
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
, m_itemControllerInter(itemControllerInter)
, m_pluginsSetting("deepin", "dde-dock")
DockPluginsController::DockPluginsController(QObject *parent)
: AbstractPluginsController(parent)
{
qApp->installEventFilter(this);
setObjectName("DockPlugin");
}
void DockPluginsController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &mPluginsMap = pluginsMap();
// check if same item added
if (m_pluginList.contains(itemInter))
if (m_pluginList[itemInter].contains(itemKey))
if (mPluginsMap.contains(itemInter))
if (mPluginsMap[itemInter].contains(itemKey))
return;
PluginsItem *item = nullptr;
@ -59,16 +55,16 @@ void DockPluginsController::itemAdded(PluginsItemInterface * const itemInter, co
item->setVisible(false);
m_pluginList[itemInter][itemKey] = item;
mPluginsMap[itemInter][itemKey] = item;
emit pluginItemInserted(item);
}
void DockPluginsController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{
PluginsItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
PluginsItem *item = static_cast<PluginsItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
item->update();
@ -77,8 +73,7 @@ void DockPluginsController::itemUpdate(PluginsItemInterface * const itemInter, c
void DockPluginsController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{
PluginsItem *item = pluginItemAt(itemInter, itemKey);
PluginsItem *item = static_cast<PluginsItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
@ -86,7 +81,8 @@ void DockPluginsController::itemRemoved(PluginsItemInterface * const itemInter,
emit pluginItemRemoved(item);
m_pluginList[itemInter].remove(itemKey);
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);
@ -97,24 +93,27 @@ void DockPluginsController::itemRemoved(PluginsItemInterface * const itemInter,
void DockPluginsController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
PluginsItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
PluginsItem *item = static_cast<PluginsItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestWindowAutoHide(autoHide);
}
void DockPluginsController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
PluginsItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
PluginsItem *item = static_cast<PluginsItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestRefreshWindowVisible();
}
void DockPluginsController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
PluginsItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
PluginsItem *item = static_cast<PluginsItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
if (visible) {
item->showPopupApplet(itemInter->itemPopupApplet(itemKey));
@ -125,116 +124,11 @@ void DockPluginsController::requestSetAppletVisible(PluginsItemInterface * const
void DockPluginsController::startLoader()
{
DockPluginLoader *loader = new DockPluginLoader(this);
connect(loader, &DockPluginLoader::finished, loader, &DockPluginLoader::deleteLater, Qt::QueuedConnection);
connect(loader, &DockPluginLoader::pluginFounded, this, &DockPluginsController::loadPlugin, Qt::QueuedConnection);
QTimer::singleShot(1, loader, [=] { loader->start(QThread::LowestPriority); });
}
void DockPluginsController::displayModeChanged()
{
const DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
const auto inters = m_pluginList.keys();
for (auto inter : inters)
inter->displayModeChanged(displayMode);
}
void DockPluginsController::positionChanged()
{
const Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
const auto inters = m_pluginList.keys();
for (auto inter : inters)
inter->positionChanged(position);
}
void DockPluginsController::loadPlugin(const QString &pluginFile)
{
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile);
const auto meta = pluginLoader->metaData().value("MetaData").toObject();
if (!meta.contains("api") || meta["api"].toString() != DOCK_PLUGIN_API_VERSION)
{
QString notifyMessage(tr("The plugin %1 is not compatible with the system."));
QProcess::startDetached("notify-send", QStringList()
<< "-i" << "dialog-warning"
<< notifyMessage.arg(QFileInfo(pluginFile).fileName()));
qWarning() << "plugin api version not matched! expect version:" << DOCK_PLUGIN_API_VERSION << pluginFile;
return;
QString pluginsDir("../plugins");
if (!QDir(pluginsDir).exists()) {
pluginsDir = "/usr/lib/dde-dock/plugins";
}
qDebug() << "using dock plugins dir:" << pluginsDir;
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
if (!interface)
{
qWarning() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
pluginLoader->unload();
pluginLoader->deleteLater();
return;
}
m_pluginList.insert(interface, QMap<QString, PluginsItem *>());
QString dbusService = meta.value("depends-daemon-dbus-service").toString();
if (!dbusService.isEmpty() && !m_dbusDaemonInterface->isServiceRegistered(dbusService).value()) {
qDebug() << dbusService << "daemon has not started, waiting for signal";
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[=](const QString &name, const QString &oldOwner, const QString &newOwner) {
if (name == dbusService && !newOwner.isEmpty()) {
qDebug() << dbusService << "daemon started, init plugin and disconnect";
initPlugin(interface);
disconnect(m_dbusDaemonInterface);
}
}
);
return;
}
initPlugin(interface);
}
void DockPluginsController::initPlugin(PluginsItemInterface *interface) {
qDebug() << "init plugin: " << interface->pluginName();
interface->init(this);
qDebug() << "init plugin finished: " << interface->pluginName();
}
bool DockPluginsController::eventFilter(QObject *o, QEvent *e)
{
if (o != qApp)
return false;
if (e->type() != QEvent::DynamicPropertyChange)
return false;
QDynamicPropertyChangeEvent * const dpce = static_cast<QDynamicPropertyChangeEvent *>(e);
const QString propertyName = dpce->propertyName();
if (propertyName == PROP_POSITION)
positionChanged();
else if (propertyName == PROP_DISPLAY_MODE)
displayModeChanged();
return false;
}
PluginsItem *DockPluginsController::pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const
{
if (!m_pluginList.contains(itemInter))
return nullptr;
return m_pluginList[itemInter][itemKey];
}
void DockPluginsController::saveValue(PluginsItemInterface *const itemInter, const QString &itemKey, const QVariant &value) {
m_pluginsSetting.beginGroup(itemInter->pluginName());
m_pluginsSetting.setValue(itemKey, value);
m_pluginsSetting.endGroup();
}
const QVariant DockPluginsController::getValue(PluginsItemInterface *const itemInter, const QString &itemKey, const QVariant& failback) {
m_pluginsSetting.beginGroup(itemInter->pluginName());
QVariant value(m_pluginsSetting.value(itemKey, failback));
m_pluginsSetting.endGroup();
return value;
AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this));
}

View File

@ -24,22 +24,24 @@
#include "item/pluginsitem.h"
#include "pluginproxyinterface.h"
#include "util/abstractpluginscontroller.h"
#include <com_deepin_dde_daemon_dock.h>
#include <QPluginLoader>
#include <QList>
#include <QMap>
#include <QDBusConnectionInterface>
class DockItemController;
class PluginsItemInterface;
class DockPluginsController : public QObject, PluginProxyInterface
class DockPluginsController : public AbstractPluginsController
{
Q_OBJECT
friend class DockItemController;
public:
explicit DockPluginsController(DockItemController *itemControllerInter = 0);
explicit DockPluginsController(QObject *parent = 0);
// implements PluginProxyInterface
void itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) Q_DECL_OVERRIDE;
@ -48,31 +50,14 @@ public:
void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) Q_DECL_OVERRIDE;
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) Q_DECL_OVERRIDE;
void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) Q_DECL_OVERRIDE;
void saveValue(PluginsItemInterface *const itemInter, const QString &itemKey, const QVariant &value) Q_DECL_OVERRIDE;
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &itemKey, const QVariant& failback = QVariant()) Q_DECL_OVERRIDE;
void startLoader();
signals:
void pluginItemInserted(PluginsItem *pluginItem) const;
void pluginItemRemoved(PluginsItem *pluginItem) const;
void pluginItemUpdated(PluginsItem *pluginItem) const;
void fashionTraySizeChanged(const QSize &traySize) const;
private slots:
void startLoader();
void displayModeChanged();
void positionChanged();
void loadPlugin(const QString &pluginFile);
void initPlugin(PluginsItemInterface *interface);
private:
bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
PluginsItem *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
private:
QDBusConnectionInterface *m_dbusDaemonInterface;
QMap<PluginsItemInterface *, QMap<QString, PluginsItem *>> m_pluginList;
DockItemController *m_itemControllerInter;
QSettings m_pluginsSetting;
};
#endif // DOCKPLUGINSCONTROLLER_H

View File

@ -0,0 +1,273 @@
/*
* 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 "abstractpluginscontroller.h"
#include "pluginsiteminterface.h"
#include <QDebug>
#include <QDir>
#include <QGSettings>
static const QStringList CompatiblePluginApiList {
"1.1.1",
"1.2",
DOCK_PLUGIN_API_VERSION
};
AbstractPluginsController::AbstractPluginsController(QObject *parent)
: QObject(parent)
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
, m_dockDaemonInter(new DockDaemonInter("com.deepin.dde.daemon.Dock", "/com/deepin/dde/daemon/Dock", QDBusConnection::sessionBus(), this))
{
qApp->installEventFilter(this);
refreshPluginSettings();
connect(m_dockDaemonInter, &DockDaemonInter::PluginSettingsSynced, this, &AbstractPluginsController::refreshPluginSettings, Qt::QueuedConnection);
}
void AbstractPluginsController::saveValue(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, value.toJsonValue());
m_pluginSettingsObject.insert(itemInter->pluginName(), localObject);
// save to daemon
QJsonObject remoteObject, remoteObjectInter;
remoteObjectInter.insert(key, value.toJsonValue());
remoteObject.insert(itemInter->pluginName(), remoteObjectInter);
m_dockDaemonInter->MergePluginSettings(QJsonDocument(remoteObject).toJson(QJsonDocument::JsonFormat::Compact));
}
const QVariant AbstractPluginsController::getValue(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::removeValue(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);
}
QMap<PluginsItemInterface *, QMap<QString, QObject *> > &AbstractPluginsController::pluginsMap()
{
return m_pluginsMap;
}
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)
{
for (auto it = m_pluginsMap.constBegin(); it != m_pluginsMap.constEnd(); ++it) {
for (auto key : it.value().keys()) {
if (key == itemKey) {
return it.key();
}
}
}
return nullptr;
}
PluginsItemInterface *AbstractPluginsController::pluginInterAt(QObject *destItem)
{
for (auto it = m_pluginsMap.constBegin(); it != m_pluginsMap.constEnd(); ++it) {
for (auto item : it.value().values()) {
if (item == destItem) {
return it.key();
}
}
}
return nullptr;
}
void AbstractPluginsController::startLoader(PluginLoader *loader)
{
connect(loader, &PluginLoader::finished, loader, &PluginLoader::deleteLater, Qt::QueuedConnection);
connect(loader, &PluginLoader::pluginFounded, this, &AbstractPluginsController::loadPlugin, Qt::QueuedConnection);
QGSettings gsetting("com.deepin.dde.dock", "/com/deepin/dde/dock/");
QTimer::singleShot(gsetting.get("delay-plugins-time").toUInt(),
loader, [=] { loader->start(QThread::LowestPriority); });
}
void AbstractPluginsController::displayModeChanged()
{
const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
const auto inters = m_pluginsMap.keys();
for (auto inter : inters)
inter->displayModeChanged(displayMode);
}
void AbstractPluginsController::positionChanged()
{
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
const auto inters = m_pluginsMap.keys();
for (auto inter : inters)
inter->positionChanged(position);
}
void AbstractPluginsController::loadPlugin(const QString &pluginFile)
{
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile);
const QJsonObject &meta = pluginLoader->metaData().value("MetaData").toObject();
const QString &pluginApi = meta.value("api").toString();
if (pluginApi.isEmpty() || !CompatiblePluginApiList.contains(pluginApi))
{
qWarning() << objectName()
<< "plugin api version not matched! expect versions:" << CompatiblePluginApiList
<< ", got version:" << pluginApi
<< ", the plugin file is:" << pluginFile;
return;
}
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
if (!interface)
{
qWarning() << objectName() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
pluginLoader->unload();
pluginLoader->deleteLater();
return;
}
m_pluginsMap.insert(interface, QMap<QString, QObject *>());
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) {
if (name == dbusService && !newOwner.isEmpty()) {
qDebug() << objectName() << dbusService << "daemon started, init plugin and disconnect";
initPlugin(interface);
disconnect(m_dbusDaemonInterface);
}
}
);
return;
}
initPlugin(interface);
}
void AbstractPluginsController::initPlugin(PluginsItemInterface *interface) {
qDebug() << objectName() << "init plugin: " << interface->pluginName();
interface->init(this);
qDebug() << objectName() << "init plugin finished: " << interface->pluginName();
}
void AbstractPluginsController::refreshPluginSettings()
{
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) {
itemRemoved(it.key(), key);
}
for (auto key : itemKeyList) {
itemAdded(it.key(), key);
}
}
}
bool AbstractPluginsController::eventFilter(QObject *o, QEvent *e)
{
if (o != qApp)
return false;
if (e->type() != QEvent::DynamicPropertyChange)
return false;
QDynamicPropertyChangeEvent * const dpce = static_cast<QDynamicPropertyChangeEvent *>(e);
const QString propertyName = dpce->propertyName();
if (propertyName == PROP_POSITION)
positionChanged();
else if (propertyName == PROP_DISPLAY_MODE)
displayModeChanged();
return false;
}

View File

@ -0,0 +1,78 @@
/*
* 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 ABSTRACTPLUGINSCONTROLLER_H
#define ABSTRACTPLUGINSCONTROLLER_H
#include "pluginproxyinterface.h"
#include "pluginloader.h"
#include <com_deepin_dde_daemon_dock.h>
#include <QPluginLoader>
#include <QList>
#include <QMap>
#include <QDBusConnectionInterface>
using DockDaemonInter = com::deepin::dde::daemon::Dock;
class PluginsItemInterface;
class AbstractPluginsController : public QObject, PluginProxyInterface
{
Q_OBJECT
public:
explicit AbstractPluginsController(QObject *parent = 0);
// implements PluginProxyInterface
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) Q_DECL_OVERRIDE;
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) Q_DECL_OVERRIDE;
void removeValue(PluginsItemInterface * const itemInter, const QStringList &keyList) override;
protected:
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap();
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
PluginsItemInterface *pluginInterAt(const QString &itemKey);
PluginsItemInterface *pluginInterAt(QObject *destItem);
protected Q_SLOTS:
void startLoader(PluginLoader *loader);
private slots:
void displayModeChanged();
void positionChanged();
void loadPlugin(const QString &pluginFile);
void initPlugin(PluginsItemInterface *interface);
void refreshPluginSettings();
private:
bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
private:
QDBusConnectionInterface *m_dbusDaemonInterface;
DockDaemonInter *m_dockDaemonInter;
QMap<PluginsItemInterface *, QMap<QString, QObject *>> m_pluginsMap;
QJsonObject m_pluginSettingsObject;
};
#endif // ABSTRACTPLUGINSCONTROLLER_H

View File

@ -19,25 +19,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "dockpluginloader.h"
#include "dockpluginscontroller.h"
#include "pluginloader.h"
#include <QDir>
#include <QDebug>
#include <QLibrary>
DockPluginLoader::DockPluginLoader(QObject *parent)
PluginLoader::PluginLoader(const QString &pluginDirPath, QObject *parent)
: QThread(parent)
, m_pluginDirPath(pluginDirPath)
{
}
void DockPluginLoader::run()
void PluginLoader::run()
{
QDir pluginsDir("../plugins");
if (!pluginsDir.exists()) {
pluginsDir.setPath("/usr/lib/dde-dock/plugins");
}
qDebug() << "using dock plugins dir:" << pluginsDir.absolutePath();
QDir pluginsDir(m_pluginDirPath);
const QStringList plugins = pluginsDir.entryList(QDir::Files);
for (const QString file : plugins)

View File

@ -19,17 +19,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DOCKPLUGINLOADER_H
#define DOCKPLUGINLOADER_H
#ifndef PLUGINLOADER_H
#define PLUGINLOADER_H
#include <QThread>
class DockPluginLoader : public QThread
class PluginLoader : public QThread
{
Q_OBJECT
public:
explicit DockPluginLoader(QObject *parent);
explicit PluginLoader(const QString &pluginDirPath, QObject *parent);
signals:
void finished() const;
@ -37,6 +37,9 @@ signals:
protected:
void run();
private:
QString m_pluginDirPath;
};
#endif // DOCKPLUGINLOADER_H
#endif // PLUGINLOADER_H

View File

@ -27,7 +27,7 @@
namespace Dock {
#define DOCK_PLUGIN_MIME "dock/plugin"
#define DOCK_PLUGIN_API_VERSION "1.1.1"
#define DOCK_PLUGIN_API_VERSION "1.2.1"
#define PROP_DISPLAY_MODE "DisplayMode"
///

View File

@ -85,6 +85,14 @@ public:
/// return value from .config/deepin/dde-dock.conf
///
virtual const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) = 0;
///
/// \brief removeValue
/// remove the values specified by keyList
/// remove all values of itemInter if keyList is empty
/// SeeAlse: saveValue
///
virtual void removeValue(PluginsItemInterface *const itemInter, const QStringList &keyList) = 0;
};
#endif // PLUGINPROXYINTERFACE_H

View File

@ -211,6 +211,12 @@ public:
return qApp->property(PROP_POSITION).value<Dock::Position>();
}
///
/// \brief settingsChanged
/// override this function to receive plugin settings changed signal(DeepinSync)
///
virtual void pluginSettingsChanged() {}
protected:
///
/// \brief m_proxyInter

View File

@ -79,10 +79,7 @@ void DatetimePlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, pluginIsDisable());
if (!pluginIsDisable())
m_proxyInter->itemAdded(this, pluginName());
else
m_proxyInter->itemRemoved(this, pluginName());
refreshPluginItemsVisible();
}
bool DatetimePlugin::pluginIsDisable()
@ -183,6 +180,13 @@ void DatetimePlugin::invokedMenuItem(const QString &itemKey, const QString &menu
}
}
void DatetimePlugin::pluginSettingsChanged()
{
m_centralWidget->set24HourFormat(m_proxyInter->getValue(this, TIME_FORMAT_KEY, true).toBool());
refreshPluginItemsVisible();
}
void DatetimePlugin::updateCurrentTimeString()
{
const QDateTime currentDateTime = QDateTime::currentDateTime();
@ -200,3 +204,11 @@ void DatetimePlugin::updateCurrentTimeString()
m_currentTimeString = currentString;
m_centralWidget->update();
}
void DatetimePlugin::refreshPluginItemsVisible()
{
if (!pluginIsDisable())
m_proxyInter->itemAdded(this, pluginName());
else
m_proxyInter->itemRemoved(this, pluginName());
}

View File

@ -58,8 +58,11 @@ public:
void invokedMenuItem(const QString &itemKey, const QString &menuId, const bool checked) override;
void pluginSettingsChanged() override;
private slots:
void updateCurrentTimeString();
void refreshPluginItemsVisible();
private:
QPointer<DatetimeWidget> m_centralWidget;

View File

@ -88,19 +88,7 @@ void NetworkPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, STATE_KEY, pluginIsDisable());
if (pluginIsDisable()) {
for (auto itemKey : m_itemsMap.keys()) {
m_proxyInter->itemRemoved(this, itemKey);
}
return;
}
if (!m_pluginLoaded) {
loadPlugin();
return;
}
onDeviceListChanged(m_networkModel->devices());
refreshPluginItemsVisible();
}
bool NetworkPlugin::pluginIsDisable()
@ -171,6 +159,11 @@ void NetworkPlugin::setSortKey(const QString &itemKey, const int order)
m_proxyInter->saveValue(this, key, order);
}
void NetworkPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
bool NetworkPlugin::isConnectivity()
{
return NetworkModel::connectivity() == Connectivity::Full;
@ -329,3 +322,20 @@ void NetworkPlugin::onItemRequestSetAppletVisible(const bool visible)
m_proxyInter->requestSetAppletVisible(this, item->path(), visible);
}
void NetworkPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable()) {
for (auto itemKey : m_itemsMap.keys()) {
m_proxyInter->itemRemoved(this, itemKey);
}
return;
}
if (!m_pluginLoaded) {
loadPlugin();
return;
}
onDeviceListChanged(m_networkModel->devices());
}

View File

@ -54,12 +54,15 @@ public:
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
static bool isConnectivity();
private slots:
void onDeviceListChanged(const QList<dde::network::NetworkDevice *> devices);
void refreshWiredItemVisible();
void onItemRequestSetAppletVisible(const bool visible);
void refreshPluginItemsVisible();
private:
DeviceItem *itemByPath(const QString &path);

View File

@ -73,16 +73,7 @@ void OnboardPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, pluginIsDisable());
if (pluginIsDisable())
{
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
refreshPluginItemsVisible();
}
bool OnboardPlugin::pluginIsDisable()
@ -151,6 +142,11 @@ void OnboardPlugin::setSortKey(const QString &itemKey, const int order)
m_proxyInter->saveValue(this, key, order);
}
void OnboardPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
void OnboardPlugin::loadPlugin()
{
if (m_pluginLoaded) {
@ -165,3 +161,17 @@ void OnboardPlugin::loadPlugin()
m_proxyInter->itemAdded(this, pluginName());
displayModeChanged(displayMode());
}
void OnboardPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable())
{
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
}

View File

@ -55,8 +55,11 @@ public:
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
private:
void loadPlugin();
void refreshPluginItemsVisible();
private:
bool m_pluginLoaded;

View File

@ -94,15 +94,7 @@ void PowerPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, pluginIsDisable());
if (pluginIsDisable()) {
m_proxyInter->itemRemoved(this, POWER_KEY);
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
updateBatteryVisible();
}
refreshPluginItemsVisible();
}
bool PowerPlugin::pluginIsDisable()
@ -171,6 +163,11 @@ void PowerPlugin::setSortKey(const QString &itemKey, const int order)
m_proxyInter->saveValue(this, key, order);
}
void PowerPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
void PowerPlugin::updateBatteryVisible()
{
const bool exist = !m_powerInter->batteryPercentage().isEmpty();
@ -197,3 +194,16 @@ void PowerPlugin::loadPlugin()
updateBatteryVisible();
}
void PowerPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable()) {
m_proxyInter->itemRemoved(this, POWER_KEY);
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
updateBatteryVisible();
}
}

View File

@ -55,10 +55,12 @@ public:
void refreshIcon(const QString &itemKey) Q_DECL_OVERRIDE;
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
private:
void updateBatteryVisible();
void loadPlugin();
void refreshPluginItemsVisible();
private:
bool m_pluginLoaded;

View File

@ -83,16 +83,7 @@ void ShutdownPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, PLUGIN_STATE_KEY, !m_proxyInter->getValue(this, PLUGIN_STATE_KEY, true).toBool());
if (pluginIsDisable())
{
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
refreshPluginItemsVisible();
}
bool ShutdownPlugin::pluginIsDisable()
@ -223,6 +214,11 @@ void ShutdownPlugin::setSortKey(const QString &itemKey, const int order)
m_proxyInter->saveValue(this, key, order);
}
void ShutdownPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
void ShutdownPlugin::loadPlugin()
{
if (m_pluginLoaded) {
@ -251,3 +247,17 @@ bool ShutdownPlugin::checkSwap()
return false;
}
void ShutdownPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable())
{
m_proxyInter->itemRemoved(this, pluginName());
} else {
if (!m_pluginLoaded) {
loadPlugin();
return;
}
m_proxyInter->itemAdded(this, pluginName());
}
}

View File

@ -55,9 +55,12 @@ public:
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
private:
void loadPlugin();
bool checkSwap();
void refreshPluginItemsVisible();
private:
bool m_pluginLoaded;

View File

@ -54,10 +54,7 @@ void SoundPlugin::pluginStateSwitched()
{
m_proxyInter->saveValue(this, STATE_KEY, pluginIsDisable());
if (pluginIsDisable())
m_proxyInter->itemRemoved(this, SOUND_KEY);
else
m_proxyInter->itemAdded(this, SOUND_KEY);
refreshPluginItemsVisible();
}
bool SoundPlugin::pluginIsDisable()
@ -128,3 +125,16 @@ void SoundPlugin::refreshIcon(const QString &itemKey)
m_soundItem->refreshIcon();
}
}
void SoundPlugin::pluginSettingsChanged()
{
refreshPluginItemsVisible();
}
void SoundPlugin::refreshPluginItemsVisible()
{
if (pluginIsDisable())
m_proxyInter->itemRemoved(this, SOUND_KEY);
else
m_proxyInter->itemAdded(this, SOUND_KEY);
}

View File

@ -48,6 +48,10 @@ public:
int itemSortKey(const QString &itemKey) Q_DECL_OVERRIDE;
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void refreshIcon(const QString &itemKey) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
private:
void refreshPluginItemsVisible();
private:
SoundItem *m_soundItem;

View File

@ -111,7 +111,7 @@ void PopupControlWidget::clearTrashFloder()
d.setTitle(ClearTrashMutliple.arg(count));
d.setMessage(qApp->translate("DialogManager", "This action cannot be restored"));
d.setIcon(m_dialogTrashFullIcon);
d.setIcon(m_dialogTrashFullIcon, QSize(64, 64));
d.addButton(buttonTexts[0], true, DDialog::ButtonNormal);
d.addButton(buttonTexts[1], false, DDialog::ButtonWarning);
d.setDefaultButton(1);

View File

@ -7,6 +7,8 @@ project(${PLUGIN_NAME})
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp"
"../../frame/util/themeappicon.h" "../../frame/util/themeappicon.cpp"
"../../frame/util/dockpopupwindow.h" "../../frame/util/dockpopupwindow.cpp"
"../../frame/util/abstractpluginscontroller.h" "../../frame/util/abstractpluginscontroller.cpp"
"../../frame/util/pluginloader.h" "../../frame/util/pluginloader.cpp"
"../../frame/dbus/sni/*.h" "../../frame/dbus/sni/*.cpp"
"../../frame/dbus/dbusmenu.h" "../../frame/dbus/dbusmenu.cpp"
"../../frame/dbus/dbusmenumanager.h" "../../frame/dbus/dbusmenumanager.cpp")
@ -21,6 +23,7 @@ find_package(DtkWidget REQUIRED)
pkg_check_modules(XCB_LIBS REQUIRED xcb-ewmh xcb xcb-image xcb-composite xtst xcb-icccm dbusmenu-qt5)
pkg_check_modules(DDE-Network-Utils REQUIRED dde-network-utils)
pkg_check_modules(DFrameworkDBus REQUIRED dframeworkdbus)
pkg_check_modules(QGSettings REQUIRED gsettings-qt)
add_definitions("${QT_DEFINITIONS} -DQT_PLUGIN")
add_library(${PLUGIN_NAME} SHARED ${SRCS} tray.qrc)
@ -30,6 +33,7 @@ target_include_directories(${PLUGIN_NAME} PUBLIC ${DtkWidget_INCLUDE_DIRS}
${XCB_LIBS_INCLUDE_DIRS}
${DDE-Network-Utils_INCLUDE_DIRS}
${DFrameworkDBus_INCLUDE_DIRS}
${QGSettings_INCLUDE_DIRS}
../../interfaces
../../frame)
target_link_libraries(${PLUGIN_NAME} PRIVATE
@ -41,6 +45,7 @@ target_link_libraries(${PLUGIN_NAME} PRIVATE
${XCB_LIBS_LIBRARIES}
${DDE-Network-Utils_LIBRARIES}
${DFrameworkDBus_LIBRARIES}
${QGSettings_LIBRARIES}
)
install(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION lib/dde-dock/plugins)

View File

@ -29,7 +29,7 @@ HoldContainer::HoldContainer(TrayPlugin *trayPlugin, QWidget *parent)
bool HoldContainer::acceptWrapper(FashionTrayWidgetWrapper *wrapper)
{
const QString &key = wrapper->absTrayWidget()->itemKeyForConfig() + HoldKeySuffix;
const QString &key = HoldKeyPrefix + wrapper->absTrayWidget()->itemKeyForConfig();
return trayPlugin()->getValue(wrapper->itemKey(), key, false).toBool();
}
@ -39,7 +39,7 @@ void HoldContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
AbstractContainer::addWrapper(wrapper);
if (containsWrapper(wrapper)) {
const QString &key = wrapper->absTrayWidget()->itemKeyForConfig() + HoldKeySuffix;
const QString &key = HoldKeyPrefix + wrapper->absTrayWidget()->itemKeyForConfig();
trayPlugin()->saveValue(wrapper->itemKey(), key, true);
}
}

View File

@ -18,7 +18,7 @@ void NormalContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
AbstractContainer::addWrapper(wrapper);
if (containsWrapper(wrapper)) {
const QString &key = wrapper->absTrayWidget()->itemKeyForConfig() + HoldKeySuffix;
const QString &key = HoldKeyPrefix + wrapper->absTrayWidget()->itemKeyForConfig();
trayPlugin()->saveValue(wrapper->itemKey(), key, false);
}
}

View File

@ -9,7 +9,7 @@ namespace Dock {
#define TrayWidgetHeightMin 24
#define HoldKeySuffix "-holded"
#define HoldKeyPrefix "holded_"
}

View File

@ -240,6 +240,11 @@ void FashionTrayItem::setRightSplitVisible(const bool visible)
}
}
void FashionTrayItem::onPluginSettingsChanged()
{
m_controlWidget->setExpanded(m_trayPlugin->getValue(FASHION_MODE_ITEM_KEY, ExpandedKey, true).toBool());
}
void FashionTrayItem::showEvent(QShowEvent *event)
{
requestResize();

View File

@ -60,6 +60,7 @@ public slots:
void onExpandChanged(const bool expand);
void setSuggestIconSize(QSize size);
void setRightSplitVisible(const bool visible);
void onPluginSettingsChanged();
protected:
void showEvent(QShowEvent *event) Q_DECL_OVERRIDE;

View File

@ -1,58 +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 "systemtrayloader.h"
#include "systemtrayscontroller.h"
#include <QDebug>
SystemTrayLoader::SystemTrayLoader(QObject *parent)
: QThread(parent)
{
}
void SystemTrayLoader::run()
{
QDir pluginsDir("../plugins/system-trays");
if (!pluginsDir.exists()) {
pluginsDir.setPath("/usr/lib/dde-dock/plugins/system-trays");
}
qDebug() << "using system tray plugins dir:" << pluginsDir.absolutePath();
const QStringList plugins = pluginsDir.entryList(QDir::Files);
for (const QString file : plugins)
{
if (!QLibrary::isLibrary(file))
continue;
// TODO: old dock plugins is uncompatible
if (file.startsWith("libdde-dock-"))
continue;
emit pluginFounded(pluginsDir.absoluteFilePath(file));
msleep(500);
}
emit finished();
}

View File

@ -1,42 +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 SYSTEMTRAYLOADER_H
#define SYSTEMTRAYLOADER_H
#include <QThread>
class SystemTrayLoader : public QThread
{
Q_OBJECT
public:
explicit SystemTrayLoader(QObject *parent);
signals:
void finished() const;
void pluginFounded(const QString &pluginFile) const;
protected:
void run();
};
#endif // SYSTEMTRAYLOADER_H

View File

@ -21,58 +21,57 @@
#include "systemtrayscontroller.h"
#include "pluginsiteminterface.h"
#include "systemtrayloader.h"
#include <QDebug>
#include <QDir>
SystemTraysController::SystemTraysController(QObject *parent)
: QObject(parent)
, m_dbusDaemonInterface(QDBusConnection::sessionBus().interface())
, m_pluginsSetting("deepin", "dde-dock")
: AbstractPluginsController(parent)
{
qApp->installEventFilter(this);
setObjectName("SystemTray");
}
void SystemTraysController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
{
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &mPluginsMap = pluginsMap();
// check if same item added
if (m_pluginsMap.contains(itemInter))
if (m_pluginsMap[itemInter].contains(itemKey))
if (mPluginsMap.contains(itemInter))
if (mPluginsMap[itemInter].contains(itemKey))
return;
SystemTrayItem *item = new SystemTrayItem(itemInter, itemKey);
item->setVisible(false);
m_pluginsMap[itemInter][itemKey] = item;
mPluginsMap[itemInter][itemKey] = item;
emit systemTrayAdded(itemKey, item);
emit pluginItemAdded(itemKey, item);
}
void SystemTraysController::itemUpdate(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemTrayItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
SystemTrayItem *item = static_cast<SystemTrayItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
item->update();
emit systemTrayUpdated(itemKey);
emit pluginItemUpdated(itemKey, item);
}
void SystemTraysController::itemRemoved(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemTrayItem *item = pluginItemAt(itemInter, itemKey);
SystemTrayItem *item = static_cast<SystemTrayItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
item->detachPluginWidget();
emit systemTrayRemoved(itemKey);
emit pluginItemRemoved(itemKey, item);
m_pluginsMap[itemInter].remove(itemKey);
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);
@ -83,24 +82,27 @@ void SystemTraysController::itemRemoved(PluginsItemInterface * const itemInter,
void SystemTraysController::requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide)
{
SystemTrayItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
SystemTrayItem *item = static_cast<SystemTrayItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestWindowAutoHide(autoHide);
}
void SystemTraysController::requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey)
{
SystemTrayItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
SystemTrayItem *item = static_cast<SystemTrayItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
Q_EMIT item->requestRefershWindowVisible();
}
void SystemTraysController::requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible)
{
SystemTrayItem *item = pluginItemAt(itemInter, itemKey);
Q_ASSERT(item);
SystemTrayItem *item = static_cast<SystemTrayItem *>(pluginItemAt(itemInter, itemKey));
if (!item)
return;
if (visible) {
item->showPopupApplet(itemInter->itemPopupApplet(itemKey));
@ -109,144 +111,6 @@ void SystemTraysController::requestSetAppletVisible(PluginsItemInterface * const
}
}
void SystemTraysController::startLoader()
{
SystemTrayLoader *loader = new SystemTrayLoader(this);
connect(loader, &SystemTrayLoader::finished, loader, &SystemTrayLoader::deleteLater, Qt::QueuedConnection);
connect(loader, &SystemTrayLoader::pluginFounded, this, &SystemTraysController::loadPlugin, Qt::QueuedConnection);
QTimer::singleShot(1, loader, [=] { loader->start(QThread::LowestPriority); });
}
void SystemTraysController::displayModeChanged()
{
const Dock::DisplayMode displayMode = qApp->property(PROP_DISPLAY_MODE).value<Dock::DisplayMode>();
const auto inters = m_pluginsMap.keys();
for (auto inter : inters)
inter->displayModeChanged(displayMode);
}
void SystemTraysController::positionChanged()
{
const Dock::Position position = qApp->property(PROP_POSITION).value<Dock::Position>();
const auto inters = m_pluginsMap.keys();
for (auto inter : inters)
inter->positionChanged(position);
}
void SystemTraysController::loadPlugin(const QString &pluginFile)
{
QPluginLoader *pluginLoader = new QPluginLoader(pluginFile);
const auto meta = pluginLoader->metaData().value("MetaData").toObject();
if (!meta.contains("api") || meta["api"].toString() != DOCK_PLUGIN_API_VERSION)
{
qWarning() << "plugin api version not matched! expect version:" << DOCK_PLUGIN_API_VERSION << pluginFile;
return;
}
PluginsItemInterface *interface = qobject_cast<PluginsItemInterface *>(pluginLoader->instance());
if (!interface)
{
qWarning() << "load plugin failed!!!" << pluginLoader->errorString() << pluginFile;
pluginLoader->unload();
pluginLoader->deleteLater();
return;
}
m_pluginsMap.insert(interface, QMap<QString, SystemTrayItem *>());
QString dbusService = meta.value("depends-daemon-dbus-service").toString();
if (!dbusService.isEmpty() && !m_dbusDaemonInterface->isServiceRegistered(dbusService).value()) {
qDebug() << "SystemTray:" << dbusService << "daemon has not started, waiting for signal";
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this,
[=](const QString &name, const QString &oldOwner, const QString &newOwner) {
if (name == dbusService && !newOwner.isEmpty()) {
qDebug() << "SystemTray:" << dbusService << "daemon started, init plugin and disconnect";
initPlugin(interface);
disconnect(m_dbusDaemonInterface);
}
}
);
return;
}
initPlugin(interface);
}
void SystemTraysController::initPlugin(PluginsItemInterface *interface) {
qDebug() << "SystemTray:" << "init plugin: " << interface->pluginName();
interface->init(this);
qDebug() << "SystemTray:" << "init plugin finished: " << interface->pluginName();
}
bool SystemTraysController::eventFilter(QObject *o, QEvent *e)
{
if (o != qApp)
return false;
if (e->type() != QEvent::DynamicPropertyChange)
return false;
QDynamicPropertyChangeEvent * const dpce = static_cast<QDynamicPropertyChangeEvent *>(e);
const QString propertyName = dpce->propertyName();
if (propertyName == PROP_POSITION)
positionChanged();
else if (propertyName == PROP_DISPLAY_MODE)
displayModeChanged();
return false;
}
SystemTrayItem *SystemTraysController::pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const
{
if (!m_pluginsMap.contains(itemInter))
return nullptr;
return m_pluginsMap[itemInter][itemKey];
}
PluginsItemInterface *SystemTraysController::pluginInterAt(const QString &itemKey) const
{
for (auto it = m_pluginsMap.constBegin(); it != m_pluginsMap.constEnd(); ++it) {
for (auto key : it.value().keys()) {
if (key == itemKey) {
return it.key();
}
}
}
return nullptr;
}
PluginsItemInterface *SystemTraysController::pluginInterAt(SystemTrayItem *systemTrayItem) const
{
for (auto it = m_pluginsMap.constBegin(); it != m_pluginsMap.constEnd(); ++it) {
for (auto item : it.value().values()) {
if (item == systemTrayItem) {
return it.key();
}
}
}
return nullptr;
}
void SystemTraysController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) {
m_pluginsSetting.beginGroup(itemInter->pluginName());
m_pluginsSetting.setValue(key, value);
m_pluginsSetting.endGroup();
}
const QVariant SystemTraysController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback) {
m_pluginsSetting.beginGroup(itemInter->pluginName());
QVariant value(m_pluginsSetting.value(key, fallback));
m_pluginsSetting.endGroup();
return value;
}
int SystemTraysController::systemTrayItemSortKey(const QString &itemKey)
{
auto inter = pluginInterAt(itemKey);
@ -290,3 +154,14 @@ void SystemTraysController::saveValueSystemTrayItem(const QString &itemKey, cons
saveValue(inter, key, value);
}
void SystemTraysController::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

@ -24,6 +24,9 @@
#include "systemtrayitem.h"
#include "pluginproxyinterface.h"
#include "util/abstractpluginscontroller.h"
#include <com_deepin_dde_daemon_dock.h>
#include <QPluginLoader>
#include <QList>
@ -31,7 +34,7 @@
#include <QDBusConnectionInterface>
class PluginsItemInterface;
class SystemTraysController : public QObject, PluginProxyInterface
class SystemTraysController : public AbstractPluginsController
{
Q_OBJECT
@ -45,8 +48,6 @@ public:
void requestWindowAutoHide(PluginsItemInterface * const itemInter, const QString &itemKey, const bool autoHide) Q_DECL_OVERRIDE;
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) Q_DECL_OVERRIDE;
void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) Q_DECL_OVERRIDE;
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) Q_DECL_OVERRIDE;
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) Q_DECL_OVERRIDE;
int systemTrayItemSortKey(const QString &itemKey);
void setSystemTrayItemSortKey(const QString &itemKey, const int order);
@ -54,31 +55,12 @@ 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);
public slots:
void startLoader();
signals:
void systemTrayAdded(const QString &itemKey, AbstractTrayWidget *trayWidget) const;
void systemTrayRemoved(const QString &itemKey) const;
void systemTrayUpdated(const QString &itemKey) const;
private slots:
void displayModeChanged();
void positionChanged();
void loadPlugin(const QString &pluginFile);
void initPlugin(PluginsItemInterface *interface);
private:
bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
SystemTrayItem *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
PluginsItemInterface *pluginInterAt(const QString &itemKey) const;
PluginsItemInterface *pluginInterAt(SystemTrayItem *systemTrayItem) const;
private:
QDBusConnectionInterface *m_dbusDaemonInterface;
QMap<PluginsItemInterface *, QMap<QString, SystemTrayItem *>> m_pluginsMap;
QSettings m_pluginsSetting;
void pluginItemAdded(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
void pluginItemRemoved(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
void pluginItemUpdated(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
};
#endif // SYSTEMTRAYSCONTROLLER_H

View File

@ -32,6 +32,7 @@
#include "../widgets/tipswidget.h"
#include "xcb/xcb_icccm.h"
#define PLUGIN_ENABLED_KEY "enable"
#define FASHION_MODE_TRAYS_SORTED "fashion-mode-trays-sorted"
#define SNI_WATCHER_SERVICE "org.kde.StatusNotifierWatcher"
@ -77,13 +78,13 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
m_proxyInter = proxyInter;
if (!proxyInter->getValue(this, "enable", true).toBool()) {
if (pluginIsDisable()) {
qDebug() << "hide tray from config disable!!";
return;
}
connect(m_systemTraysController, &SystemTraysController::systemTrayAdded, this, &TrayPlugin::addTrayWidget);
connect(m_systemTraysController, &SystemTraysController::systemTrayRemoved, this, [=](const QString &itemKey) {trayRemoved(itemKey);});
connect(m_systemTraysController, &SystemTraysController::pluginItemAdded, this, &TrayPlugin::addTrayWidget);
connect(m_systemTraysController, &SystemTraysController::pluginItemRemoved, this, [=](const QString &itemKey) {trayRemoved(itemKey);});
m_trayInter->Manage();
@ -96,9 +97,14 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
QTimer::singleShot(4000, this, &TrayPlugin::initXEmbed);
}
bool TrayPlugin::pluginIsDisable()
{
return !m_proxyInter->getValue(this, PLUGIN_ENABLED_KEY, true).toBool();
}
void TrayPlugin::displayModeChanged(const Dock::DisplayMode mode)
{
if (!m_proxyInter->getValue(this, "enable", true).toBool()) {
if (pluginIsDisable()) {
return;
}
@ -107,7 +113,7 @@ void TrayPlugin::displayModeChanged(const Dock::DisplayMode mode)
void TrayPlugin::positionChanged(const Dock::Position position)
{
if (!m_proxyInter->getValue(this, "enable", true).toBool()) {
if (pluginIsDisable()) {
return;
}
@ -230,6 +236,19 @@ void TrayPlugin::refreshIcon(const QString &itemKey)
}
}
void TrayPlugin::pluginSettingsChanged()
{
if (pluginIsDisable()) {
return;
}
if (displayMode() == Dock::DisplayMode::Fashion) {
m_fashionItem->onPluginSettingsChanged();
m_fashionItem->clearTrayWidgets();
m_fashionItem->setTrayWidgets(m_trayMap);
}
}
Dock::Position TrayPlugin::dockPosition() const
{
return position();

View File

@ -48,6 +48,7 @@ public:
const QString pluginName() const Q_DECL_OVERRIDE;
void init(PluginProxyInterface *proxyInter) Q_DECL_OVERRIDE;
bool pluginIsDisable() override;
void displayModeChanged(const Dock::DisplayMode mode) Q_DECL_OVERRIDE;
void positionChanged(const Dock::Position position) Q_DECL_OVERRIDE;
QWidget *itemWidget(const QString &itemKey) Q_DECL_OVERRIDE;
@ -59,6 +60,7 @@ public:
void setSortKey(const QString &itemKey, const int order) Q_DECL_OVERRIDE;
void setItemIsInContainer(const QString &itemKey, const bool container) Q_DECL_OVERRIDE;
void refreshIcon(const QString &itemKey) Q_DECL_OVERRIDE;
void pluginSettingsChanged() override;
Dock::Position dockPosition() const;
bool traysSortedInFashionMode();