mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 09:23:03 +00:00
refactor: system tray plugins controller/loader
Change-Id: I08d0a5539ba788f7a29f187b419aa0c4b43f3408
This commit is contained in:
parent
31f8ab6c4c
commit
51e62820df
Notes:
gerrit
2019-01-08 09:09:33 +08:00
Verified-1: <jenkins@deepin.com> Reviewed-on: https://cr.deepin.io/41152 Project: dde/dde-dock Branch: refs/heads/dev/daemon-plugin-settings
188
frame/util/abstractpluginscontroller.cpp
Normal file
188
frame/util/abstractpluginscontroller.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
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(QDateTime::currentMSecsSinceEpoch() / 1000 / 1000);
|
||||
|
||||
connect(m_dockDaemonInter, &DockDaemonInter::PluginSettingsUpdated, this, &AbstractPluginsController::refreshPluginSettings);
|
||||
}
|
||||
|
||||
void AbstractPluginsController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) {
|
||||
QJsonObject valueObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||
valueObject.insert(key, value.toJsonValue());
|
||||
m_pluginSettingsObject.insert(itemInter->pluginName(), valueObject);
|
||||
|
||||
m_dockDaemonInter->SetPluginSettings(
|
||||
QDateTime::currentMSecsSinceEpoch() / 1000 / 1000,
|
||||
QJsonDocument(m_pluginSettingsObject).toJson());
|
||||
}
|
||||
|
||||
const QVariant AbstractPluginsController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback) {
|
||||
QVariant v = m_pluginSettingsObject.value(itemInter->pluginName()).toObject().value(key).toVariant();
|
||||
if (v.isNull() || !v.isValid()) {
|
||||
v = fallback;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
|
||||
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 auto meta = pluginLoader->metaData().value("MetaData").toObject();
|
||||
if (!meta.contains("api") || meta["api"].toString() != DOCK_PLUGIN_API_VERSION)
|
||||
{
|
||||
qWarning() << objectName() << "plugin api version not matched! expect version:" << DOCK_PLUGIN_API_VERSION << 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(qlonglong ts)
|
||||
{
|
||||
// TODO: handle nano seconds
|
||||
|
||||
const QString &pluginSettings = m_dockDaemonInter->GetPluginSettings().value();
|
||||
if (pluginSettings.isEmpty()) {
|
||||
qDebug() << "Error! get plugin settings from dbus failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject &settingsObject = QJsonDocument::fromJson(pluginSettings.toLocal8Bit()).object();
|
||||
if (settingsObject.isEmpty()) {
|
||||
qDebug() << "Error! parse plugin settings from json failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_pluginSettingsObject = settingsObject;
|
||||
|
||||
// not notify plugins to refresh settings if this update is not emit by dock daemon
|
||||
if (sender() != m_dockDaemonInter) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: notify all plugins to reload plugin settings
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
74
frame/util/abstractpluginscontroller.h
Normal file
74
frame/util/abstractpluginscontroller.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
protected:
|
||||
QMap<PluginsItemInterface *, QMap<QString, QObject *>> &pluginsMap();
|
||||
QObject *pluginItemAt(PluginsItemInterface * const itemInter, const QString &itemKey) const;
|
||||
|
||||
protected Q_SLOTS:
|
||||
void startLoader(PluginLoader *loader);
|
||||
|
||||
private slots:
|
||||
void displayModeChanged();
|
||||
void positionChanged();
|
||||
void loadPlugin(const QString &pluginFile);
|
||||
void initPlugin(PluginsItemInterface *interface);
|
||||
void refreshPluginSettings(qlonglong ts);
|
||||
|
||||
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
|
54
frame/util/pluginloader.cpp
Normal file
54
frame/util/pluginloader.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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 "pluginloader.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
#include <QLibrary>
|
||||
|
||||
PluginLoader::PluginLoader(const QString &pluginDirPath, QObject *parent)
|
||||
: QThread(parent)
|
||||
, m_pluginDirPath(pluginDirPath)
|
||||
{
|
||||
}
|
||||
|
||||
void PluginLoader::run()
|
||||
{
|
||||
const QDir pluginsDir(m_pluginDirPath);
|
||||
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();
|
||||
}
|
45
frame/util/pluginloader.h
Normal file
45
frame/util/pluginloader.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 PLUGINLOADER_H
|
||||
#define PLUGINLOADER_H
|
||||
|
||||
#include <QThread>
|
||||
|
||||
class PluginLoader : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PluginLoader(const QString &pluginDirPath, QObject *parent);
|
||||
|
||||
signals:
|
||||
void finished() const;
|
||||
void pluginFounded(const QString &pluginFile) const;
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
private:
|
||||
QString m_pluginDirPath;
|
||||
};
|
||||
|
||||
#endif // PLUGINLOADER_H
|
@ -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/dbusmenu.h" "../../frame/dbus/dbusmenu.cpp"
|
||||
"../../frame/dbus/dbusmenumanager.h" "../../frame/dbus/dbusmenumanager.cpp")
|
||||
|
||||
@ -20,6 +22,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)
|
||||
@ -29,6 +32,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
|
||||
@ -40,6 +44,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)
|
||||
|
@ -27,56 +27,52 @@
|
||||
#include <QDir>
|
||||
|
||||
SystemTraysController::SystemTraysController(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))
|
||||
: AbstractPluginsController(parent)
|
||||
{
|
||||
qApp->installEventFilter(this);
|
||||
|
||||
refreshPluginSettings(QDateTime::currentMSecsSinceEpoch() / 1000 / 1000);
|
||||
|
||||
connect(m_dockDaemonInter, &DockDaemonInter::PluginSettingsUpdated, this, &SystemTraysController::refreshPluginSettings);
|
||||
setObjectName("SystemTray");
|
||||
}
|
||||
|
||||
void SystemTraysController::itemAdded(PluginsItemInterface * const itemInter, const QString &itemKey)
|
||||
{
|
||||
auto 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);
|
||||
auto mPluginsMap = pluginsMap();
|
||||
mPluginsMap[itemInter].remove(itemKey);
|
||||
|
||||
// do not delete the itemWidget object(specified in the plugin interface)
|
||||
item->centralWidget()->setParent(nullptr);
|
||||
@ -87,24 +83,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));
|
||||
@ -113,135 +112,11 @@ void SystemTraysController::requestSetAppletVisible(PluginsItemInterface * const
|
||||
}
|
||||
}
|
||||
|
||||
void SystemTraysController::startLoader()
|
||||
PluginsItemInterface *SystemTraysController::pluginInterAt(const QString &itemKey)
|
||||
{
|
||||
SystemTrayLoader *loader = new SystemTrayLoader(this);
|
||||
auto mPluginsMap = pluginsMap();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void SystemTraysController::refreshPluginSettings(qlonglong ts)
|
||||
{
|
||||
// TODO: handle nano seconds
|
||||
|
||||
const QString &pluginSettings = m_dockDaemonInter->GetPluginSettings().value();
|
||||
if (pluginSettings.isEmpty()) {
|
||||
qDebug() << "Error! get plugin settings from dbus failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
const QJsonObject &settingsObject = QJsonDocument::fromJson(pluginSettings.toLocal8Bit()).object();
|
||||
if (settingsObject.isEmpty()) {
|
||||
qDebug() << "Error! parse plugin settings from json failed!";
|
||||
return;
|
||||
}
|
||||
|
||||
m_pluginSettingsObject = settingsObject;
|
||||
|
||||
// not notify plugins to refresh settings if this update is not emit by dock daemon
|
||||
if (sender() != m_dockDaemonInter) {
|
||||
return;
|
||||
}
|
||||
|
||||
// static_cast<DockDaemonInter *>(sender())
|
||||
// TODO: notify all plugins to reload plugin settings
|
||||
}
|
||||
|
||||
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 it = mPluginsMap.constBegin(); it != mPluginsMap.constEnd(); ++it) {
|
||||
for (auto key : it.value().keys()) {
|
||||
if (key == itemKey) {
|
||||
return it.key();
|
||||
@ -252,9 +127,11 @@ PluginsItemInterface *SystemTraysController::pluginInterAt(const QString &itemKe
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PluginsItemInterface *SystemTraysController::pluginInterAt(SystemTrayItem *systemTrayItem) const
|
||||
PluginsItemInterface *SystemTraysController::pluginInterAt(SystemTrayItem *systemTrayItem)
|
||||
{
|
||||
for (auto it = m_pluginsMap.constBegin(); it != m_pluginsMap.constEnd(); ++it) {
|
||||
auto mPluginsMap = pluginsMap();
|
||||
|
||||
for (auto it = mPluginsMap.constBegin(); it != mPluginsMap.constEnd(); ++it) {
|
||||
for (auto item : it.value().values()) {
|
||||
if (item == systemTrayItem) {
|
||||
return it.key();
|
||||
@ -265,24 +142,6 @@ PluginsItemInterface *SystemTraysController::pluginInterAt(SystemTrayItem *syste
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SystemTraysController::saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) {
|
||||
QJsonObject valueObject = m_pluginSettingsObject.value(itemInter->pluginName()).toObject();
|
||||
valueObject.insert(key, value.toJsonValue());
|
||||
m_pluginSettingsObject.insert(itemInter->pluginName(), valueObject);
|
||||
|
||||
m_dockDaemonInter->SetPluginSettings(
|
||||
QDateTime::currentMSecsSinceEpoch() / 1000 / 1000,
|
||||
QJsonDocument(m_pluginSettingsObject).toJson());
|
||||
}
|
||||
|
||||
const QVariant SystemTraysController::getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback) {
|
||||
QVariant v = m_pluginSettingsObject.value(itemInter->pluginName()).toObject().value(key).toVariant();
|
||||
if (v.isNull() || !v.isValid()) {
|
||||
v = fallback;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
int SystemTraysController::systemTrayItemSortKey(const QString &itemKey)
|
||||
{
|
||||
auto inter = pluginInterAt(itemKey);
|
||||
@ -326,3 +185,14 @@ void SystemTraysController::saveValueSystemTrayItem(const QString &itemKey, cons
|
||||
|
||||
saveValue(inter, key, value);
|
||||
}
|
||||
|
||||
void SystemTraysController::startLoader()
|
||||
{
|
||||
#ifdef QT_DEBUG
|
||||
const QString pluginsDir("../plugins/system-trays");
|
||||
#else
|
||||
const QString pluginsDir("../lib/dde-dock/plugins/system-trays");
|
||||
#endif
|
||||
|
||||
AbstractPluginsController::startLoader(new PluginLoader(pluginsDir, this));
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "systemtrayitem.h"
|
||||
#include "pluginproxyinterface.h"
|
||||
#include "util/abstractpluginscontroller.h"
|
||||
|
||||
#include <com_deepin_dde_daemon_dock.h>
|
||||
|
||||
@ -35,7 +36,7 @@
|
||||
using DockDaemonInter = com::deepin::dde::daemon::Dock;
|
||||
|
||||
class PluginsItemInterface;
|
||||
class SystemTraysController : public QObject, PluginProxyInterface
|
||||
class SystemTraysController : public AbstractPluginsController
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@ -49,8 +50,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);
|
||||
@ -58,33 +57,16 @@ 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);
|
||||
void refreshPluginSettings(qlonglong ts);
|
||||
void pluginItemAdded(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
|
||||
void pluginItemRemoved(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
|
||||
void pluginItemUpdated(const QString &itemKey, AbstractTrayWidget *pluginItem) const;
|
||||
|
||||
private:
|
||||
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;
|
||||
DockDaemonInter *m_dockDaemonInter;
|
||||
|
||||
QJsonObject m_pluginSettingsObject;
|
||||
PluginsItemInterface *pluginInterAt(const QString &itemKey);
|
||||
PluginsItemInterface *pluginInterAt(SystemTrayItem *systemTrayItem);
|
||||
};
|
||||
|
||||
#endif // SYSTEMTRAYSCONTROLLER_H
|
||||
|
@ -96,8 +96,9 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
|
||||
connect(m_trayInter, &DBusTrayManager::TrayIconsChanged, this, &TrayPlugin::trayListChanged);
|
||||
connect(m_trayInter, &DBusTrayManager::Changed, this, &TrayPlugin::trayChanged);
|
||||
|
||||
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, AbstractTrayWidget *pluginItem) { Q_UNUSED(pluginItem); trayRemoved(itemKey); });
|
||||
|
||||
m_trayInter->Manage();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user