From a19e608fa4196bf689ade90cc7054058535811df Mon Sep 17 00:00:00 2001 From: zhaofangxun Date: Tue, 8 Sep 2026 11:10:15 +0800 Subject: [PATCH 1/2] fix: defer palette type switch and protect against null icons P0: Defer DGuiApplicationHelper::setPaletteType() call in WidgetPlugin::onDockColorThemeChanged using QTimer::singleShot(0), allowing theme_changed events (icon theme name update) to be processed first in the same batch of Wayland events. P1: In CommonIconButton::setIcon(), when QIcon::fromTheme() returns null, try fallback -> default icon -> keep old icon (don't clear). In refreshIcon(), if icon is still null after setState(), schedule a 50ms delayed retry to handle icon theme not yet loaded. Fixes intermittent black icons when switching dark mode on 4K/225%. --- plugins/dde-dock/common/commoniconbutton.cpp | 20 +++++++++++++++----- src/loader/widgetplugin.cpp | 5 ++++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/plugins/dde-dock/common/commoniconbutton.cpp b/plugins/dde-dock/common/commoniconbutton.cpp index f5adb4a48..80385c3b2 100644 --- a/plugins/dde-dock/common/commoniconbutton.cpp +++ b/plugins/dde-dock/common/commoniconbutton.cpp @@ -133,15 +133,19 @@ void CommonIconButton::setIcon(const QString &icon, const QString &fallback, con addDarkMark(tmp); addDarkMark(tmpFallback); } - m_icon = QIcon::fromTheme(tmp); + QIcon newIcon = QIcon::fromTheme(tmp); - if (m_icon.isNull()) { - m_icon = QIcon::fromTheme(tmpFallback); + if (newIcon.isNull()) { + newIcon = QIcon::fromTheme(tmpFallback); } - if (m_icon.isNull()) { + if (newIcon.isNull()) { QString defaultIcon = m_fileMapping[State::Default].first; - m_icon = QIcon::fromTheme(defaultIcon); + newIcon = QIcon::fromTheme(defaultIcon); + } + + if (!newIcon.isNull()) { + m_icon = newIcon; } update(); } @@ -213,6 +217,12 @@ void CommonIconButton::mouseReleaseEvent(QMouseEvent *event) void CommonIconButton::refreshIcon() { setState(m_state); + + if (m_icon.isNull()) { + QTimer::singleShot(50, this, [this]() { + refreshIcon(); + }); + } } void CommonIconButton::setIconSize(const QSize &size) diff --git a/src/loader/widgetplugin.cpp b/src/loader/widgetplugin.cpp index c5f3c276d..90d1f3674 100644 --- a/src/loader/widgetplugin.cpp +++ b/src/loader/widgetplugin.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -337,7 +338,9 @@ void WidgetPlugin::updateDockContainerState(PluginsItemInterface *itemInter, boo void WidgetPlugin::onDockColorThemeChanged(uint32_t type) { qDebug() << "onDockColorThemeChanged:" << type; - DGuiApplicationHelper::instance()->setPaletteType(static_cast(type)); + QTimer::singleShot(0, this, [type]() { + DGuiApplicationHelper::instance()->setPaletteType(static_cast(type)); + }); } void WidgetPlugin::onDockPositionChanged(uint32_t position) From 023d45834b26033dc9d299c175b3176dc0376317 Mon Sep 17 00:00:00 2001 From: zhaofangxun Date: Tue, 8 Sep 2026 11:24:14 +0800 Subject: [PATCH 2/2] fix: add max retry limit to refreshIcon() to prevent infinite loop --- plugins/dde-dock/common/commoniconbutton.cpp | 14 +++++++++++--- plugins/dde-dock/common/commoniconbutton.h | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/plugins/dde-dock/common/commoniconbutton.cpp b/plugins/dde-dock/common/commoniconbutton.cpp index 80385c3b2..ce2cbde69 100644 --- a/plugins/dde-dock/common/commoniconbutton.cpp +++ b/plugins/dde-dock/common/commoniconbutton.cpp @@ -219,9 +219,17 @@ void CommonIconButton::refreshIcon() setState(m_state); if (m_icon.isNull()) { - QTimer::singleShot(50, this, [this]() { - refreshIcon(); - }); + // 主题切换后图标主题可能尚未加载完成,进行有限次重试 + if (m_refreshRetryCount < kMaxRefreshRetries) { + m_refreshRetryCount++; + QTimer::singleShot(50, this, [this]() { + refreshIcon(); + }); + } else { + m_refreshRetryCount = 0; + } + } else { + m_refreshRetryCount = 0; } } diff --git a/plugins/dde-dock/common/commoniconbutton.h b/plugins/dde-dock/common/commoniconbutton.h index bf744b95e..fdc26ec22 100644 --- a/plugins/dde-dock/common/commoniconbutton.h +++ b/plugins/dde-dock/common/commoniconbutton.h @@ -73,6 +73,9 @@ public Q_SLOTS: QSize m_iconSize; qreal m_rotation; QPalette m_defaultPalette; + + static constexpr int kMaxRefreshRetries = 10; + int m_refreshRetryCount = 0; }; #endif // DOCKICONBUTTON_H