From b47de894692324d07cdd9d5411876d5e5156a6a6 Mon Sep 17 00:00:00 2001 From: zhangkun Date: Mon, 20 Oct 2025 17:23:29 +0800 Subject: [PATCH] feat: refactor wallpaper slideshow for multi-monitor support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Added getCurrentWorkspaceBackgroundForMonitor method to retrieve wallpaper for specific monitor 2. Refactored configuration storage to use monitor names directly instead of workspace-monitor combinations 3. Implemented per-monitor wallpaper type tracking to handle different wallpaper types on different screens 4. Added screen validation to ensure operations only affect valid monitors 5. Updated configuration migration to convert old workspace-monitor format to monitor-only format 6. Improved wallpaper change detection to handle multi-monitor scenarios Log: Enhanced wallpaper slideshow to better support multi-monitor setups Influence: 1. Test wallpaper slideshow on single monitor setup 2. Test wallpaper slideshow on multi-monitor setup with different wallpapers 3. Verify configuration migration from old format to new format 4. Test wallpaper change detection when switching between different wallpaper types 5. Verify slideshow scheduling works correctly for each monitor independently 6. Test with invalid monitor names to ensure proper error handling feat: 重构壁纸轮播功能以支持多显示器 1. 新增 getCurrentWorkspaceBackgroundForMonitor 方法用于获取特定显示器的 壁纸 2. 重构配置存储,直接使用显示器名称而非工作区-显示器组合 3. 实现按显示器跟踪壁纸类型,以处理不同屏幕上的不同壁纸类型 4. 添加屏幕验证确保操作仅影响有效显示器 5. 更新配置迁移以将旧的工作区-显示器格式转换为仅显示器格式 6. 改进壁纸变更检测以处理多显示器场景 Log: 增强壁纸轮播功能以更好地支持多显示器设置 Influence: 1. 在单显示器设置下测试壁纸轮播功能 2. 在多显示器设置下测试壁纸轮播功能,使用不同壁纸 3. 验证从旧格式到新格式的配置迁移 4. 测试在不同壁纸类型之间切换时的壁纸变更检测 5. 验证每个显示器的轮播调度独立正常工作 6. 使用无效显示器名称测试以确保正确的错误处理 pms: BUG-333269 pms: BUG-333263 --- .../appearancedbusproxy.cpp | 5 + .../wallpaperslideshow/appearancedbusproxy.h | 1 + .../wallpaperslideshow/commondefine.h | 2 + .../wallpaperslideshow/slideshowmanager.cpp | 144 ++++++++++++------ .../wallpaperslideshow/slideshowmanager.h | 4 +- 5 files changed, 111 insertions(+), 45 deletions(-) diff --git a/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.cpp b/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.cpp index 44e6f7d0..0e004de8 100644 --- a/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.cpp +++ b/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.cpp @@ -54,6 +54,11 @@ QString AppearanceDBusProxy::getCurrentWorkspaceBackground() return QDBusPendingReply(m_appearanceInterface->asyncCall(QStringLiteral("GetCurrentWorkspaceBackground"))); } +QString AppearanceDBusProxy::getCurrentWorkspaceBackgroundForMonitor(const QString &monitor) +{ + return QDBusPendingReply(m_appearanceInterface->asyncCall(QStringLiteral("GetCurrentWorkspaceBackgroundForMonitor"), QVariant::fromValue(monitor))); +} + void AppearanceDBusProxy::SetGreeterBackground(const QString &url) { m_appearanceInterface->asyncCall(QStringLiteral("Set"), QStringLiteral("greeterbackground"), QVariant::fromValue(url)); diff --git a/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.h b/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.h index bc1b6c3d..c98dbde7 100644 --- a/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.h +++ b/src/plugin-qt/wallpaperslideshow/appearancedbusproxy.h @@ -17,6 +17,7 @@ class AppearanceDBusProxy : public QObject explicit AppearanceDBusProxy(QObject *parent = nullptr); void SetCurrentWorkspaceBackgroundForMonitor(const QString &url, const QString &screenName); QString getCurrentWorkspaceBackground(); + QString getCurrentWorkspaceBackgroundForMonitor(const QString &monitor); void SetGreeterBackground(const QString &url); public Q_SLOTS: diff --git a/src/plugin-qt/wallpaperslideshow/commondefine.h b/src/plugin-qt/wallpaperslideshow/commondefine.h index 47ee2274..b20e6fc9 100644 --- a/src/plugin-qt/wallpaperslideshow/commondefine.h +++ b/src/plugin-qt/wallpaperslideshow/commondefine.h @@ -19,6 +19,8 @@ const QString APPEARANCE_INTERFACE = "org.deepin.dde.Appearance1"; #define WALLPAPER_SLIDESHOW_PATH "/org/deepin/dde/WallpaperSlideshow" #define WALLPAPER_SLIDESHOW_INTERFACE "org.deepin.dde.WallpaperSlideshow" +#define WS_CONFIG_PATH utils::GetUserConfigDir() + "/deepin/dde-daemon/appearance/wallpaper-slideshow.json" + #define SCHEME_FILE "file://" #define WSPOLICYLOGIN "login" diff --git a/src/plugin-qt/wallpaperslideshow/slideshowmanager.cpp b/src/plugin-qt/wallpaperslideshow/slideshowmanager.cpp index 09210698..22e765a8 100644 --- a/src/plugin-qt/wallpaperslideshow/slideshowmanager.cpp +++ b/src/plugin-qt/wallpaperslideshow/slideshowmanager.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -31,22 +32,27 @@ SlideshowManager::~SlideshowManager() } -bool SlideshowManager::doSetWallpaperSlideShow(const QString &monitorName,const QString &wallpaperSlideShow) +bool SlideshowManager::doSetWallpaperSlideShow(const QString &monitorName, const QString &wallpaperSlideShow) { - int idx = m_dbusProxy->GetCurrentWorkspace(); + if (!isValidScreen(monitorName)) { + qWarning() << "monitor can not found: " << monitorName; + return false; + } + QByteArray jsonData = m_wallpaperSlideShow.toUtf8(); + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(jsonData, &err); - QJsonDocument doc = QJsonDocument::fromJson(wallpaperSlideShow.toLatin1()); - QJsonObject cfgObj = doc.object(); + QJsonObject cfgObj; + if (err.error == QJsonParseError::NoError && doc.isObject()) { + cfgObj = doc.object(); + } - QString key = QString("%1&&%2").arg(monitorName).arg(idx); + cfgObj[monitorName] = wallpaperSlideShow; - cfgObj[key] = wallpaperSlideShow; + doc.setObject(cfgObj); - QJsonDocument docTmp; - docTmp.setObject(cfgObj); - QString value = docTmp.toJson(QJsonDocument::Compact); + QString value = QString::fromUtf8(doc.toJson(QJsonDocument::Compact)); - m_curMonitorSpace = key; setWallpaperSlideShow(value); return true; } @@ -70,15 +76,11 @@ bool SlideshowManager::setWallpaperSlideShow(const QString &value) QString SlideshowManager::doGetWallpaperSlideShow(QString monitorName) { - int index = m_dbusProxy->GetCurrentWorkspace(); - QJsonDocument doc = QJsonDocument::fromJson(m_wallpaperSlideShow.toLatin1()); QVariantMap tempMap = doc.object().toVariantMap(); - QString key = QString("%1&&%2").arg(monitorName).arg(index); - - if (tempMap.count(key) == 1) { - return tempMap[key].toString(); + if (tempMap.count(monitorName) == 1) { + return tempMap[monitorName].toString(); } return ""; @@ -100,6 +102,11 @@ void SlideshowManager::updateWSPolicy(QString policy) QVariantMap config = doc.object().toVariantMap(); for (auto iter : config.toStdMap()) { + const QString screenName = iter.first; + if (screenName.isEmpty()) { + qWarning() << "screenName is empty: " << iter.first; + continue; + } if (m_wsSchedulerMap.count(iter.first) == 0) { QSharedPointer wallpaperScheduler( new WallpaperScheduler(std::bind(&SlideshowManager::autoChangeBg, this, std::placeholders::_1, std::placeholders::_2))); @@ -107,11 +114,11 @@ void SlideshowManager::updateWSPolicy(QString policy) } if (m_wsLoopMap.count(iter.first) == 0) { - m_wsLoopMap[iter.first] = QSharedPointer(new WallpaperLoop(m_wallpaperType)); + m_wsLoopMap[iter.first] = QSharedPointer(new WallpaperLoop(m_wallpaperType[screenName])); } - m_wsLoopMap[iter.first]->updateWallpaperType(m_wallpaperType); + m_wsLoopMap[iter.first]->updateWallpaperType(m_wallpaperType[screenName]); - if (m_curMonitorSpace == iter.first && WallpaperLoopConfigManger::isValidWSPolicy(iter.second.toString())) { + if (WallpaperLoopConfigManger::isValidWSPolicy(iter.second.toString())) { bool bOk; int nSec = iter.second.toString().toInt(&bOk); if (bOk) { @@ -129,10 +136,13 @@ void SlideshowManager::updateWSPolicy(QString policy) void SlideshowManager::loadWSConfig() { WallpaperLoopConfigManger wallConfig; - QString fileName = utils::GetUserConfigDir() + "/deepin/dde-daemon/appearance/wallpaper-slideshow.json"; - WallpaperLoopConfigManger::WallpaperLoopConfigMap cfg = wallConfig.loadWSConfig(fileName); + WallpaperLoopConfigManger::WallpaperLoopConfigMap cfg = wallConfig.loadWSConfig(WS_CONFIG_PATH); for (auto monitorSpace : cfg.keys()) { + const QString screenName = monitorSpace; + if (screenName.isEmpty()) { + continue; + } if (m_wsSchedulerMap.count(monitorSpace) == 0) { QSharedPointer wallpaperScheduler( new WallpaperScheduler(std::bind(&SlideshowManager::autoChangeBg, this, std::placeholders::_1, std::placeholders::_2))); @@ -142,7 +152,7 @@ void SlideshowManager::loadWSConfig() m_wsSchedulerMap[monitorSpace]->setLastChangeTime(cfg[monitorSpace].lastChange); if (m_wsLoopMap.count(monitorSpace) == 0) { - m_wsLoopMap[monitorSpace] = QSharedPointer(new WallpaperLoop(m_wallpaperType)); + m_wsLoopMap[monitorSpace] = QSharedPointer(new WallpaperLoop(m_wallpaperType.value(screenName))); m_wsLoopMap[monitorSpace]->updateWallpaperType(Backgrounds::BT_Custom); } @@ -185,17 +195,7 @@ void SlideshowManager::autoChangeBg(QString monitorSpace, QDateTime date) return; } - QString strIndex = QString::number(m_dbusProxy->GetCurrentWorkspace()); - - QStringList monitorlist = monitorSpace.split("&&"); - if (monitorlist.size() != 2) { - qWarning() << "monitorSpace format error"; - return; - } - - if (strIndex == monitorlist.at(1)) { - setMonitorBackground(monitorlist.at(0), file); - } + setMonitorBackground(monitorSpace, file); saveWSConfig(monitorSpace, date); } @@ -213,6 +213,12 @@ void SlideshowManager::init() QVariantMap tempMap = doc.object().toVariantMap(); for (auto iter : tempMap.toStdMap()) { + const QString screenName = iter.first.split("&&").first(); + if (screenName.isEmpty()) { + qWarning() << "screenName is empty: " << iter.first; + continue; + } + if (m_wsSchedulerMap.count(iter.first) != 1) { QSharedPointer wallpaperScheduler( new WallpaperScheduler(std::bind(&SlideshowManager::autoChangeBg, this, std::placeholders::_1, std::placeholders::_2))); @@ -220,7 +226,7 @@ void SlideshowManager::init() } if (!m_wsLoopMap.contains(iter.first)) { - m_wsLoopMap[iter.first] = QSharedPointer(new WallpaperLoop(m_wallpaperType)); + m_wsLoopMap[iter.first] = QSharedPointer(new WallpaperLoop(m_wallpaperType.value(screenName))); } if (WallpaperLoopConfigManger::isValidWSPolicy(iter.second.toString())) { @@ -246,7 +252,38 @@ void SlideshowManager::init() void SlideshowManager::loadConfig() { - m_wallpaperSlideShow = m_settingDconfig->value(GSKEYWALLPAPERSLIDESHOW).toString(); + QFile::remove(WS_CONFIG_PATH); + + const QString wallpaperSlideShow = m_settingDconfig->value(GSKEYWALLPAPERSLIDESHOW).toString(); + + QJsonParseError err; + QJsonDocument doc = QJsonDocument::fromJson(wallpaperSlideShow.toLatin1(), &err); + if (err.error != QJsonParseError::NoError) { + qWarning() << "parse wallpaperSlideShow failed:" << err.errorString(); + return; + } + + QJsonObject rootObject = doc.object(); + QJsonObject newObject; + + // 兼容老配置,去掉&& + for (auto it = rootObject.begin(); it != rootObject.end(); ++it) { + QString key = it.key(); + QJsonValue value = it.value(); + + if (key.contains("&&")) { + QString newKey = key.split("&&").first(); + newObject[newKey] = value; + } else { + newObject[key] = value; + } + } + + QJsonDocument newDoc(newObject); + m_wallpaperSlideShow = newDoc.toJson(QJsonDocument::Compact); + + m_settingDconfig->setValue(GSKEYWALLPAPERSLIDESHOW, m_wallpaperSlideShow); + onWallpaperChanged(); } @@ -329,17 +366,38 @@ void SlideshowManager::handlePrepareForSleep(bool sleep) void SlideshowManager::onWallpaperChanged() { - const auto wallpaper = m_dbusProxy->getCurrentWorkspaceBackground(); + qDebug() << "wallpaper changed"; Backgrounds::instance()->refreshBackground(); - - for (auto it = m_wsLoopMap.begin(); it != m_wsLoopMap.end(); ++it) { - it.value()->updateLoopList(); + bool update = false; + for (const auto &screen : qApp->screens()) { + if (screen) { + const QString &screenName = screen->name(); + const auto &wallpaper = m_dbusProxy->getCurrentWorkspaceBackgroundForMonitor(screenName); + const auto &wallpaperType = Backgrounds::getBackgroundType(wallpaper); + + if (m_wallpaperType.value(screenName) != wallpaperType) { + qInfo() << "wallpaperSlideshow type changed: old is " << m_wallpaperType[screenName] << "new: " << wallpaperType << "screen: " << screenName; + m_wallpaperType[screenName] = wallpaperType; + update = true; + } + } } - auto wallpaperType = Backgrounds::getBackgroundType(wallpaper); - if (wallpaperType != m_wallpaperType) { - qInfo() << "wallpaperSlideshow type changed: old is " << m_wallpaperType << "new: " << wallpaperType; - m_wallpaperType = wallpaperType; + if (update) { updateWSPolicy(m_wallpaperSlideShow); + + for (auto it = m_wsLoopMap.begin(); it != m_wsLoopMap.end(); ++it) { + it.value()->updateLoopList(); + } + } +} + +bool SlideshowManager::isValidScreen(const QString &screenName) +{ + for (auto screen : qApp->screens()) { + if (screen && screen->name() == screenName) { + return true; + } } + return false; } diff --git a/src/plugin-qt/wallpaperslideshow/slideshowmanager.h b/src/plugin-qt/wallpaperslideshow/slideshowmanager.h index a0a5bfd6..3f4543b3 100644 --- a/src/plugin-qt/wallpaperslideshow/slideshowmanager.h +++ b/src/plugin-qt/wallpaperslideshow/slideshowmanager.h @@ -42,6 +42,7 @@ private slots: private: void init(); void loadConfig(); + bool isValidScreen(const QString &screenName); signals: void propertyChanged(const QString &name, const QVariant &value); @@ -52,6 +53,5 @@ private slots: QMap> m_wsLoopMap; QSharedPointer m_dbusProxy; QString m_wallpaperSlideShow; - QString m_curMonitorSpace; - Backgrounds::BackgroundType m_wallpaperType; + QMap m_wallpaperType; };