Skip to content

Commit eed3350

Browse files
committed
fix: fix repeater child object crash without parent
Add memory management feature flag DCC_MEMORY_MANAGEME to control object ownership and deletion behavior. Implement DccQuickRepeater to ensure child items have proper parent relationships. Fix potential crashes when repeater child objects lack parent objects by setting ownership and parent relationships correctly. Changes include: 1. Add DCC_MEMORY_MANAGEME compile flag to control memory management features 2. Create DccQuickRepeater class that automatically sets parent for child items 3. Replace standard Repeater with DccQuickRepeater in QML files 4. Improve object ownership management in DccObject child handling 5. Add conditional memory cleanup in DccManager with safety checks Log: Fixed crash issue when repeater child objects have no parent objects Influence: 1. Test repeater functionality in various modules (accounts, datetime, display, etc.) 2. Verify no crashes when dynamically adding/removing repeater items 3. Check memory usage and cleanup during application exit 4. Test object parent relationships in QML components 5. Verify timezone dialog and other repeater-based components work correctly fix: 修复Repeater子对象无父对象导致的崩溃问题 添加内存管理功能标志DCC_MEMORY_MANAGEME来控制对象所有权和删除行为。实现 DccQuickRepeater确保子项具有正确的父子关系。通过正确设置所有权和父子关系 修复当Repeater子对象缺少父对象时可能发生的崩溃问题。 变更包括: 1. 添加DCC_MEMORY_MANAGEME编译标志控制内存管理功能 2. 创建DccQuickRepeater类自动为子项设置父对象 3. 在QML文件中将标准Repeater替换为DccQuickRepeater 4. 改进DccObject子项处理中的对象所有权管理 5. 在DccManager中添加带安全检查的条件内存清理 Log: 修复Repeater子对象无父对象导致的崩溃问题 Influence: 1. 测试各模块中的Repeater功能(账户、时间日期、显示等) 2. 验证动态添加/删除Repeater项时不会崩溃 3. 检查应用程序退出时的内存使用和清理情况 4. 测试QML组件中的对象父子关系 5. 验证时区对话框和其他基于Repeater的组件正常工作 PMS: BUG-307037
1 parent 3363f9e commit eed3350

File tree

19 files changed

+77
-10
lines changed

19 files changed

+77
-10
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ set(ENABLE_ASAN OFF)
2020
option(BUILD_TESTING "UNIT test" OFF)
2121
set(BUILD_EXAMPLES OFF)
2222

23+
set(DCC_MEMORY_MANAGEME ON)
2324
# dcc-v23
2425
set(BUILD_DCC_OLD OFF)
2526
if (BUILD_DCC_OLD)
@@ -101,6 +102,9 @@ endif ()
101102

102103
add_definitions(-DLOCALE_I18N_PATH="${LOCALE_I18N_PATH}")
103104

105+
if(DCC_MEMORY_MANAGEME)
106+
add_definitions(-DDCC_MEMORY_MANAGEME)
107+
endif()
104108
# 增加安全编译参数
105109
set(POSITION_INDEPENDENT_CODE True)
106110
set(THREADS_PREFER_PTHREAD_FLAG ON)

include/dccquickrepeater.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
#ifndef DCCQUICKREPEATER_H
5+
#define DCCQUICKREPEATER_H
6+
7+
#include "private/qquickrepeater_p.h"
8+
9+
namespace dccV25 {
10+
class DccQuickRepeater : public QQuickRepeater
11+
{
12+
Q_OBJECT
13+
QML_ELEMENT
14+
public:
15+
explicit DccQuickRepeater(QQuickItem *parent = nullptr);
16+
~DccQuickRepeater() override;
17+
18+
protected:
19+
void onItemAdded(int index, QQuickItem *item);
20+
};
21+
} // namespace dccV25
22+
#endif // DCCQUICKREPEATER_H

src/dde-control-center/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ set(DCCFrame_Libraries
2121
${DTK_NS}::Gui
2222
${QT_NS}::Gui
2323
${QT_NS}::Quick
24+
${QT_NS}::QuickPrivate
2425
${QT_NS}::QmlModelsPrivate
2526
)
2627

src/dde-control-center/dccmanager.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ bool DccManager::eventFilter(QObject *watched, QEvent *event)
558558
if (event->type() == QEvent::MouseButtonPress && watched == m_window && m_window) {
559559
QMouseEvent *e = static_cast<QMouseEvent *>(event);
560560
if (e->buttons() == Qt::LeftButton) {
561-
QQuickWindow *w = static_cast<QQuickWindow *>(m_window);
561+
QQuickWindow *w = static_cast<QQuickWindow *>(m_window.get());
562562
QQuickItem *focusItem = w->activeFocusItem();
563563
if (focusItem) {
564564
QObject *popup = focusItem->property("popup").value<QObject *>();
@@ -933,8 +933,11 @@ void DccManager::clearData()
933933
m_window->close();
934934
// doShowPage(m_root, QString());
935935

936-
// #ifdef QT_DEBUG
936+
#ifdef DCC_MEMORY_MANAGEME
937937
// TODO: delete m_engine会有概率崩溃
938+
if (m_window) {
939+
delete m_window;
940+
}
938941
qCDebug(dccLog()) << "delete root begin";
939942
DccObject *root = m_root;
940943
m_root = nullptr;
@@ -961,7 +964,7 @@ void DccManager::clearData()
961964
delete m_engine;
962965
qCDebug(dccLog()) << "clear QmlEngine";
963966
m_engine = nullptr;
964-
// #endif
967+
#endif
965968
}
966969

967970
void DccManager::waitLoadFinished() const

src/dde-control-center/dccmanager.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ private Q_SLOTS:
120120
QVector<DccObject *> m_currentObjects;
121121

122122
PluginManager *m_plugins;
123-
QWindow *m_window;
123+
QPointer<QWindow> m_window;
124124
Dtk::Core::DConfig *m_dconfig;
125125
QSet<QString> m_hideModule;
126126
QSet<QString> m_disableModule;

src/dde-control-center/frame/dccobject.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,8 @@ int DccObject::Private::getChildIndex(const DccObject *child) const
195195
void DccObject::Private::deleteSectionItem(bool later)
196196
{
197197
if (m_sectionItem) {
198+
#ifdef DCC_MEMORY_MANAGEME
198199
QQuickItem *item = m_sectionItem.get();
199-
m_sectionItem = nullptr;
200-
q_ptr->setParentItem(nullptr);
201200
if (later) {
202201
// 延时delete等动画完成
203202
QTimer::singleShot(500, item, [item]() {
@@ -206,6 +205,9 @@ void DccObject::Private::deleteSectionItem(bool later)
206205
} else {
207206
item->deleteLater();
208207
}
208+
#endif
209+
m_sectionItem = nullptr;
210+
q_ptr->setParentItem(nullptr);
209211
}
210212
}
211213

@@ -493,6 +495,7 @@ QQuickItem *DccObject::getSectionItem(QObject *parent)
493495
p_ptr->m_sectionItem.get()->setParent(parent);
494496
p_ptr->m_sectionItem->setParentItem(qobject_cast<QQuickItem *>(parent));
495497
p_ptr->m_sectionItem->setEnabled(isEnabledToApp());
498+
QQmlEngine::setObjectOwnership(p_ptr->m_sectionItem, QQmlEngine::JavaScriptOwnership);
496499
} else {
497500
qCWarning(dccLog()) << "create page error:" << p_ptr->m_page->errorString();
498501
delete context;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
2+
//
3+
// SPDX-License-Identifier: GPL-3.0-or-later
4+
#include "dccquickrepeater.h"
5+
6+
namespace dccV25 {
7+
DccQuickRepeater::DccQuickRepeater(QQuickItem *parent)
8+
: QQuickRepeater(parent)
9+
{
10+
connect(this, &QQuickRepeater::itemAdded, this, &DccQuickRepeater::onItemAdded);
11+
}
12+
13+
DccQuickRepeater::~DccQuickRepeater() { }
14+
15+
void DccQuickRepeater::onItemAdded(int, QQuickItem *item)
16+
{
17+
if (!item->parent()) {
18+
item->setParent(this);
19+
}
20+
}
21+
} // namespace dccV25

src/dde-control-center/frame/plugin/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ target_include_directories(${DCCQmlPlugin_Name} PRIVATE
4141
set(DCCQmlPlugin_Libraries
4242
${QT_NS}::Gui
4343
${QT_NS}::Quick
44+
${QT_NS}::QuickPrivate
4445
${DCC_FRAME_Library}
4546
)
4647

src/dde-control-center/frame/plugin/DccGroupView.qml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import QtQml.Models //Delegatechoice for Qt >= 6.9
88
import Qt.labs.qmlmodels //DelegateChooser
99

1010
import org.deepin.dtk 1.0 as D
11+
import org.deepin.dcc 1.0
1112

1213
Rectangle {
1314
id: root

src/dde-control-center/frame/plugin/DccRowView.qml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Qt.labs.platform 1.1
77
import Qt.labs.qmlmodels 1.2
88

99
import org.deepin.dtk 1.0 as D
10+
import org.deepin.dcc 1.0
1011

1112
RowLayout {
1213
id: root

0 commit comments

Comments
 (0)