fix(dtkdeclarative): prevent startTimer warning when event dispatcher is unavailable - #657
Conversation
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdds a defensive check before scheduling the DQuickDciIconImage layout so that no QTimer is started when the event dispatcher is unavailable, preventing startTimer warnings during application teardown. Sequence diagram for DQuickDciIconImage layout scheduling with event dispatcher checksequenceDiagram
participant ListViewDelegate
participant DQuickDciIconImage
participant DQuickDciIconImagePrivate
participant QAbstractEventDispatcher
participant QTimer
ListViewDelegate->>DQuickDciIconImage: itemChange()/geometryChange()
DQuickDciIconImage->>DQuickDciIconImagePrivate: scheduleLayout()
DQuickDciIconImagePrivate->>QAbstractEventDispatcher: instance(DQuickDciIconImage.thread())
alt dispatcher_available
QAbstractEventDispatcher-->>DQuickDciIconImagePrivate: dispatcher
DQuickDciIconImagePrivate->>QTimer: start()
else dispatcher_unavailable
QAbstractEventDispatcher-->>DQuickDciIconImagePrivate: null
DQuickDciIconImagePrivate-->>DQuickDciIconImagePrivate: return without starting timer
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue
Prompt for AI Agents
Please address the comments from this code review:
## Individual Comments
### Comment 1
<location path="src/private/dquickdciiconimage.cpp" line_range="222-223" />
<code_context>
void DQuickDciIconImagePrivate::scheduleLayout()
{
Q_Q(DQuickDciIconImage);
+ if (Q_UNLIKELY(!QAbstractEventDispatcher::instance(q->thread())))
+ return;
if (!layoutTimer) {
</code_context>
<issue_to_address>
**issue:** Consider whether silently returning when no event dispatcher exists is the desired behavior for `scheduleLayout`.
By returning early, layout updates are skipped whenever `q->thread()` lacks an event dispatcher. If this scenario is not expected, it may be preferable to assert, log, or fall back to `QAbstractEventDispatcher::instance()` on the current thread. If it is expected, consider adding a short comment explaining why suppressing layout here is acceptable to avoid confusion for future maintainers.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| // ~QCoreApplication() nulls eventDispatcher before ~QObject::deleteChildren() | ||
| // destroys them, which may trigger itemChange/geometryChange hooks leading here. | ||
| // Same check as QObject::startTimer() internally, prevents the warning. | ||
| if (Q_UNLIKELY(!QAbstractEventDispatcher::instance(q->thread()))) |
There was a problem hiding this comment.
QCoreApplication析构的时候会触发Item的geometryChange的事件?
deepin pr auto review★ 总体评分:100分■ 【总体评价】
■ 【详细分析】
■ 【改进建议代码示例】 void DQuickDciIconImage::itemChange(ItemChange change, const ItemChangeData &value)
{
QQuickItem::itemChange(change, value);
// 当父项变更且当前已无父项时,避免执行无效的布局调度,防止潜在崩溃
if (change == ItemParentHasChanged && !parentItem()) {
return;
}
if (change == ItemParentHasChanged || change == ItemDevicePixelRatioHasChanged || change == ItemSceneChange) {
d_func()->scheduleLayout();
}
} |
… is unavailable DQuickDciIconImage::scheduleLayout() may be invoked via itemChange() or geometryChange() hooks during the destruction of ListView delegate items reparented to QCoreApplication via QQmlDelegateModel. At that point, ~QCoreApplication() has already set eventDispatcher to nullptr , causing QObject::startTimer() to emit: "QObject::startTimer: Timers can only be used with threads started with QThread" Log: Fix startTimer warning for DciIcon Influence: 1. DciIcon displays correctly; 2. When the program exits, DciIcon in containers such as ListView and Repeater does not have a startTimer warning fix(dtkdeclarative): 修复 eventDispatcher 不可用时 startTimer 告警 ListView delegate item 经 QQmlDelegateModel 重挂到 QCoreApplication 后,在 ~QCoreApplication() 的 ~QObject::deleteChildren() 阶段析构。 此时 itemChange()/geometryChange() 钩子触发 scheduleLayout() → QTimer::start() → QObject::startTimer(),但 ~QCoreApplication() 体 已在基类析构体之前将 eventDispatcher 置空,导致以下告警: "QObject::startTimer: Timers can only be used with threads started with QThread" Log: 修复DciIcon的startTimer警告 Influence: 1.DciIcon正确显示; 2.程序退出时,ListView、Repeater等容器中的DciIcon没有startTimer警告 PMS: TASK-392413
|
@source-ai review |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, 52cyb The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/forcemerge |
|
This pr force merged! (status: unstable) |
DQuickDciIconImage::scheduleLayout() may be invoked via itemChange() or geometryChange() hooks during the destruction of ListView delegate items reparented to QCoreApplication via QQmlDelegateModel. At that point, ~QCoreApplication() has already set eventDispatcher to nullptr , causing QObject::startTimer() to emit:
"QObject::startTimer: Timers can only be used with threads started
with QThread"
Log: Fix startTimer warning for DciIcon
Influence:
fix(dtkdeclarative): 修复 eventDispatcher 不可用时 startTimer 告警
ListView delegate item 经 QQmlDelegateModel 重挂到 QCoreApplication 后,在 ~QCoreApplication() 的 ~QObject::deleteChildren() 阶段析构。 此时 itemChange()/geometryChange() 钩子触发 scheduleLayout() → QTimer::start() → QObject::startTimer(),但 ~QCoreApplication() 体 已在基类析构体之前将 eventDispatcher 置空,导致以下告警:
"QObject::startTimer: Timers can only be used with threads started
with QThread"
Log: 修复DciIcon的startTimer警告
Influence:
1.DciIcon正确显示;
2.程序退出时,ListView、Repeater等容器中的DciIcon没有startTimer警告
PMS: TASK-392413
Summary by Sourcery
Bug Fixes: