From ec775d9fd9141b7e96b0e7b72ef664a4c97e662a Mon Sep 17 00:00:00 2001 From: BLumia Date: Fri, 16 Oct 2026 14:36:53 +0800 Subject: [PATCH] fix: handle SNI NewMenu signal and empty menu path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Root cause: init() read m_menuPath only once without listening for NewMenu signal; race condition left it empty permanently 2. Fix: add NewMenu signal to XML and connect it to refresh m_menuPath and destroy stale importer; make menu path lazy-read in menuImporter() instead of init(); guard empty path 3. Impact: SNI tray apps now get correct right-click menu even under startup race; empty path falls back to ContextMenu(0,0) Log: Fix empty right-click menu for SNI tray apps on startup race Influence: 1. Test right-click menu for normal SNI apps after full startup 2. Test right-click menu during SNI app startup race condition 3. Test ContextMenu fallback for SNI apps without DBusMenu 4. Test menu refresh when app changes menu path at runtime fix: 修复SNI应用启动竞态时托盘右键弹空菜单 1. 根因:init() 只读取一次 m_menuPath 且未监听 NewMenu 信号, 启动竞态时读到空路径导致永久失效,无法回退 ContextMenu 2. 方案:XML 新增 NewMenu 信号声明,构造函数连接信号刷新 m_menuPath 并销毁旧 importer;menuImporter() 改为惰性读取 菜单路径并对空路径兜底返回 nullptr 3. 影响:SNI 托盘应用在启动竞态下右键菜单恢复正常;空路径 时回退 ContextMenu(0,0) 兜底 Log: 修复SNI应用启动竞态时托盘右键弹空菜单的问题 Influence: 1. 测试 SNI 应用正常启动后右键菜单功能 2. 测试 SNI 应用启动竞态时右键菜单功能 3. 测试无 DBusMenu 的 SNI 应用右键回退 ContextMenu 4. 测试应用运行中菜单路径变更后的菜单刷新 PMS: BUG-379875 --- .../api/dbus/org.kde.StatusNotifierItem.xml | 1 + plugins/application-tray/sniprotocolhandler.cpp | 13 +++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/application-tray/api/dbus/org.kde.StatusNotifierItem.xml b/plugins/application-tray/api/dbus/org.kde.StatusNotifierItem.xml index 64e9b4dc1..b4275399b 100644 --- a/plugins/application-tray/api/dbus/org.kde.StatusNotifierItem.xml +++ b/plugins/application-tray/api/dbus/org.kde.StatusNotifierItem.xml @@ -58,6 +58,7 @@ + diff --git a/plugins/application-tray/sniprotocolhandler.cpp b/plugins/application-tray/sniprotocolhandler.cpp index 8fad3fa2a..6c2fb7acf 100644 --- a/plugins/application-tray/sniprotocolhandler.cpp +++ b/plugins/application-tray/sniprotocolhandler.cpp @@ -179,6 +179,13 @@ SniTrayProtocolHandler::SniTrayProtocolHandler(const QString &sniServicePath, QO connect(m_sniInter, &StatusNotifierItem::NewTitle, this, &SniTrayProtocolHandler::titleChanged); connect(m_sniInter, &StatusNotifierItem::NewStatus, this, &SniTrayProtocolHandler::statusChanged); connect(m_sniInter, &StatusNotifierItem::NewToolTip, this, &SniTrayProtocolHandler::tooltiChanged); + connect(m_sniInter, &StatusNotifierItem::NewMenu, this, [this] { + m_menuPath = m_sniInter->menu().path(); + if (m_dbusMenuImporter) { + delete m_dbusMenuImporter; + m_dbusMenuImporter = nullptr; + } + }); connect(DGuiApplicationHelper::instance(), &DGuiApplicationHelper::themeTypeChanged, this, [this](DGuiApplicationHelper::ColorType themeType) { Q_UNUSED(themeType) if (auto menu = menuImporter()) { @@ -200,7 +207,6 @@ SniTrayProtocolHandler::~SniTrayProtocolHandler() void SniTrayProtocolHandler::init() { generateId(); - m_menuPath = m_sniInter->menu().path(); m_cachedIcon = dbusImageList2QIcon(m_sniInter->iconPixmap()); m_cachedAttentionIcon = dbusImageList2QIcon(m_sniInter->attentionIconPixmap()); m_cachedOverlayIcon = dbusImageList2QIcon(m_sniInter->overlayIconPixmap()); @@ -216,7 +222,10 @@ DBusMenuImporter *SniTrayProtocolHandler::menuImporter() const { if (!m_dbusMenuImporter) { auto that = const_cast(this); - if (that->m_menuPath == QLatin1String("/NO_DBUSMENU")) { + if (that->m_menuPath.isEmpty()) { + that->m_menuPath = m_sniInter->menu().path(); + } + if (that->m_menuPath.isEmpty() || that->m_menuPath == QLatin1String("/NO_DBUSMENU")) { return nullptr; } that->m_dbusMenuImporter = new DBusMenu(m_service, m_menuPath, that);