Skip to content

Commit 2496163

Browse files
18202781743deepin-bot[bot]
authored andcommitted
fix: fix application tray crash due to parent-child ownership and null
pointer issues 1. Fix crash in DDEindicatorTrayProtocol by using window() instead of parent() for event filter and content updates 2. Add null pointer checks in DDEindicatorTrayProtocol event filter 3. Fix crash in SniTrayProtocolHandler by using window() instead of parent() and adding null checks 4. Fix tooltip removal order in TrayPlugin to avoid dangling pointer references 5. Fix double-delete crash in TrayWidget by not setting handler as child widget 6. Add null handler checks in TrayWidget showEvent and paintEvent Log: Fixed application tray crashes when tray items are added/removed Influence: 1. Test adding and removing multiple tray items 2. Test tray indicator protocol operations 3. Test sni protocol tray operations 4. Test tray widget paint and show events 5. Test tray icon updates and tooltip display 6. Test application tray with various indicator types feat: 修复应用托盘因父子关系和空指针导致的崩溃问题 1. 修复 DDEindicatorTrayProtocol 中,使用 window() 替代 parent() 进行事 件过滤和内容更新 2. 在 DDEindicatorTrayProtocol 的事件过滤器中添加空指针检查 3. 修复 SniTrayProtocolHandler 中,使用 window() 替代 parent() 并添加空 指针检查 4. 修复 TrayPlugin 中 tooltip 移除顺序,避免悬空指针引用 5. 修复 TrayWidget 中不将 handler 设置为子控件导致的二次删除崩溃 6. 在 TrayWidget 的 showEvent 和 paintEvent 中添加 handler 空指针检查 Log: 修复添加/移除托盘项时应用托盘崩溃的问题 Influence: 1. 测试添加和移除多个托盘项 2. 测试托盘指示协议操作 3. 测试 sni 协议托盘操作 4. 测试托盘控件的绘制和显示事件 5. 测试托盘图标更新和提示信息显示 6. 测试各种指示类型下的应用托盘功能
1 parent 09cb60e commit 2496163

4 files changed

Lines changed: 27 additions & 10 deletions

File tree

plugins/application-tray/ddeindicatortrayprotocol.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -178,7 +178,7 @@ void DDEindicatorProtocolHandlerPrivate::updateContent()
178178
Q_Q(DDEindicatorProtocolHandler);
179179
if (!enabled) return;
180180

181-
auto widget = static_cast<QWidget*>(q->parent());
181+
auto widget = q->window();
182182

183183
if (widget) {
184184
widget->update();
@@ -333,9 +333,12 @@ bool DDEindicatorProtocolHandler::eventFilter(QObject *watched, QEvent *event)
333333
{
334334
Q_D(DDEindicatorProtocolHandler);
335335

336-
if (watched == parent()) {
336+
if (watched == window()) {
337337
if (event->type() == QEvent::Paint) {
338-
auto widget = static_cast<QWidget*>(parent());
338+
auto widget = window();
339+
if (!widget)
340+
return false;
341+
339342
QPainter painter(widget);
340343
QFontMetrics qfm = QFontMetrics(widget->font());
341344
QRect tightTextRect = qfm.tightBoundingRect(d->m_text);

plugins/application-tray/sniprotocolhandler.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,11 @@ bool SniTrayProtocolHandler::eventFilter(QObject *watched, QEvent *event)
328328
menu->setFixedSize(menu->sizeHint());
329329
menu->winId();
330330

331-
auto widget = static_cast<QWidget*>(parent());
332-
auto plugin = Plugin::EmbedPlugin::get(widget->window()->windowHandle());
331+
auto *win = window()->windowHandle();
332+
if (!win)
333+
return false;
334+
335+
auto plugin = Plugin::EmbedPlugin::get(win);
333336
auto geometry = plugin->pluginPos();
334337
auto pluginPopup = Plugin::PluginPopup::get(menu->windowHandle());
335338
pluginPopup->setPluginId("application-tray");

plugins/application-tray/trayplugin.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024-2026 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -83,14 +83,18 @@ void TrayPlugin::onTrayhandlerCreatd(QPointer<AbstractTrayProtocolHandler> handl
8383
m_widget.insert(id, new TrayWidget(handler));
8484

8585
auto remove = [this, id]() {
86+
// 清理 tooltip 指针,因为 tooltip widget 是 handler 的成员变量,
87+
// 当 handler 被销毁时会被删除,所以需要先从 map 中移除悬空指针
88+
m_tooltip.remove(id);
89+
8690
m_proyInter->itemRemoved(this, id);
91+
8792
auto widget = m_widget.value(id);
8893
if (widget) {
8994
widget->deleteLater();
9095
}
9196

9297
m_widget.remove(id);
93-
m_tooltip.remove(id);
9498
};
9599

96100
auto showWidget = [this, handler, id](){

plugins/application-tray/traywidget.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
1+
// SPDX-FileCopyrightText: 2024 - 2026 UnionTech Software Technology Co., Ltd.
22
//
33
// SPDX-License-Identifier: GPL-3.0-or-later
44

@@ -28,7 +28,8 @@ TrayWidget::TrayWidget(QPointer<AbstractTrayProtocolHandler> handler)
2828
setWindowTitle(m_handler->id());
2929
setFixedSize(trayIconSize, trayIconSize);
3030

31-
m_handler->setParent(this);
31+
// Note: Do NOT set parent here - handler lifecycle is managed by QSharedPointer
32+
// Setting parent would cause double-delete when QSharedPointer destroys the handler
3233

3334
connect(m_handler, &AbstractTrayProtocolHandler::iconChanged, this, [this](){update();});
3435
connect(m_handler, &AbstractTrayProtocolHandler::overlayIconChanged, this, [this](){update();});
@@ -47,6 +48,9 @@ TrayWidget::~TrayWidget()
4748
void TrayWidget::showEvent(QShowEvent* event)
4849
{
4950
Q_UNUSED(event)
51+
if (!m_handler)
52+
return;
53+
5054
m_handler->setWindow(window());
5155
window()->installEventFilter(m_handler);
5256
window()->setMouseTracking(true);
@@ -56,6 +60,9 @@ void TrayWidget::paintEvent(QPaintEvent* event)
5660
{
5761
Q_UNUSED(event)
5862

63+
if (!m_handler)
64+
return;
65+
5966
// TODO: support attentionIcon/overlayIcon
6067
QPalette palette;
6168
auto textColor = DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType ? Qt::black : Qt::white;

0 commit comments

Comments
 (0)