Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 50 additions & 14 deletions plugins/application-tray/sniprotocolhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@

#include "dbusmenuimporter.h"

#include <QMouseEvent>

Check warning on line 14 in plugins/application-tray/sniprotocolhandler.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QMouseEvent> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QWindow>

Check warning on line 15 in plugins/application-tray/sniprotocolhandler.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QWindow> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QThreadPool>

Check warning on line 16 in plugins/application-tray/sniprotocolhandler.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QThreadPool> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <QRunnable>

Check warning on line 17 in plugins/application-tray/sniprotocolhandler.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <QRunnable> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <DGuiApplicationHelper>

Check warning on line 19 in plugins/application-tray/sniprotocolhandler.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <DGuiApplicationHelper> not found. Please note: Cppcheck does not need standard library headers to get proper results.

DGUI_USE_NAMESPACE

Expand Down Expand Up @@ -75,20 +77,38 @@
return;
}

for (auto currentRegistedItem : currentRegistedItems) {
if (!m_registedItem.contains(currentRegistedItem)) {
auto trayHandler = QSharedPointer<SniTrayProtocolHandler>(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());
// 处理新增的items:在子线程创建 Handler(init() 阻塞在此)
for (const auto &currentRegistedItem : currentRegistedItems) {
if (!m_registedItem.contains(currentRegistedItem) && !m_pendingItems.contains(currentRegistedItem)) {
m_pendingItems.insert(currentRegistedItem);

QThreadPool::globalInstance()->start([this, currentRegistedItem]() {
auto pair = SniTrayProtocolHandler::serviceAndPath(currentRegistedItem);
const uint pid = QDBusConnection::sessionBus().interface()->servicePid(pair.first).value();

auto trayHandler = QSharedPointer<SniTrayProtocolHandler>(
new SniTrayProtocolHandler(currentRegistedItem));
trayHandler->moveToThread(this->thread());

QMetaObject::invokeMethod(this, [this, currentRegistedItem, pid, trayHandler]() {
if (!m_pendingItems.contains(currentRegistedItem)) {
return; // item 已被取消,不添加
}
m_pendingItems.remove(currentRegistedItem);

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());
}, Qt::QueuedConnection);
});
}
}

for (auto alreadyRegistedItem : m_registedItem.keys()) {
// 处理移除的items
for (const auto &alreadyRegistedItem : m_registedItem.keys()) {
if (!currentRegistedItems.contains(alreadyRegistedItem)) {
if (auto value = m_registedItem.value(alreadyRegistedItem, nullptr)) {
uint pid = m_item2Pid[alreadyRegistedItem];
Expand All @@ -98,11 +118,22 @@
}
}
}

// 移除pending中但不在当前列表的items(取消异步创建)
QSet<QString> toRemoveFromPending;
for (const auto &pendingItem : m_pendingItems) {
if (!currentRegistedItems.contains(pendingItem)) {
toRemoveFromPending.insert(pendingItem);
}
}
for (const auto &item : toRemoveFromPending) {
m_pendingItems.remove(item);
}
}

SniTrayProtocolHandler::SniTrayProtocolHandler(const QString &sniServicePath, QObject *parent)
: AbstractTrayProtocolHandler(parent)
, m_tooltip (new QLabel())
, m_tooltip(nullptr) // 延迟创建,在tooltip()方法中创建
, m_ignoreFirstAttention(true)
, m_dbusMenuImporter(nullptr)
{
Expand All @@ -111,9 +142,8 @@
// will get a unique dbus name (number like x.xxxx) and dbus path
m_dbusUniqueName = pair.first.mid(1);
m_sniInter = new StatusNotifierItem(pair.first, pair.second, QDBusConnection::sessionBus(), this);
m_sniInter->setTimeout(2000);
init();
m_sniInter->setSync(false);
m_tooltip->setForegroundRole(QPalette::BrightText);

connect(m_sniInter, &StatusNotifierItem::NewIcon, this, &SniTrayProtocolHandler::iconChanged);
connect(m_sniInter, &StatusNotifierItem::NewOverlayIcon, this, &SniTrayProtocolHandler::overlayIconChanged);
Expand Down Expand Up @@ -183,6 +213,12 @@

QWidget* SniTrayProtocolHandler::tooltip() const
{
// 延迟创建label,确保在主线程创建
if (!m_tooltip) {
const_cast<SniTrayProtocolHandler*>(this)->m_tooltip = new QLabel();
m_tooltip->setForegroundRole(QPalette::BrightText);
}

if (!m_sniInter->toolTip().title.isEmpty()) {
m_tooltip->setText(m_sniInter->toolTip().title);
return m_tooltip;
Expand Down
3 changes: 2 additions & 1 deletion plugins/application-tray/sniprotocolhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,15 @@ private Q_SLOTS:

QHash<QString, QSharedPointer<SniTrayProtocolHandler>> m_registedItem;
QHash<QString, uint> m_item2Pid;
QSet<QString> m_pendingItems; // 跟踪正在异步创建的items
};

class SniTrayProtocolHandler : public AbstractTrayProtocolHandler
{
Q_OBJECT

public:
SniTrayProtocolHandler(const QString &sniServicePath, QObject *parent= nullptr);
SniTrayProtocolHandler(const QString &sniServicePath, QObject *parent = nullptr);
~SniTrayProtocolHandler();

virtual uint32_t windowId() const override;
Expand Down
Loading