diff --git a/frame/controller/dockitemmanager.cpp b/frame/controller/dockitemmanager.cpp index 8a83ce2d6..3aa7ba612 100644 --- a/frame/controller/dockitemmanager.cpp +++ b/frame/controller/dockitemmanager.cpp @@ -27,6 +27,7 @@ #include "utils.h" #include "appmultiitem.h" #include "quicksettingcontroller.h" +#include "proxyplugincontroller.h" #include #include @@ -68,6 +69,18 @@ DockItemManager::DockItemManager(QObject *parent) } // 托盘区域和插件区域 由DockPluginsController获取 + QuickSettingController *quickController = QuickSettingController::instance(); + connect(quickController, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginAttr) { + if (pluginAttr != QuickSettingController::PluginAttribute::Fixed) + return; + + m_pluginItems << itemInter; + pluginItemInserted(quickController->pluginItemWidget(itemInter)); + }); + + 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(m_appInter, &DockInter::EntryAdded, this, &DockItemManager::appItemAdded); @@ -84,6 +97,13 @@ DockItemManager::DockItemManager(QObject *parent) connect(qApp, &QApplication::aboutToQuit, this, &QObject::deleteLater); + // 读取已经加载的固定区域插件 + QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Fixed); + for (PluginsItemInterface *plugin : plugins) { + m_pluginItems << plugin; + pluginItemInserted(quickController->pluginItemWidget(plugin)); + } + // 刷新图标 QMetaObject::invokeMethod(this, "refreshItemsIcon", Qt::QueuedConnection); } @@ -101,11 +121,6 @@ const QList> DockItemManager::itemList() const return m_itemList; } -const QList DockItemManager::pluginList() const -{ - return QuickSettingController::instance()->pluginsMap().keys(); -} - bool DockItemManager::appIsOnDock(const QString &appDesktop) const { return m_appInter->IsOnDock(appDesktop); @@ -279,6 +294,88 @@ void DockItemManager::manageItem(DockItem *item) connect(item, &DockItem::requestWindowAutoHide, this, &DockItemManager::requestWindowAutoHide, Qt::UniqueConnection); } +void DockItemManager::pluginItemInserted(PluginsItem *item) +{ + manageItem(item); + + DockItem::ItemType pluginType = item->itemType(); + + // find first plugins item position + int firstPluginPosition = -1; + for (int i(0); i != m_itemList.size(); ++i) { + DockItem::ItemType type = m_itemList[i]->itemType(); + if (type != pluginType) + continue; + + firstPluginPosition = i; + break; + } + + if (firstPluginPosition == -1) + firstPluginPosition = m_itemList.size(); + + // find insert position + int insertIndex = 0; + const int itemSortKey = item->itemSortKey(); + if (itemSortKey == -1 || firstPluginPosition == -1) { + insertIndex = m_itemList.size(); + } else if (itemSortKey == 0) { + insertIndex = firstPluginPosition; + } else { + insertIndex = m_itemList.size(); + for (int i(firstPluginPosition + 1); i != m_itemList.size() + 1; ++i) { + PluginsItem *pItem = static_cast(m_itemList[i - 1].data()); + Q_ASSERT(pItem); + + const int sortKey = pItem->itemSortKey(); + if (pluginType == DockItem::FixedPlugin) { + if (sortKey != -1 && itemSortKey > sortKey) + continue; + insertIndex = i - 1; + break; + } + if (sortKey != -1 && itemSortKey > sortKey && pItem->itemType() != DockItem::FixedPlugin) + continue; + insertIndex = i - 1; + break; + } + } + + m_itemList.insert(insertIndex, item); + if(pluginType == DockItem::FixedPlugin) + insertIndex ++; + + if (!Utils::SettingValue(QString("com.deepin.dde.dock.module.") + item->pluginName(), QByteArray(), "enable", true).toBool()) + item->setVisible(false); + + emit itemInserted(insertIndex - firstPluginPosition, item); +} + +void DockItemManager::onPluginItemRemoved(PluginsItemInterface *itemInter) +{ + if (!m_pluginItems.contains(itemInter)) + return; + + PluginsItem *item = QuickSettingController::instance()->pluginItemWidget(itemInter); + item->hidePopup(); + + emit itemRemoved(item); + + m_itemList.removeOne(item); + + if (m_loadFinished) { + updatePluginsItemOrderKey(); + } +} + +void DockItemManager::onPluginUpdate(PluginsItemInterface *itemInter) +{ + if (!m_pluginItems.contains(itemInter)) + return; + + Q_EMIT itemUpdated(QuickSettingController::instance()->pluginItemWidget(itemInter)); +} + void DockItemManager::onPluginLoadFinished() { updatePluginsItemOrderKey(); diff --git a/frame/controller/dockitemmanager.h b/frame/controller/dockitemmanager.h index 41bc952cb..dad07c475 100644 --- a/frame/controller/dockitemmanager.h +++ b/frame/controller/dockitemmanager.h @@ -31,6 +31,8 @@ #include class AppMultiItem; +class PluginsItem; + /** * @brief The DockItemManager class * 管理类,管理所有的应用数据,插件数据 @@ -43,7 +45,6 @@ public: static DockItemManager *instance(QObject *parent = nullptr); const QList > itemList() const; - const QList pluginList() const; bool appIsOnDock(const QString &appDesktop) const; signals: @@ -63,6 +64,8 @@ public slots: private Q_SLOTS: void onPluginLoadFinished(); + void onPluginItemRemoved(PluginsItemInterface *itemInter); + void onPluginUpdate(PluginsItemInterface *itemInter); #ifdef USE_AM void onAppWindowCountChanged(); @@ -77,6 +80,7 @@ private: void updatePluginsItemOrderKey(); void reloadAppItems(); void manageItem(DockItem *item); + void pluginItemInserted(PluginsItem *item); #ifdef USE_AM void updateMultiItems(AppItem *appItem, bool emitSignal = false); @@ -91,6 +95,7 @@ private: QList> m_itemList; QList m_appIDist; + QList m_pluginItems; bool m_loadFinished; // 记录所有插件是否加载完成 diff --git a/frame/controller/proxyplugincontroller.cpp b/frame/controller/proxyplugincontroller.cpp index 70b0cead3..f8a434188 100644 --- a/frame/controller/proxyplugincontroller.cpp +++ b/frame/controller/proxyplugincontroller.cpp @@ -144,11 +144,6 @@ QPluginLoader *ProxyPluginController::pluginLoader(PluginsItemInterface * const return nullptr; } -QList ProxyPluginController::pluginsItems() const -{ - return m_pluginsItems; -} - QString ProxyPluginController::itemKey(PluginsItemInterface *itemInter) const { if (m_pluginsItemKeys.contains(itemInter)) diff --git a/frame/controller/proxyplugincontroller.h b/frame/controller/proxyplugincontroller.h index 906575466..e52f738bb 100644 --- a/frame/controller/proxyplugincontroller.h +++ b/frame/controller/proxyplugincontroller.h @@ -40,12 +40,11 @@ class ProxyPluginController : public AbstractPluginsController Q_OBJECT public: - static ProxyPluginController *instance(PluginType instanceKey); + 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); - QList pluginsItems() const; QString itemKey(PluginsItemInterface *itemInter) const; protected: diff --git a/frame/controller/quicksettingcontroller.cpp b/frame/controller/quicksettingcontroller.cpp index bec1ba079..7c72f6a42 100644 --- a/frame/controller/quicksettingcontroller.cpp +++ b/frame/controller/quicksettingcontroller.cpp @@ -39,20 +39,7 @@ QuickSettingController::~QuickSettingController() void QuickSettingController::pluginItemAdded(PluginsItemInterface * const itemInter, const QString &itemKey) { // 根据读取到的metaData数据获取当前插件的类型,提供给外部 - PluginAttribute pluginClass = PluginAttribute::Quick; - QPluginLoader *pluginLoader = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginLoader(itemInter); - if (pluginLoader) { - if (pluginLoader->fileName().contains("/plugins/system-trays")) { - // 如果是从系统托盘目录下加载的插件,则认为它是托盘插件,此时需要放入到托盘中 - pluginClass = PluginAttribute::System; - } else { - QJsonObject meta = pluginLoader->metaData().value("MetaData").toObject(); - if (meta.contains("tool") && meta.value("tool").toBool()) - pluginClass = PluginAttribute::Tool; - else if (meta.contains("fixed") && meta.value("fixed").toBool()) - pluginClass = PluginAttribute::Fixed; - } - } + PluginAttribute pluginClass = getPluginClass(itemInter); m_quickPlugins[pluginClass] << itemInter; m_quickPluginsMap[itemInter] = itemKey; @@ -85,6 +72,37 @@ void QuickSettingController::updateDockInfo(PluginsItemInterface * const itemInt Q_EMIT pluginUpdated(itemInter, part); } +QuickSettingController::PluginAttribute QuickSettingController::getPluginClass(PluginsItemInterface * const itemInter) const +{ + QPluginLoader *pluginLoader = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginLoader(itemInter); + if (!pluginLoader) + return PluginAttribute::Quick; + + if (pluginLoader->fileName().contains("/plugins/system-trays")) { + // 如果是从系统目录下加载的插件,则认为它是系统插件,此时需要放入到托盘中 + return PluginAttribute::Tray; + } + + QJsonObject meta = pluginLoader->metaData().value("MetaData").toObject(); + if (meta.contains("tool") && meta.value("tool").toBool()) { + // 如果有tool标记,则认为它是工具插件,例如回收站和窗管提供的相关插件 + return PluginAttribute::Tool; + } + + if (meta.contains("system") && meta.value("system").toBool()) { + // 如果有system标记,则认为它是右侧的关机按钮插件 + return PluginAttribute::System; + } + + if (meta.contains("fixed") && meta.value("fixed").toBool()) { + // 如果有fixed标记,则认为它是固定区域的插件,例如显示桌面和多任务视图 + return PluginAttribute::Fixed; + } + + // 其他的都认为是快捷插件 + return PluginAttribute::Quick; +} + QuickSettingController *QuickSettingController::instance() { static QuickSettingController instance; @@ -119,3 +137,20 @@ PluginsItem *QuickSettingController::pluginItemWidget(PluginsItemInterface *plug m_pluginItemWidgetMap[pluginItem] = widget; return widget; } + +QList QuickSettingController::pluginInSettings() +{ + QList settingPlugins; + // 用于在控制中心显示可改变位置的插件,这里只提供 + QMap> &plugins = ProxyPluginController::instance(PluginType::QuickPlugin)->pluginsMap(); + QList allPlugins = plugins.keys(); + for (PluginsItemInterface *plugin : allPlugins) { + PluginAttribute pluginClass = getPluginClass(plugin); + if (pluginClass == QuickSettingController::PluginAttribute::Quick + || pluginClass == QuickSettingController::PluginAttribute::System + || pluginClass == QuickSettingController::PluginAttribute::Tool) + settingPlugins << plugin; + } + + return settingPlugins; +} diff --git a/frame/controller/quicksettingcontroller.h b/frame/controller/quicksettingcontroller.h index 142b37081..63336d5e9 100644 --- a/frame/controller/quicksettingcontroller.h +++ b/frame/controller/quicksettingcontroller.h @@ -32,10 +32,11 @@ class QuickSettingController : public AbstractPluginsController public: enum class PluginAttribute { - Quick = 0, - Tool, - Fixed, - System + Quick = 0, // 快捷区域插件 + Tool, // 工具插件(回收站和窗管开发的另一套插件) + System, // 系统插件(关机插件) + Tray, // 托盘插件(U盘图标等) + Fixed // 固定区域插件(显示桌面和多任务视图) }; public: @@ -44,6 +45,7 @@ public: QString itemKey(PluginsItemInterface *pluginItem) const; QJsonObject metaData(PluginsItemInterface *pluginItem) const; PluginsItem *pluginItemWidget(PluginsItemInterface *pluginItem); + QList pluginInSettings(); Q_SIGNALS: void pluginInserted(PluginsItemInterface *itemInter, const PluginAttribute &); @@ -64,6 +66,9 @@ protected: void updateDockInfo(PluginsItemInterface * const itemInter, const DockPart &part) override; +private: + PluginAttribute getPluginClass(PluginsItemInterface * const itemInter) const; + private: QMap> m_quickPlugins; QMap m_quickPluginsMap; diff --git a/frame/dbus/dbusdockadaptors.cpp b/frame/dbus/dbusdockadaptors.cpp index 6cc8b2102..c85a6ecd5 100644 --- a/frame/dbus/dbusdockadaptors.cpp +++ b/frame/dbus/dbusdockadaptors.cpp @@ -24,6 +24,7 @@ #include "dockitemmanager.h" #include "windowmanager.h" #include "proxyplugincontroller.h" +#include "quicksettingcontroller.h" #include "pluginsitem.h" #include @@ -47,12 +48,13 @@ DBusDockAdaptors::DBusDockAdaptors(WindowManager* parent) }); } + QList allPlugin = plugins(); connect(DockItemManager::instance(), &DockItemManager::itemInserted, this, [ = ] (const int index, DockItem *item) { Q_UNUSED(index); if (item->itemType() == DockItem::Plugins || item->itemType() == DockItem::FixedPlugin) { PluginsItem *pluginItem = static_cast(item); - for (auto *p : DockItemManager::instance()->pluginList()) { + for (auto *p : allPlugin) { if (p->pluginName() == pluginItem->pluginName()) { Q_EMIT pluginVisibleChanged(p->pluginDisplayName(), getPluginVisible(p->pluginDisplayName())); } @@ -64,7 +66,7 @@ DBusDockAdaptors::DBusDockAdaptors(WindowManager* parent) if (item->itemType() == DockItem::Plugins || item->itemType() == DockItem::FixedPlugin) { PluginsItem *pluginItem = static_cast(item); - for (auto *p : DockItemManager::instance()->pluginList()) { + for (auto *p : allPlugin) { if (p->pluginName() == pluginItem->pluginName()) { Q_EMIT pluginVisibleChanged(p->pluginDisplayName(), getPluginVisible(p->pluginDisplayName())); } @@ -99,10 +101,10 @@ void DBusDockAdaptors::ReloadPlugins() QStringList DBusDockAdaptors::GetLoadedPlugins() { - auto pluginList = DockItemManager::instance()->pluginList(); + QList allPlugin = plugins(); QStringList nameList; QMap map; - for (auto plugin : pluginList) { + for (auto plugin : allPlugin) { // 托盘本身也是一个插件,这里去除掉这个特殊的插件,还有一些没有实际名字的插件 if (plugin->pluginName() == "tray" || plugin->pluginDisplayName().isEmpty() @@ -134,7 +136,8 @@ void DBusDockAdaptors::resizeDock(int offset, bool dragging) // 返回每个插件的识别Key(所以此值应始终不变),供个性化插件根据key去匹配每个插件对应的图标 QString DBusDockAdaptors::getPluginKey(const QString &pluginName) { - for (auto plugin : DockItemManager::instance()->pluginList()) { + QList allPlugin = plugins(); + for (auto plugin : allPlugin) { if (plugin->pluginDisplayName() == pluginName) return plugin->pluginName(); } @@ -144,7 +147,8 @@ QString DBusDockAdaptors::getPluginKey(const QString &pluginName) bool DBusDockAdaptors::getPluginVisible(const QString &pluginName) { - for (auto *p : DockItemManager::instance()->pluginList()) { + QList allPlugin = plugins(); + for (auto *p : allPlugin) { if (!p->pluginIsAllowDisable()) continue; @@ -165,7 +169,8 @@ bool DBusDockAdaptors::getPluginVisible(const QString &pluginName) void DBusDockAdaptors::setPluginVisible(const QString &pluginName, bool visible) { - for (auto *p : DockItemManager::instance()->pluginList()) { + QList allPlugin = plugins(); + for (auto *p : allPlugin) { if (!p->pluginIsAllowDisable()) continue; @@ -223,3 +228,8 @@ bool DBusDockAdaptors::isPluginValid(const QString &name) return true; } + +QList DBusDockAdaptors::plugins() const +{ + return QuickSettingController::instance()->pluginInSettings(); +} diff --git a/frame/dbus/dbusdockadaptors.h b/frame/dbus/dbusdockadaptors.h index 2d0575ce9..d3188235a 100644 --- a/frame/dbus/dbusdockadaptors.h +++ b/frame/dbus/dbusdockadaptors.h @@ -31,6 +31,7 @@ */ class QGSettings; class WindowManager; +class PluginsItemInterface; class DBusDockAdaptors: public QDBusAbstractAdaptor { @@ -100,6 +101,7 @@ signals: private: bool isPluginValid(const QString &name); + QList plugins() const; private: QGSettings *m_gsettings; diff --git a/frame/window/quicksettingcontainer.cpp b/frame/window/quicksettingcontainer.cpp index 2d7e36fed..f241080d5 100644 --- a/frame/window/quicksettingcontainer.cpp +++ b/frame/window/quicksettingcontainer.cpp @@ -203,6 +203,8 @@ void QuickSettingContainer::onPluginRemove(PluginsItemInterface * itemInter) if (!quickItem) return; + m_pluginLayout->removeWidget(quickItem); + m_quickSettings.removeOne(quickItem); disconnect(quickItem, &QuickSettingItem::detailClicked, this, &QuickSettingContainer::onItemDetailClick); quickItem->setParent(nullptr); quickItem->removeEventFilter(this); diff --git a/frame/window/systempluginwindow.cpp b/frame/window/systempluginwindow.cpp index 6f67873b0..bfa651fdc 100644 --- a/frame/window/systempluginwindow.cpp +++ b/frame/window/systempluginwindow.cpp @@ -126,8 +126,8 @@ void SystemPluginWindow::initUi() void SystemPluginWindow::initConnection() { QuickSettingController *quickController = QuickSettingController::instance(); - connect(quickController, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginClass) { - if (pluginClass != QuickSettingController::PluginAttribute::Fixed) + connect(quickController, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginAttr) { + if (pluginAttr != QuickSettingController::PluginAttribute::System) return; pluginAdded(itemInter); @@ -136,7 +136,7 @@ void SystemPluginWindow::initConnection() connect(quickController, &QuickSettingController::pluginRemoved, this, &SystemPluginWindow::onPluginItemRemoved); connect(quickController, &QuickSettingController::pluginUpdated, this, &SystemPluginWindow::onPluginItemUpdated); - QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Fixed); + QList plugins = quickController->pluginItems(QuickSettingController::PluginAttribute::System); for (int i = 0; i < plugins.size(); i++) pluginAdded(plugins[i]); } diff --git a/frame/window/tray/tray_model.cpp b/frame/window/tray/tray_model.cpp index d7e4755be..c0db86d71 100644 --- a/frame/window/tray/tray_model.cpp +++ b/frame/window/tray/tray_model.cpp @@ -48,17 +48,19 @@ TrayModel::TrayModel(QListView *view, bool isIconTray, bool hasInputMethod, QObj if (isIconTray) { connect(m_monitor, &TrayMonitor::xEmbedTrayAdded, this, &TrayModel::onXEmbedTrayAdded); connect(m_monitor, &TrayMonitor::indicatorFounded, this, &TrayModel::onIndicatorFounded); - connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginAttr) { - if (pluginAttr != QuickSettingController::PluginAttribute::System) + + QuickSettingController *quickController = QuickSettingController::instance(); + connect(quickController, &QuickSettingController::pluginInserted, this, [ = ](PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute &pluginAttr) { + if (pluginAttr != QuickSettingController::PluginAttribute::Tray) return; systemItemAdded(itemInter); }); - connect(QuickSettingController::instance(), &QuickSettingController::pluginRemoved, this, &TrayModel::onSystemItemRemoved); + connect(quickController, &QuickSettingController::pluginRemoved, this, &TrayModel::onSystemItemRemoved); QMetaObject::invokeMethod(this, [ = ] { - QList systemPlugins = QuickSettingController::instance()->pluginItems(QuickSettingController::PluginAttribute::System); - for (PluginsItemInterface *plugin : systemPlugins) + QList trayPlugins = quickController->pluginItems(QuickSettingController::PluginAttribute::Tray); + for (PluginsItemInterface *plugin : trayPlugins) systemItemAdded(plugin); }, Qt::QueuedConnection); } diff --git a/frame/window/tray/widgets/snitrayitemwidget.cpp b/frame/window/tray/widgets/snitrayitemwidget.cpp index a93215a21..e21befa84 100644 --- a/frame/window/tray/widgets/snitrayitemwidget.cpp +++ b/frame/window/tray/widgets/snitrayitemwidget.cpp @@ -151,6 +151,23 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par connect(m_sniInter, &StatusNotifierItem::NewStatus, [ = ] { onSNIStatusChanged(m_sniInter->status()); }); + + QMetaObject::invokeMethod(this, [ this ] { + m_sniIconName = m_sniInter->iconName(); + m_sniIconPixmap = m_sniInter->iconPixmap(); + m_sniIconThemePath = m_sniInter->iconThemePath(); + m_updateIconTimer->start(); + + m_sniOverlayIconName = m_sniInter->overlayIconName(); + m_sniOverlayIconPixmap = m_sniInter->overlayIconPixmap(); + m_sniIconThemePath = m_sniInter->iconThemePath(); + m_updateOverlayIconTimer->start(); + + m_sniAttentionIconName = m_sniInter->attentionIconName(); + m_sniAttentionIconPixmap = m_sniInter->attentionIconPixmap(); + m_sniIconThemePath = m_sniInter->iconThemePath(); + m_updateAttentionIconTimer->start(); + }, Qt::QueuedConnection); } QString SNITrayItemWidget::itemKeyForConfig() diff --git a/plugins/multitasking/multitasking.json b/plugins/multitasking/multitasking.json index bec81f0da..cdda5b480 100644 --- a/plugins/multitasking/multitasking.json +++ b/plugins/multitasking/multitasking.json @@ -1,3 +1,4 @@ { - "api": "2.0.0" + "api": "2.0.0", + "fixed": true } diff --git a/plugins/show-desktop/show-desktop.json b/plugins/show-desktop/show-desktop.json index bec81f0da..cdda5b480 100644 --- a/plugins/show-desktop/show-desktop.json +++ b/plugins/show-desktop/show-desktop.json @@ -1,3 +1,4 @@ { - "api": "2.0.0" + "api": "2.0.0", + "fixed": true } diff --git a/plugins/shutdown/shutdown.json b/plugins/shutdown/shutdown.json index cdda5b480..a1a7e7292 100644 --- a/plugins/shutdown/shutdown.json +++ b/plugins/shutdown/shutdown.json @@ -1,4 +1,4 @@ { "api": "2.0.0", - "fixed": true + "system": true }