From 4feea73186dcb8ebf5e48cd75b69c315d5d42c63 Mon Sep 17 00:00:00 2001 From: wjyrich Date: Thu, 30 Jul 2026 10:34:47 +0800 Subject: [PATCH] feat: add plugin interaction config for tray plugins MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Added a new DConfig-based configuration module `PluginInteractionConfig` that controls plugin item interactions 2. Supports three configurable items: itemActivationEnabled, itemContextMenuEnabled, and itemTooltipEnabled 3. Each plugin can have its own per-plugin configuration using subpath identifiers 4. Integrated the interaction config into PluginItem to conditionally disable popup, context menu, tooltip, and command execution 5. Updated CMakeLists.txt to include Dtk::Core dependency and install the new config meta file Log: Added plugin interaction configuration for tray plugins to control activation, context menu, and tooltip features Influence: 1. Test that plugin item popup applet is blocked when itemActivationEnabled is false 2. Test that plugin context menu is hidden when itemContextMenuEnabled is false 3. Test that tooltip is not shown when itemTooltipEnabled is false 4. Verify that command execution is prevented when itemActivationEnabled is false 5. Test dynamic config changes: enabling/disabling features should take effect immediately 6. Verify per-plugin configuration isolation works correctly 7. Test with plugins that have quick items to ensure they are excluded 8. Verify that invalid DConfig falls back to all features enabled feat: 为托盘插件添加交互配置控制 1. 新增基于 DConfig 的配置模块 `PluginInteractionConfig`,用于控制插件项 交互 2. 支持三个可配置项:itemActivationEnabled、itemContextMenuEnabled 和 itemTooltipEnabled 3. 每个插件可以使用子路径标识符拥有独立的配置 4. 将交互配置集成到 PluginItem 中,根据配置条件性地禁用弹出窗口、上下文 菜单、悬浮提示和命令执行 5. 更新 CMakeLists.txt,添加 Dtk::Core 依赖并安装新的配置元文件 Log: 新增托盘插件交互配置功能,可独立控制插件的激活、上下文菜单和悬浮提 示特性 Influence: 1. 测试当 itemActivationEnabled 为 false 时,插件项弹出窗口被阻止 2. 测试当 itemContextMenuEnabled 为 false 时,插件上下文菜单被隐藏 3. 测试当 itemTooltipEnabled 为 false 时,悬浮提示不显示 4. 验证当 itemActivationEnabled 为 false 时,命令执行被阻止 5. 测试动态配置变更:启用/禁用功能应即时生效 6. 验证每个插件的配置隔离正常工作 7. 测试快捷项插件以确保它们被排除在外 8. 验证无效 DConfig 时回退为所有功能启用 PMS: TASK-393299 --- src/loader/CMakeLists.txt | 14 +++++- ...rg.deepin.dde.dock.plugin.interaction.json | 39 +++++++++++++++ src/loader/pluginitem.cpp | 50 +++++++++++++++++++ src/loader/pluginitem.h | 4 +- 4 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/loader/configs/org.deepin.dde.dock.plugin.interaction.json diff --git a/src/loader/CMakeLists.txt b/src/loader/CMakeLists.txt index fd396f518..24c6117fa 100644 --- a/src/loader/CMakeLists.txt +++ b/src/loader/CMakeLists.txt @@ -3,7 +3,7 @@ # SPDX-License-Identifier: CC0-1.0 find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Core Widgets LinguistTools) -find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED COMPONENTS Gui Widget) +find_package(Dtk${DTK_VERSION_MAJOR} REQUIRED COMPONENTS Core Gui Widget Tools) file(GLOB SRCS "*.h" "*.cpp" "../../interfaces/*.h" "utils/*.h" "utils/*.cpp") @@ -11,6 +11,15 @@ file(GLOB TS_FILES "translations/*.ts") qt_add_translation(QM_FILES ${TS_FILES}) add_custom_target(trayloader_translations ALL DEPENDS ${QM_FILES}) +set(PLUGIN_INTERACTION_CONFIG_META_FILE + "${CMAKE_CURRENT_SOURCE_DIR}/configs/org.deepin.dde.dock.plugin.interaction.json") +dtk_add_config_to_cpp( + PLUGIN_INTERACTION_CONFIG_HEADER + "${PLUGIN_INTERACTION_CONFIG_META_FILE}" + OUTPUT_FILE_NAME plugininteractionconfig.h + CLASS_NAME PluginInteractionConfig +) + add_executable(trayplugin-loader main.cpp dockdbusproxy.cpp @@ -19,6 +28,7 @@ add_executable(trayplugin-loader widgetplugin.cpp pluginitem.h pluginitem.cpp + "${PLUGIN_INTERACTION_CONFIG_HEADER}" quickpluginitem.h quickpluginitem.cpp utils/setproctitle.h @@ -43,6 +53,7 @@ target_link_libraries(trayplugin-loader PRIVATE dockpluginmanager-interface Qt${QT_VERSION_MAJOR}::Core Qt${QT_VERSION_MAJOR}::Widgets + Dtk${DTK_VERSION_MAJOR}::Core Dtk${DTK_VERSION_MAJOR}::Widget Dtk${DTK_VERSION_MAJOR}::Gui ) @@ -52,6 +63,7 @@ install(TARGETS trayplugin-loader DESTINATION ${CMAKE_INSTALL_LIBEXECDIR}) #dconfig dtk_add_config_meta_files(APPID org.deepin.dde.dock FILES ./configs/org.deepin.dde.dock.plugin.common.json) # compat dtk_add_config_meta_files(APPID org.deepin.dde.tray-loader FILES ./configs/org.deepin.dde.dock.plugin.common.json) +dtk_add_config_meta_files(APPID org.deepin.dde.tray-loader FILES "${PLUGIN_INTERACTION_CONFIG_META_FILE}") # 安装 .qm 文件 install(FILES ${QM_FILES} DESTINATION ${CMAKE_INSTALL_DATADIR}/trayplugin-loader/translations) diff --git a/src/loader/configs/org.deepin.dde.dock.plugin.interaction.json b/src/loader/configs/org.deepin.dde.dock.plugin.interaction.json new file mode 100644 index 000000000..4148a9fae --- /dev/null +++ b/src/loader/configs/org.deepin.dde.dock.plugin.interaction.json @@ -0,0 +1,39 @@ +{ + "magic": "dsg.config.meta", + "version": "1.0", + "contents": { + "itemActivationEnabled": { + "value": true, + "serial": 0, + "flags": [], + "name": "Enable plugin item activation", + "name[zh_CN]": "允许激活插件项", + "description": "Whether the tray loader may invoke itemCommand and itemPopupApplet for the taskbar items provided by this plugin.", + "description[zh_CN]": "是否允许任务栏加载器调用此插件在任务栏中各插件项的 itemCommand 和 itemPopupApplet 接口。", + "permissions": "readwrite", + "visibility": "private" + }, + "itemContextMenuEnabled": { + "value": true, + "serial": 0, + "flags": [], + "name": "Enable plugin item context menu", + "name[zh_CN]": "允许插件项上下文菜单", + "description": "Whether the tray loader may invoke itemContextMenu and display framework-provided context menu actions for the taskbar items provided by this plugin.", + "description[zh_CN]": "是否允许任务栏加载器调用此插件在任务栏中各插件项的 itemContextMenu 接口,并显示任务栏提供的驻留或移除驻留菜单。", + "permissions": "readwrite", + "visibility": "private" + }, + "itemTooltipEnabled": { + "value": true, + "serial": 0, + "flags": [], + "name": "Enable plugin item tooltip", + "name[zh_CN]": "允许插件项悬浮提示", + "description": "Whether the tray loader may invoke itemTipsWidget and display tooltips for the taskbar items provided by this plugin.", + "description[zh_CN]": "是否允许任务栏加载器调用此插件在任务栏中各插件项的 itemTipsWidget 接口并显示悬浮提示。", + "permissions": "readwrite", + "visibility": "private" + } + } +} diff --git a/src/loader/pluginitem.cpp b/src/loader/pluginitem.cpp index 53b3a2707..2b61bcb80 100644 --- a/src/loader/pluginitem.cpp +++ b/src/loader/pluginitem.cpp @@ -7,6 +7,7 @@ #include "plugin.h" #include "widgetplugin.h" #include "dockcontextmenu.h" +#include "plugininteractionconfig.h" #include @@ -16,9 +17,19 @@ #include #include #include +#include const static QString DockQuickPlugins = "Dock_Quick_Plugins"; +namespace { +constexpr auto PluginInteractionConfigAppId = "org.deepin.dde.tray-loader"; + +QString pluginInteractionConfigSubpath(const QString &pluginId) +{ + return QStringLiteral("/%1").arg(QString::fromLatin1(QUrl::toPercentEncoding(pluginId))); +} +} + PluginItem::PluginItem(PluginsItemInterface *pluginItemInterface, const QString &itemKey, QWidget *parent) : QWidget(parent) , m_itemKey(itemKey) @@ -69,6 +80,9 @@ PluginItem::~PluginItem() QWidget *PluginItem::itemPopupApplet() { + if (m_interactionConfig && !m_interactionConfig->itemActivationEnabled()) + return nullptr; + if (auto popup = m_pluginsItemInterface->itemPopupApplet(m_itemKey)) { bool existed = panelPopupExisted(); bool embed = embedPanelPopupExisted(); @@ -101,6 +115,9 @@ QWidget *PluginItem::itemPopupApplet() QMenu *PluginItem::pluginContextMenu() { + if (m_interactionConfig && !m_interactionConfig->itemContextMenuEnabled()) + return nullptr; + if (!m_menu->actions().isEmpty()) { m_menu->clear(); } @@ -291,6 +308,27 @@ void PluginItem::handleShutDownMenu(const QString &menuId) void PluginItem::init() { + if (itemKey() != Dock::QUICK_ITEM_KEY && !m_interactionConfig) { + m_interactionConfig = PluginInteractionConfig::create( + QLatin1String(PluginInteractionConfigAppId), + pluginInteractionConfigSubpath(pluginId()), + this); + connect(m_interactionConfig, + &PluginInteractionConfig::itemContextMenuEnabledChanged, + this, + [this] { + if (!m_interactionConfig->itemContextMenuEnabled()) + m_menu->close(); + }); + connect(m_interactionConfig, + &PluginInteractionConfig::itemTooltipEnabledChanged, + this, + [this] { + if (!m_interactionConfig->itemTooltipEnabled()) + closeToolTip(); + }); + } + setAttribute(Qt::WA_TranslucentBackground); winId(); @@ -305,6 +343,9 @@ void PluginItem::init() void PluginItem::initPluginMenu() { + if (m_interactionConfig && !m_interactionConfig->itemContextMenuEnabled()) + return; + const QString menuJson = m_pluginsItemInterface->itemContextMenu(m_itemKey); if (menuJson.isEmpty()) { qWarning() << "itemContextMenu is empty!"; @@ -335,6 +376,9 @@ void PluginItem::initPluginMenu() QWidget *PluginItem::pluginTooltip() { + if (m_interactionConfig && !m_interactionConfig->itemTooltipEnabled()) + return nullptr; + auto popup = m_pluginsItemInterface->itemPopupApplet(m_itemKey); if (popup && popup->isVisible()) popup->windowHandle()->hide(); @@ -344,6 +388,9 @@ QWidget *PluginItem::pluginTooltip() QWidget * PluginItem::itemTooltip(const QString &itemKey) { + if (m_interactionConfig && !m_interactionConfig->itemTooltipEnabled()) + return nullptr; + if (!m_tipsWidget) { auto toolTip = m_pluginsItemInterface->itemTipsWidget(itemKey); if (!toolTip) { @@ -375,6 +422,9 @@ QWidget * PluginItem::itemTooltip(const QString &itemKey) bool PluginItem::executeCommand() { + if (m_interactionConfig && !m_interactionConfig->itemActivationEnabled()) + return false; + const QString command = m_pluginsItemInterface->itemCommand(m_itemKey); if (!command.isEmpty()) { qInfo() << "command: " << command; diff --git a/src/loader/pluginitem.h b/src/loader/pluginitem.h index 38b1339f0..731fc2cb4 100644 --- a/src/loader/pluginitem.h +++ b/src/loader/pluginitem.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2011 - 2022 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2011 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: LGPL-3.0-or-later @@ -13,6 +13,7 @@ const int Attribute_ForceUnDock = 0x800000; class DockContextMenu; +class PluginInteractionConfig; class PluginItem : public QWidget { Q_OBJECT @@ -76,6 +77,7 @@ class PluginItem : public QWidget private: QTimer* m_tooltipTimer; QPointer m_tipsWidget; + PluginInteractionConfig *m_interactionConfig = nullptr; QAction *m_unDockAction = nullptr; int m_pluginFlags = 0;