From ab1c3645f87605a21ec0529500967a5c2c0bf214 Mon Sep 17 00:00:00 2001 From: yeshanshan Date: Thu, 11 Jun 2026 13:42:26 +0800 Subject: [PATCH] fix: prevent dockHiddenSurfaceIds from being reset to empty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit refactors the save logic for tray sort order data to prevent `dockHiddenSurfaceIds` from being accidentally cleared. Previously, `onAvailableSurfacesChanged()` called `saveDataToDConfig()` which saved all configuration values, including `dockHiddenSurfaceIds`, at a point where other processes might be concurrently modifying this value, leading to a race condition where it could be overwritten with empty data. The fix splits the monolithic `saveDataToDConfig()` into targeted save methods: `saveSortOrderToDConfig()`, `saveHiddenIdsToDConfig()`, `saveDockHiddenIdsToDConfig()`, and `saveCollapsedToDConfig()`. In `onAvailableSurfacesChanged()`, only sort order and hidden IDs are saved, deliberately excluding `dockHiddenSurfaceIds` to avoid the race condition. The `dockHiddenSurfaceIds` is now only saved from `setDockVisible()` via the new `saveDockHiddenIdsToDConfig()` method, when the value is explicitly changed. Influence: 1. Test tray plugin visibility toggling and verify `dockHiddenSurfaceIds` persists correctly 2. Verify `hiddenSurfaceIds` and sort order still update properly on surface changes 3. Test scenarios where multiple processes might modify dock configuration simultaneously 4. Verify no data loss occurs when hiding/showing dock tray items 5. Test that collapsed state saves and loads correctly fix: 修复 dockHiddenSurfaceIds 被意外重置为空的问题 本次重构了托盘排序数据的保存逻辑,防止 `dockHiddenSurfaceIds` 被意外清 空。之前 `onAvailableSurfacesChanged()` 调用 `saveDataToDConfig()` 会保 存所有配置值,包括 `dockHiddenSurfaceIds`,而此时其他进程可能正在并发修 改该值,导致竞态条件,使其被空数据覆盖。 修复方案将单一的 `saveDataToDConfig()` 拆分为针对性的保存方 法:`saveSortOrderToDConfig()`、`saveHiddenIdsToDConfig()`、 `saveDockHiddenIdsToDConfig()` 和 `saveCollapsedToDConfig()`。 在 `onAvailableSurfacesChanged()` 中,只保存排序和隐藏 ID,刻意排 除 `dockHiddenSurfaceIds` 以避免竞态条件。`dockHiddenSurfaceIds` 现在仅在通过 `setDockVisible()` 显式修改时,通过新增的 `saveDockHiddenIdsToDConfig()` 方法保存。 Influence: 1. 测试托盘插件的可见性切换,验证 `dockHiddenSurfaceIds` 是否持久化保存 2. 验证在 surface 变化时 `hiddenSurfaceIds` 和排序是否正常更新 3. 测试多个进程同时修改 dock 配置的场景 4. 验证显示/隐藏 dock 托盘项时数据不会丢失 5. 测试折叠状态的保存和加载是否正常 PMS:BUG-363149 --- panels/dock/tray/traysortordermodel.cpp | 38 ++++++++++++++++++++++--- panels/dock/tray/traysortordermodel.h | 5 ++++ 2 files changed, 39 insertions(+), 4 deletions(-) diff --git a/panels/dock/tray/traysortordermodel.cpp b/panels/dock/tray/traysortordermodel.cpp index 5d2a7b06a..371e6853b 100644 --- a/panels/dock/tray/traysortordermodel.cpp +++ b/panels/dock/tray/traysortordermodel.cpp @@ -57,7 +57,7 @@ TraySortOrderModel::TraySortOrderModel(QObject *parent) connect(this, &TraySortOrderModel::collapsedChanged, this, [this](){ qDebug() << "collapsedChanged"; updateVisualIndexes(); - saveDataToDConfig(); + saveCollapsedToDConfig(); }); connect(this, &TraySortOrderModel::actionsAlwaysVisibleChanged, this, [this](){ qDebug() << "actionsAlwaysVisibleChanged"; @@ -223,6 +223,7 @@ void TraySortOrderModel::setSurfaceVisible(const QString &surfaceId, bool visibl } handlePluginVisibleChanged(surfaceId, visible); updateVisualIndexes(); + saveHiddenIdsToDConfig(); } bool TraySortOrderModel::isDisplayedSurface(const QString &surfaceId) const @@ -242,7 +243,7 @@ void TraySortOrderModel::setDockVisible(const QString &surfaceId, bool visible) } } updateVisualIndexes(); - saveDataToDConfig(); + saveDockHiddenIdsToDConfig(); } bool TraySortOrderModel::isDockVisible(const QString &surfaceId) const @@ -547,12 +548,37 @@ void TraySortOrderModel::loadDataFromDConfig() } void TraySortOrderModel::saveDataToDConfig() +{ + saveSortOrderToDConfig(); + saveHiddenDataToDConfig(); + saveCollapsedToDConfig(); +} + +void TraySortOrderModel::saveSortOrderToDConfig() { m_dconfig->setValue("stashedSurfaceIds", m_stashedIds); m_dconfig->setValue("collapsableSurfaceIds", m_collapsableIds); m_dconfig->setValue("pinnedSurfaceIds", m_pinnedIds); +} + +void TraySortOrderModel::saveHiddenDataToDConfig() +{ + saveHiddenIdsToDConfig(); + saveDockHiddenIdsToDConfig(); +} + +void TraySortOrderModel::saveHiddenIdsToDConfig() +{ m_dconfig->setValue("hiddenSurfaceIds", m_hiddenIds); +} + +void TraySortOrderModel::saveDockHiddenIdsToDConfig() +{ m_dconfig->setValue("dockHiddenSurfaceIds", m_dockHiddenIds); +} + +void TraySortOrderModel::saveCollapsedToDConfig() +{ m_dconfig->setValue("isCollapsed", m_collapsed); } @@ -575,8 +601,12 @@ void TraySortOrderModel::onAvailableSurfacesChanged() } // finally, update visual index updateVisualIndexes(); - // and also save the current sort order - saveDataToDConfig(); + // Save only the data that onAvailableSurfacesChanged may have modified: + // - section lists (via registerSurfaceId → findSection → registerToSection) + // - hiddenIds (via findSection's default-hide logic) + // Do NOT save dockHiddenSurfaceIds here to avoid race conditions with other processes. + saveSortOrderToDConfig(); + saveHiddenIdsToDConfig(); } void TraySortOrderModel::handlePluginVisibleChanged(const QString &surfaceId, bool visible) diff --git a/panels/dock/tray/traysortordermodel.h b/panels/dock/tray/traysortordermodel.h index 69b1a57ef..4f3165f79 100644 --- a/panels/dock/tray/traysortordermodel.h +++ b/panels/dock/tray/traysortordermodel.h @@ -123,6 +123,11 @@ class TraySortOrderModel : public QStandardItemModel QString registerSurfaceId(const QVariantMap &surfaceData); void loadDataFromDConfig(); void saveDataToDConfig(); + void saveSortOrderToDConfig(); + void saveHiddenDataToDConfig(); + void saveHiddenIdsToDConfig(); + void saveDockHiddenIdsToDConfig(); + void saveCollapsedToDConfig(); void handlePluginVisibleChanged(const QString &surfaceId, bool visible); private slots: