From 3e5537422670d24789ca1d78e897807a104c69cf Mon Sep 17 00:00:00 2001 From: yeshanshan Date: Fri, 5 Jun 2026 13:57:02 +0800 Subject: [PATCH] fix: prevent crash when treeland restarts in taskbar MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The crash occurs because when treeland restarts, the clear() method in TreeLandWindowMonitor clears internal window lists but fails to reset the tracked windows model. When treeland restart triggers a cleanup followed by re-initialization, the model still holds stale references to windows that have been destroyed, leading to a use-after-free crash when the model attempts to access the window data during view updates. Added clearTrackedWindows() method to properly clear all tracked windows from the model using beginResetModel/endResetModel, and called it at the start of clear() in both TreeLandWindowMonitor and X11WindowMonitor to ensure the model is reset before internal lists are cleared. This ensures the model and view are properly synchronized, preventing access to destroyed window objects. Log: fix treeland restart crash Influence: 1. Test taskbar behavior when treeland restarts unexpectedly 2. Verify taskbar shows correct windows after treeland restart 3. Test taskbar with no windows open during treeland restart 4. Verify no crash when multiple rapid treeland restarts occur 5. Test X11 window monitor clear function for regressions 6. Verify taskbar preview windows still work correctly after restart fix: 修复任务栏在treeland重启时崩溃的问题 当treeland重启时,TreeLandWindowMonitor中的clear()方法清除了内部窗口列 表,但未能重置跟踪窗口的模型。treeland重启触发清理后重新初始化时,模型 仍然持有已被销毁窗口的陈旧引用,导致视图更新时访问已释放的窗口对象引发崩 溃。新增clearTrackedWindows()方法,通过beginResetModel/endResetModel正确 清除模型中的所有跟踪窗口,并在TreeLandWindowMonitor和X11WindowMonitor的 clear()方法开始时调用该方法,确保在清除内部列表之前重置模型。这保证了模 型和视图同步一致,防止访问已销毁的窗口对象。 Log: 修复treeland重启崩溃问题 Influence: 1. 测试treeland异常重启时任务栏的行为 2. 验证treeland重启后任务栏显示正确的窗口 3. 测试treeland重启时没有打开任何窗口的情况 4. 验证多次快速重启treeland不会导致崩溃 5. 测试X11窗口监视器的清除功能是否有回归问题 6. 验证重启后任务栏预览窗口仍然正常工作 --- panels/dock/taskmanager/abstractwindowmonitor.cpp | 8 ++++++++ panels/dock/taskmanager/abstractwindowmonitor.h | 3 ++- panels/dock/taskmanager/treelandwindowmonitor.cpp | 1 + panels/dock/taskmanager/x11windowmonitor.cpp | 1 + 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/panels/dock/taskmanager/abstractwindowmonitor.cpp b/panels/dock/taskmanager/abstractwindowmonitor.cpp index ae07623d3..c8b198e7f 100644 --- a/panels/dock/taskmanager/abstractwindowmonitor.cpp +++ b/panels/dock/taskmanager/abstractwindowmonitor.cpp @@ -158,5 +158,13 @@ void AbstractWindowMonitor::destroyWindow(AbstractWindow * window) endRemoveRows(); } +void AbstractWindowMonitor::clearTrackedWindows() +{ + if (m_trackedWindows.isEmpty()) + return; + beginResetModel(); + m_trackedWindows.clear(); + endResetModel(); +} } diff --git a/panels/dock/taskmanager/abstractwindowmonitor.h b/panels/dock/taskmanager/abstractwindowmonitor.h index ddf60c527..dbc20dec4 100644 --- a/panels/dock/taskmanager/abstractwindowmonitor.h +++ b/panels/dock/taskmanager/abstractwindowmonitor.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd. +// SPDX-FileCopyrightText: 2023 - 2026 UnionTech Software Technology Co., Ltd. // // SPDX-License-Identifier: GPL-3.0-or-later @@ -26,6 +26,7 @@ class AbstractWindowMonitor : public QAbstractListModel, public AbstractTaskMana void trackWindow(AbstractWindow* window); void destroyWindow(AbstractWindow * window); + void clearTrackedWindows(); AbstractWindowMonitor(QObject* parent = nullptr); virtual void start() = 0; diff --git a/panels/dock/taskmanager/treelandwindowmonitor.cpp b/panels/dock/taskmanager/treelandwindowmonitor.cpp index 7d5a4362a..32cf23e5e 100644 --- a/panels/dock/taskmanager/treelandwindowmonitor.cpp +++ b/panels/dock/taskmanager/treelandwindowmonitor.cpp @@ -102,6 +102,7 @@ void TreeLandWindowMonitor::stop() void TreeLandWindowMonitor::clear() { + clearTrackedWindows(); m_windows.clear(); m_dockPreview.reset(nullptr); updateFullscreenState(); diff --git a/panels/dock/taskmanager/x11windowmonitor.cpp b/panels/dock/taskmanager/x11windowmonitor.cpp index 7eca4f72a..b10badf8e 100644 --- a/panels/dock/taskmanager/x11windowmonitor.cpp +++ b/panels/dock/taskmanager/x11windowmonitor.cpp @@ -91,6 +91,7 @@ void X11WindowMonitor::stop() void X11WindowMonitor::clear() { + clearTrackedWindows(); m_windows.clear(); m_windowPreview.reset(nullptr); }