diff --git a/quickshell/services/WallpaperService.qml b/quickshell/services/WallpaperService.qml index 09605a0..c51b6dd 100644 --- a/quickshell/services/WallpaperService.qml +++ b/quickshell/services/WallpaperService.qml @@ -9,6 +9,7 @@ Item { property var wallpapers: [] property string activeCustomWallpaper: "" + property var cachedThemeWallpapers: ({}) // Automatic recolor watcher background daemon Process { @@ -17,7 +18,7 @@ Item { running: true } - // Read saved user wallpaper on startup + // Read saved user wallpaper state on startup Process { id: readWallpaperProc command: ["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/read_wallpaper.py"] @@ -26,12 +27,17 @@ Item { onRead: data => { try { let parsed = JSON.parse(data.trim()) - if (parsed && parsed.wallpaper && parsed.wallpaper !== "") { - root.activeCustomWallpaper = parsed.wallpaper - let fileUrl = parsed.wallpaper.startsWith("file://") ? parsed.wallpaper : "file://" + parsed.wallpaper - Theme.wallpaperPath = fileUrl - let rawPath = parsed.wallpaper.replace("file://", "") - Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) + if (parsed) { + if (parsed.theme_wallpapers && typeof parsed.theme_wallpapers === "object") { + root.cachedThemeWallpapers = parsed.theme_wallpapers + } + if (parsed.wallpaper && parsed.wallpaper !== "") { + root.activeCustomWallpaper = parsed.wallpaper + let fileUrl = parsed.wallpaper.startsWith("file://") ? parsed.wallpaper : "file://" + parsed.wallpaper + Theme.wallpaperPath = fileUrl + let rawPath = parsed.wallpaper.replace("file://", "") + Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) + } } } catch (e) {} } @@ -68,14 +74,22 @@ Item { scanProc.running = true } - function applyWallpaper(filePath) { + function applyWallpaper(filePath, variantName) { if (!filePath) return; + let vName = variantName || (Theme ? Theme.currentVariant : "") activeCustomWallpaper = filePath let fileUrl = filePath.startsWith("file://") ? filePath : "file://" + filePath Theme.wallpaperPath = fileUrl let rawPath = filePath.replace("file://", "") + + if (vName !== "") { + let updatedMap = Object.assign({}, cachedThemeWallpapers) + updatedMap[vName] = rawPath + cachedThemeWallpapers = updatedMap + } + Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) - Quickshell.execDetached(["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/save_wallpaper.py", rawPath]) + Quickshell.execDetached(["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/save_wallpaper.py", rawPath, vName]) } function refresh() { diff --git a/quickshell/services/python/read_wallpaper.py b/quickshell/services/python/read_wallpaper.py index 49a72de..4fb86d3 100755 --- a/quickshell/services/python/read_wallpaper.py +++ b/quickshell/services/python/read_wallpaper.py @@ -1,19 +1,39 @@ #!/usr/bin/env python3 import json import os +import sys def read_wallpaper(): + target_variant = sys.argv[1].strip() if len(sys.argv) > 1 else "" user_file = os.path.expanduser('~/.config/quickshell_user_wallpaper.json') + if os.path.exists(user_file): try: with open(user_file, 'r', encoding='utf-8') as f: data = json.load(f) - if isinstance(data, dict) and data.get("wallpaper"): - print(json.dumps(data), flush=True) + if isinstance(data, dict): + tw = data.get("theme_wallpapers", {}) + active_v = target_variant or data.get("active_variant", "") + + if active_v and isinstance(tw, dict) and tw.get(active_v): + cached_wp = tw.get(active_v) + raw = cached_wp.replace("file://", "") + if os.path.exists(raw): + print(json.dumps({"wallpaper": cached_wp, "variant": active_v, "theme_wallpapers": tw}), flush=True) + return + + if data.get("wallpaper"): + raw = data["wallpaper"].replace("file://", "") + if os.path.exists(raw): + print(json.dumps({"wallpaper": data["wallpaper"], "variant": active_v, "theme_wallpapers": tw}), flush=True) + return + + print(json.dumps({"wallpaper": "", "variant": active_v, "theme_wallpapers": tw}), flush=True) return except Exception: pass - print(json.dumps({"wallpaper": ""}), flush=True) + + print(json.dumps({"wallpaper": "", "variant": target_variant, "theme_wallpapers": {}}), flush=True) if __name__ == '__main__': read_wallpaper() diff --git a/quickshell/services/python/save_wallpaper.py b/quickshell/services/python/save_wallpaper.py index 6581917..f5e7874 100755 --- a/quickshell/services/python/save_wallpaper.py +++ b/quickshell/services/python/save_wallpaper.py @@ -6,9 +6,30 @@ import sys def save_wallpaper(): if len(sys.argv) < 2: return - wp_path = sys.argv[1] + wp_path = sys.argv[1].strip() + variant = sys.argv[2].strip() if len(sys.argv) > 2 else "" + user_file = os.path.expanduser('~/.config/quickshell_user_wallpaper.json') - data = {"wallpaper": wp_path} + data = {"theme_wallpapers": {}, "active_variant": ""} + + if os.path.exists(user_file): + try: + with open(user_file, 'r', encoding='utf-8') as f: + data = json.load(f) + if not isinstance(data, dict): + data = {"theme_wallpapers": {}, "active_variant": ""} + except Exception: + data = {"theme_wallpapers": {}, "active_variant": ""} + + if "theme_wallpapers" not in data or not isinstance(data["theme_wallpapers"], dict): + data["theme_wallpapers"] = {} + + if variant: + data["theme_wallpapers"][variant] = wp_path + data["active_variant"] = variant + + data["wallpaper"] = wp_path + try: with open(user_file, 'w', encoding='utf-8') as f: json.dump(data, f, indent=2) diff --git a/quickshell/theme/Theme.qml b/quickshell/theme/Theme.qml index d6baf9d..0714d93 100644 --- a/quickshell/theme/Theme.qml +++ b/quickshell/theme/Theme.qml @@ -166,12 +166,13 @@ Item { let imgPath = getVariantWallpaper(v.name) if (WallpaperService) { - WallpaperService.applyWallpaper(imgPath) + WallpaperService.applyWallpaper(imgPath, v.name) } else { wallpaperPath = imgPath.startsWith("file://") ? imgPath : "file://" + imgPath let rawPath = imgPath.replace("file://", "") Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) } + let rawPath = imgPath.replace("file://", "") Quickshell.execDetached(["sh", "-c", "wallust run '" + rawPath + "' || ~/.cargo/bin/wallust run '" + rawPath + "' 2>/dev/null || true"]) // Persist selected theme variant to disk @@ -197,8 +198,17 @@ Item { } function getVariantWallpaper(varName) { + if (!varName || varName === "") return "" + let cur = varName.toLowerCase().trim() + + // 1. Check if user set/cached a custom wallpaper for this specific theme variant + if (WallpaperService && WallpaperService.cachedThemeWallpapers && WallpaperService.cachedThemeWallpapers[varName]) { + let cached = WallpaperService.cachedThemeWallpapers[varName] + if (cached && cached !== "") return cached + } + + // 2. Check scanned wallpapers folder for matching variant folder if (WallpaperService && WallpaperService.wallpapers) { - let cur = varName.toLowerCase().trim() for (let i = 0; i < WallpaperService.wallpapers.length; i++) { let wp = WallpaperService.wallpapers[i] if ((wp.variant || "").toLowerCase().trim() === cur) {