diff --git a/plugins/application-tray/abstracttrayprotocol.h b/plugins/application-tray/abstracttrayprotocol.h index 44c9c9015..5d6072115 100644 --- a/plugins/application-tray/abstracttrayprotocol.h +++ b/plugins/application-tray/abstracttrayprotocol.h @@ -11,6 +11,13 @@ class TrayWidget; namespace tray { + +enum Protocol { + UNKNOWN = 0, + XEMBED, + SNI +}; + class AbstractTrayProtocolHandler; class AbstractTrayProtocol : public QObject { @@ -21,6 +28,9 @@ class AbstractTrayProtocol : public QObject Q_SIGNALS: void trayCreated(QPointer handler); + +protected: + inline static QHash registeredMap; }; class AbstractTrayProtocolHandler : public QObject diff --git a/plugins/application-tray/sniprotocolhandler.cpp b/plugins/application-tray/sniprotocolhandler.cpp index c5e0c0504..2854c8a1c 100644 --- a/plugins/application-tray/sniprotocolhandler.cpp +++ b/plugins/application-tray/sniprotocolhandler.cpp @@ -78,6 +78,11 @@ void SniTrayProtocol::registedItemChanged() for (auto currentRegistedItem : currentRegistedItems) { if (!m_registedItem.contains(currentRegistedItem)) { auto trayHandler = QSharedPointer(new SniTrayProtocolHandler(currentRegistedItem)); + uint pid = QDBusConnection::sessionBus().interface()->servicePid(SniTrayProtocolHandler::serviceAndPath(currentRegistedItem).first).value(); + m_item2Pid[currentRegistedItem] = pid; + if (registeredMap[pid] != SNI) + emit removeXEmbedItemByPid(pid); + registeredMap[pid] = SNI; m_registedItem.insert(currentRegistedItem, trayHandler); Q_EMIT AbstractTrayProtocol::trayCreated(trayHandler.get()); } @@ -86,6 +91,9 @@ void SniTrayProtocol::registedItemChanged() for (auto alreadyRegistedItem : m_registedItem.keys()) { if (!currentRegistedItems.contains(alreadyRegistedItem)) { if (auto value = m_registedItem.value(alreadyRegistedItem, nullptr)) { + uint pid = m_item2Pid[alreadyRegistedItem]; + m_item2Pid.remove(alreadyRegistedItem); + registeredMap.remove(pid); m_registedItem.remove(alreadyRegistedItem); } } diff --git a/plugins/application-tray/sniprotocolhandler.h b/plugins/application-tray/sniprotocolhandler.h index 50dd22a40..628f726c9 100644 --- a/plugins/application-tray/sniprotocolhandler.h +++ b/plugins/application-tray/sniprotocolhandler.h @@ -27,6 +27,9 @@ class SniTrayProtocol : public AbstractTrayProtocol explicit SniTrayProtocol(QObject *parent = nullptr); ~SniTrayProtocol(); +Q_SIGNALS: + void removeXEmbedItemByPid(uint pid); + private Q_SLOTS: void registedItemChanged(); @@ -34,6 +37,7 @@ private Q_SLOTS: OrgKdeStatusNotifierWatcherInterface* m_trayManager; QHash> m_registedItem; + QHash m_item2Pid; }; class SniTrayProtocolHandler : public AbstractTrayProtocolHandler diff --git a/plugins/application-tray/trayplugin.cpp b/plugins/application-tray/trayplugin.cpp index fa4395ef8..f8aa9f6e6 100644 --- a/plugins/application-tray/trayplugin.cpp +++ b/plugins/application-tray/trayplugin.cpp @@ -59,6 +59,7 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter) connect(sniProtocol, &SniTrayProtocol::trayCreated, this, &TrayPlugin::onTrayhandlerCreatd); connect(indicatorProtocol, &SniTrayProtocol::trayCreated, this, &TrayPlugin::onTrayhandlerCreatd); + connect(sniProtocol, &SniTrayProtocol::removeXEmbedItemByPid, xembedProtocol, &XembedProtocol::onRemoveItemByPid); if (UTIL->isXAvaliable()) { connect(xembedProtocol, &SniTrayProtocol::trayCreated, this, &TrayPlugin::onTrayhandlerCreatd); } else { diff --git a/plugins/application-tray/xembedprotocolhandler.cpp b/plugins/application-tray/xembedprotocolhandler.cpp index 107551a82..14ab1346f 100644 --- a/plugins/application-tray/xembedprotocolhandler.cpp +++ b/plugins/application-tray/xembedprotocolhandler.cpp @@ -88,6 +88,11 @@ void XembedProtocol::onTrayIconsChanged() for (auto currentRegistedItem : currentRegistedItems) { if (!m_registedItem.contains(currentRegistedItem)) { auto trayHandler = QSharedPointer(new XembedProtocolHandler(currentRegistedItem)); + uint pid = UTIL->getWindowPid(trayHandler->windowId()); + if (registeredMap[pid] == SNI) + continue; + registeredMap[pid] = XEMBED; + m_item2Pid[currentRegistedItem] = pid; connect(m_trayManager, &TrayManager::Changed, trayHandler.get(), &XembedProtocolHandler::xembedTrayIconChanged); m_registedItem.insert(currentRegistedItem, trayHandler); Q_EMIT AbstractTrayProtocol::trayCreated(trayHandler.get()); @@ -97,6 +102,9 @@ void XembedProtocol::onTrayIconsChanged() for (auto alreadyRegistedItem : m_registedItem.keys()) { if (!currentRegistedItems.contains(alreadyRegistedItem)) { if (auto value = m_registedItem.value(alreadyRegistedItem, nullptr)) { + uint pid = m_item2Pid[alreadyRegistedItem]; + registeredMap.remove(pid); + m_item2Pid.remove(alreadyRegistedItem); m_registedItem.remove(alreadyRegistedItem); } } @@ -105,6 +113,15 @@ void XembedProtocol::onTrayIconsChanged() } +void XembedProtocol::onRemoveItemByPid(uint pid) +{ + auto it = std::find_if(m_registedItem.keys().begin(), m_registedItem.keys().end(), [this, pid] (uint id) { return pid == m_item2Pid[id]; }); + if (it != m_registedItem.keys().end()) { + m_item2Pid.remove(*it); + m_registedItem.remove(*it); + } +} + XembedProtocolHandler::XembedProtocolHandler(const uint32_t& id, QObject* parent) : AbstractTrayProtocolHandler(parent) , m_enabled(false) diff --git a/plugins/application-tray/xembedprotocolhandler.h b/plugins/application-tray/xembedprotocolhandler.h index e7ddc607f..8fb1c6704 100644 --- a/plugins/application-tray/xembedprotocolhandler.h +++ b/plugins/application-tray/xembedprotocolhandler.h @@ -26,6 +26,9 @@ class XembedProtocol : public AbstractTrayProtocol, public QAbstractNativeEventF XembedProtocol(QObject *parent = nullptr); ~XembedProtocol(); +public Q_SLOTS: + void onRemoveItemByPid(uint pid); + protected: bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override; @@ -36,6 +39,7 @@ private Q_SLOTS: TrayManager* m_trayManager; FdoSelectionManager *m_selectionManager = nullptr; QHash> m_registedItem; + QHash m_item2Pid; }; class XembedProtocolHandler : public AbstractTrayProtocolHandler