mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
fix: 修复部分托盘服务对应进程状态异常时导致任务栏卡死问题
fcitx进程异常时,其statusnotifieritem服务被任务栏调用会导致任务栏卡死 Log: 解决部分情况下任务栏卡死问题 Influence: 托盘服务 Bug: https://pms.uniontech.com/bug-view-121947.html Change-Id: Ia7bc9cf077b3b707677a5fe5388b483600ba0de8
This commit is contained in:
parent
c7826edd46
commit
7ac4592ebb
@ -29,6 +29,9 @@
|
||||
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QtConcurrent>
|
||||
#include <QFuture>
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
@ -86,6 +89,7 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par
|
||||
setOwnerPID(conn.interface()->servicePid(m_dbusService));
|
||||
|
||||
m_sniInter = new StatusNotifierItem(m_dbusService, m_dbusPath, QDBusConnection::sessionBus(), this);
|
||||
m_sniInter->setSync(false);
|
||||
|
||||
if (!m_sniInter->isValid()) {
|
||||
qDebug() << "SNI dbus interface is invalid!" << m_dbusService << m_dbusPath << m_sniInter->lastError();
|
||||
@ -147,30 +151,11 @@ SNITrayItemWidget::SNITrayItemWidget(const QString &sniServicePath, QWidget *par
|
||||
connect(m_sniInter, &StatusNotifierItem::NewStatus, [ = ] {
|
||||
onSNIStatusChanged(m_sniInter->status());
|
||||
});
|
||||
|
||||
initSNIPropertys();
|
||||
}
|
||||
|
||||
QString SNITrayItemWidget::itemKeyForConfig()
|
||||
{
|
||||
QString key;
|
||||
|
||||
do {
|
||||
key = m_sniId;
|
||||
if (!key.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
key = QDBusInterface(m_dbusService, m_dbusPath, StatusNotifierItem::staticInterfaceName())
|
||||
.property("Id").toString();
|
||||
if (!key.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
key = m_sniServicePath;
|
||||
} while (false);
|
||||
|
||||
return QString("sni:%1").arg(key);
|
||||
return QString("sni:%1").arg(m_sniId.isEmpty() ? m_sniServicePath : m_sniId);
|
||||
}
|
||||
|
||||
void SNITrayItemWidget::updateIcon()
|
||||
@ -181,13 +166,18 @@ void SNITrayItemWidget::updateIcon()
|
||||
void SNITrayItemWidget::sendClick(uint8_t mouseButton, int x, int y)
|
||||
{
|
||||
switch (mouseButton) {
|
||||
case XCB_BUTTON_INDEX_1:
|
||||
// left button click invalid
|
||||
if (LeftClickInvalidIdList.contains(m_sniId)) {
|
||||
showContextMenu(x, y);
|
||||
} else {
|
||||
m_sniInter->Activate(x, y);
|
||||
}
|
||||
case XCB_BUTTON_INDEX_1: {
|
||||
QFuture<void> future = QtConcurrent::run([ = ] {
|
||||
StatusNotifierItem inter(m_dbusService, m_dbusPath, QDBusConnection::sessionBus());
|
||||
QDBusPendingReply<> reply = inter.Activate(x, y);
|
||||
// try to invoke context menu while calling activate get a error.
|
||||
// primarily work for apps using libappindicator.
|
||||
reply.waitForFinished();
|
||||
if (reply.isError()) {
|
||||
showContextMenu(x,y);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case XCB_BUTTON_INDEX_2:
|
||||
m_sniInter->SecondaryActivate(x, y);
|
||||
@ -256,24 +246,6 @@ uint SNITrayItemWidget::servicePID(const QString &servicePath)
|
||||
return conn.interface()->servicePid(serviceName);
|
||||
}
|
||||
|
||||
void SNITrayItemWidget::initSNIPropertys()
|
||||
{
|
||||
m_sniAttentionIconName = m_sniInter->attentionIconName();
|
||||
m_sniAttentionIconPixmap = m_sniInter->attentionIconPixmap();
|
||||
m_sniAttentionMovieName = m_sniInter->attentionMovieName();
|
||||
m_sniCategory = m_sniInter->category();
|
||||
m_sniIconName = m_sniInter->iconName();
|
||||
m_sniIconPixmap = m_sniInter->iconPixmap();
|
||||
m_sniIconThemePath = m_sniInter->iconThemePath();
|
||||
m_sniId = m_sniInter->id();
|
||||
m_sniMenuPath = m_sniInter->menu();
|
||||
m_sniOverlayIconName = m_sniInter->overlayIconName();
|
||||
m_sniOverlayIconPixmap = m_sniInter->overlayIconPixmap();
|
||||
m_sniStatus = m_sniInter->status();
|
||||
|
||||
m_updateIconTimer->start();
|
||||
}
|
||||
|
||||
void SNITrayItemWidget::initMenu()
|
||||
{
|
||||
const QString &sniMenuPath = m_sniMenuPath.path();
|
||||
|
@ -81,7 +81,6 @@ Q_SIGNALS:
|
||||
void statusChanged(SNITrayItemWidget::ItemStatus status);
|
||||
|
||||
private Q_SLOTS:
|
||||
void initSNIPropertys();
|
||||
void initMenu();
|
||||
void refreshIcon();
|
||||
void refreshOverlayIcon();
|
||||
|
@ -30,6 +30,9 @@
|
||||
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
#include <QDBusPendingCall>
|
||||
#include <QtConcurrent>
|
||||
#include <QFuture>
|
||||
|
||||
#include <xcb/xproto.h>
|
||||
|
||||
@ -39,7 +42,6 @@ DGUI_USE_NAMESPACE
|
||||
|
||||
const QStringList ItemCategoryList {"ApplicationStatus", "Communications", "SystemServices", "Hardware"};
|
||||
const QStringList ItemStatusList {"Passive", "Active", "NeedsAttention"};
|
||||
const QStringList LeftClickInvalidIdList {"sogou-qimpanel",};
|
||||
QPointer<DockPopupWindow> SNITrayWidget::PopupWindow = nullptr;
|
||||
Dock::Position SNITrayWidget::DockPosition = Dock::Position::Top;
|
||||
using namespace Dock;
|
||||
@ -93,7 +95,7 @@ SNITrayWidget::SNITrayWidget(const QString &sniServicePath, QWidget *parent)
|
||||
setOwnerPID(conn.interface()->servicePid(m_dbusService));
|
||||
|
||||
m_sniInter = new StatusNotifierItem(m_dbusService, m_dbusPath, QDBusConnection::sessionBus(), this);
|
||||
|
||||
m_sniInter->setSync(false);
|
||||
if (!m_sniInter->isValid()) {
|
||||
qDebug() << "SNI dbus interface is invalid!" << m_dbusService << m_dbusPath << m_sniInter->lastError();
|
||||
return;
|
||||
@ -154,30 +156,11 @@ SNITrayWidget::SNITrayWidget(const QString &sniServicePath, QWidget *parent)
|
||||
connect(m_sniInter, &StatusNotifierItem::NewStatus, [ = ] {
|
||||
onSNIStatusChanged(m_sniInter->status());
|
||||
});
|
||||
|
||||
initSNIPropertys();
|
||||
}
|
||||
|
||||
QString SNITrayWidget::itemKeyForConfig()
|
||||
{
|
||||
QString key;
|
||||
|
||||
do {
|
||||
key = m_sniId;
|
||||
if (!key.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
key = QDBusInterface(m_dbusService, m_dbusPath, StatusNotifierItem::staticInterfaceName())
|
||||
.property("Id").toString();
|
||||
if (!key.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
|
||||
key = m_sniServicePath;
|
||||
} while (false);
|
||||
|
||||
return QString("sni:%1").arg(key);
|
||||
return QString("sni:%1").arg(m_sniId.isEmpty() ? m_sniServicePath : m_sniId);
|
||||
}
|
||||
|
||||
void SNITrayWidget::updateIcon()
|
||||
@ -188,13 +171,18 @@ void SNITrayWidget::updateIcon()
|
||||
void SNITrayWidget::sendClick(uint8_t mouseButton, int x, int y)
|
||||
{
|
||||
switch (mouseButton) {
|
||||
case XCB_BUTTON_INDEX_1:
|
||||
// left button click invalid
|
||||
if (LeftClickInvalidIdList.contains(m_sniId)) {
|
||||
showContextMenu(x, y);
|
||||
} else {
|
||||
m_sniInter->Activate(x, y);
|
||||
}
|
||||
case XCB_BUTTON_INDEX_1: {
|
||||
QFuture<void> future = QtConcurrent::run([ = ] {
|
||||
StatusNotifierItem inter(m_dbusService, m_dbusPath, QDBusConnection::sessionBus());
|
||||
QDBusPendingReply<> reply = inter.Activate(x, y);
|
||||
// try to invoke context menu while calling activate get a error.
|
||||
// primarily work for apps using libappindicator.
|
||||
reply.waitForFinished();
|
||||
if (reply.isError()) {
|
||||
showContextMenu(x,y);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case XCB_BUTTON_INDEX_2:
|
||||
m_sniInter->SecondaryActivate(x, y);
|
||||
@ -263,26 +251,6 @@ uint SNITrayWidget::servicePID(const QString &servicePath)
|
||||
return conn.interface()->servicePid(serviceName);
|
||||
}
|
||||
|
||||
void SNITrayWidget::initSNIPropertys()
|
||||
{
|
||||
m_sniAttentionIconName = m_sniInter->attentionIconName();
|
||||
m_sniAttentionIconPixmap = m_sniInter->attentionIconPixmap();
|
||||
m_sniAttentionMovieName = m_sniInter->attentionMovieName();
|
||||
m_sniCategory = m_sniInter->category();
|
||||
m_sniIconName = m_sniInter->iconName();
|
||||
m_sniIconPixmap = m_sniInter->iconPixmap();
|
||||
m_sniIconThemePath = m_sniInter->iconThemePath();
|
||||
m_sniId = m_sniInter->id();
|
||||
m_sniMenuPath = m_sniInter->menu();
|
||||
m_sniOverlayIconName = m_sniInter->overlayIconName();
|
||||
m_sniOverlayIconPixmap = m_sniInter->overlayIconPixmap();
|
||||
m_sniStatus = m_sniInter->status();
|
||||
|
||||
m_updateIconTimer->start();
|
||||
// m_updateOverlayIconTimer->start();
|
||||
// m_updateAttentionIconTimer->start();
|
||||
}
|
||||
|
||||
void SNITrayWidget::initMenu()
|
||||
{
|
||||
const QString &sniMenuPath = m_sniMenuPath.path();
|
||||
|
@ -79,7 +79,6 @@ Q_SIGNALS:
|
||||
void statusChanged(SNITrayWidget::ItemStatus status);
|
||||
|
||||
private Q_SLOTS:
|
||||
void initSNIPropertys();
|
||||
void initMenu();
|
||||
void refreshIcon();
|
||||
void refreshOverlayIcon();
|
||||
|
@ -480,12 +480,22 @@ void TrayPlugin::traySNIAdded(const QString &itemKey, const QString &sniServiceP
|
||||
return false;
|
||||
}
|
||||
|
||||
// 1、确保服务有效
|
||||
QDBusInterface sniItemDBus(sniServerName, "/" + list.last());
|
||||
if (!sniItemDBus.isValid()) {
|
||||
qDebug() << "sni dbus service error : " << sniServerName;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 部分服务虽然有效,但是在dbus总线上只能看到服务,其他信息都无法获取,这里通过Ping进行二次确认
|
||||
// 参考: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces
|
||||
|
||||
// 2、通过Ping接口确认服务是否正常
|
||||
QDBusInterface peerInter(sniServerName, "/" + list.last(), "org.freedesktop.DBus.Peer");
|
||||
QDBusReply<void> reply = peerInter.call("Ping");
|
||||
if (!reply.isValid())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user