From 2735a335f568b6dc27b70980ff9b27d2e88f33c5 Mon Sep 17 00:00:00 2001 From: Lemmy Date: Sat, 17 Jan 2026 23:49:34 -0500 Subject: [PATCH] Wallpaper+Overview: Always process(resize&crop) the wallpaper first then do the blurry overview. Avoid cpu contention. --- Modules/Background/Background.qml | 11 +++++++++++ Modules/Background/Overview.qml | 32 +++++++++++++------------------ Services/UI/WallpaperService.qml | 2 ++ 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/Modules/Background/Background.qml b/Modules/Background/Background.qml index cfac5d221..e009d718e 100644 --- a/Modules/Background/Background.qml +++ b/Modules/Background/Background.qml @@ -361,6 +361,7 @@ Variants { var solidPath = WallpaperService.createSolidColorPath(Settings.data.wallpaper.solidColor.toString()); futureWallpaper = solidPath; performStartupTransition(); + WallpaperService.wallpaperProcessingComplete(modelData.name, solidPath, ""); return; } @@ -370,6 +371,7 @@ Variants { if (WallpaperService.isSolidColorPath(wallpaperPath)) { futureWallpaper = wallpaperPath; performStartupTransition(); + WallpaperService.wallpaperProcessingComplete(modelData.name, wallpaperPath, ""); return; } @@ -385,6 +387,8 @@ Variants { futureWallpaper = wallpaperPath; } performStartupTransition(); + // Pass cached path for blur optimization (already resized) + WallpaperService.wallpaperProcessingComplete(modelData.name, wallpaperPath, success ? cachedPath : ""); }); } @@ -402,6 +406,7 @@ Variants { if (WallpaperService.isSolidColorPath(originalPath)) { futureWallpaper = originalPath; debounceTimer.restart(); + WallpaperService.wallpaperProcessingComplete(modelData.name, originalPath, ""); return; } @@ -410,12 +415,18 @@ Variants { const targetHeight = Math.round(modelData.height * compositorScale); ImageCacheService.getLarge(originalPath, targetWidth, targetHeight, function (cachedPath, success) { + // Ignore stale callback if we've moved on to a different wallpaper + if (originalPath !== transitioningToOriginalPath) { + return; + } if (success) { futureWallpaper = cachedPath; } else { futureWallpaper = originalPath; } debounceTimer.restart(); + // Pass cached path for blur optimization (already resized) + WallpaperService.wallpaperProcessingComplete(modelData.name, originalPath, success ? cachedPath : ""); }); } diff --git a/Modules/Background/Overview.qml b/Modules/Background/Overview.qml index 0509c7a0e..b49ef4a96 100644 --- a/Modules/Background/Overview.qml +++ b/Modules/Background/Overview.qml @@ -17,6 +17,7 @@ Loader { required property ShellScreen modelData property string wallpaper: "" + property string preprocessedWallpaper: "" // Pre-resized wallpaper from Background.qml for blur optimization property string cachedWallpaper: "" property string pendingWallpaper: "" property bool isSolidColor: false @@ -36,33 +37,23 @@ Loader { bgImage.source = ""; } - // External state management + // External state management - wait for wallpaper processing to complete + // before starting blur, to avoid CPU contention on slower systems Connections { target: WallpaperService - function onWallpaperChanged(screenName, path) { + function onWallpaperProcessingComplete(screenName, path, cachedPath) { if (screenName === modelData.name) { + // Use pre-resized image for blur optimization (avoids re-reading/resizing 4K images) + preprocessedWallpaper = cachedPath || ""; wallpaper = path; } } } function setWallpaperInitial() { - if (!WallpaperService || !WallpaperService.isInitialized) { - Qt.callLater(setWallpaperInitial); - return; - } - - // Check if we're in solid color mode - if (Settings.data.wallpaper.useSolidColor) { - var solidPath = WallpaperService.createSolidColorPath(Settings.data.wallpaper.solidColor.toString()); - wallpaper = solidPath; - return; - } - - const wallpaperPath = WallpaperService.getWallpaper(modelData.name); - if (wallpaperPath && wallpaperPath !== wallpaper) { - wallpaper = wallpaperPath; - } + // Overview now receives the initial wallpaper via wallpaperProcessingComplete signal + // from Background.qml, ensuring blur only starts after main wallpaper is processed. + // No direct wallpaper assignment needed here. } function requestBlurredOverview() { @@ -82,7 +73,10 @@ Loader { fadeOutAnim.start(); } - ImageCacheService.getBlurredOverview(wallpaper, targetWidth, targetHeight, tint, isDarkMode, function (path, success) { + // Use pre-resized image if available (optimization: avoids re-reading/resizing large images) + const sourceImage = preprocessedWallpaper || wallpaper; + + ImageCacheService.getBlurredOverview(sourceImage, targetWidth, targetHeight, tint, isDarkMode, function (path, success) { if (path) { useQtBlur = !success; // Use Qt blur fallback if ImageMagick failed pendingWallpaper = path; diff --git a/Services/UI/WallpaperService.qml b/Services/UI/WallpaperService.qml index 479fcff00..5c05cbc21 100644 --- a/Services/UI/WallpaperService.qml +++ b/Services/UI/WallpaperService.qml @@ -41,6 +41,8 @@ Singleton { // Signals for reactive UI updates signal wallpaperChanged(string screenName, string path) // Emitted when a wallpaper changes + signal wallpaperProcessingComplete(string screenName, string path, string cachedPath) + // Emitted when wallpaper processing (resize/cache) is complete. cachedPath is the resized version. signal wallpaperDirectoryChanged(string screenName, string directory) // Emitted when a monitor's directory changes signal wallpaperListChanged(string screenName, int count)