feat: implement per-theme wallpaper state caching across all 35+ theme variants

This commit is contained in:
Sho 2026-08-02 01:42:37 +09:00
parent 1419be11f0
commit 7e2cd72e72
4 changed files with 81 additions and 16 deletions

View File

@ -9,6 +9,7 @@ Item {
property var wallpapers: [] property var wallpapers: []
property string activeCustomWallpaper: "" property string activeCustomWallpaper: ""
property var cachedThemeWallpapers: ({})
// Automatic recolor watcher background daemon // Automatic recolor watcher background daemon
Process { Process {
@ -17,7 +18,7 @@ Item {
running: true running: true
} }
// Read saved user wallpaper on startup // Read saved user wallpaper state on startup
Process { Process {
id: readWallpaperProc id: readWallpaperProc
command: ["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/read_wallpaper.py"] command: ["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/read_wallpaper.py"]
@ -26,12 +27,17 @@ Item {
onRead: data => { onRead: data => {
try { try {
let parsed = JSON.parse(data.trim()) let parsed = JSON.parse(data.trim())
if (parsed && parsed.wallpaper && parsed.wallpaper !== "") { if (parsed) {
root.activeCustomWallpaper = parsed.wallpaper if (parsed.theme_wallpapers && typeof parsed.theme_wallpapers === "object") {
let fileUrl = parsed.wallpaper.startsWith("file://") ? parsed.wallpaper : "file://" + parsed.wallpaper root.cachedThemeWallpapers = parsed.theme_wallpapers
Theme.wallpaperPath = fileUrl }
let rawPath = parsed.wallpaper.replace("file://", "") if (parsed.wallpaper && parsed.wallpaper !== "") {
Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) 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) {} } catch (e) {}
} }
@ -68,14 +74,22 @@ Item {
scanProc.running = true scanProc.running = true
} }
function applyWallpaper(filePath) { function applyWallpaper(filePath, variantName) {
if (!filePath) return; if (!filePath) return;
let vName = variantName || (Theme ? Theme.currentVariant : "")
activeCustomWallpaper = filePath activeCustomWallpaper = filePath
let fileUrl = filePath.startsWith("file://") ? filePath : "file://" + filePath let fileUrl = filePath.startsWith("file://") ? filePath : "file://" + filePath
Theme.wallpaperPath = fileUrl Theme.wallpaperPath = fileUrl
let rawPath = filePath.replace("file://", "") 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(["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() { function refresh() {

View File

@ -1,19 +1,39 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import json import json
import os import os
import sys
def read_wallpaper(): 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') user_file = os.path.expanduser('~/.config/quickshell_user_wallpaper.json')
if os.path.exists(user_file): if os.path.exists(user_file):
try: try:
with open(user_file, 'r', encoding='utf-8') as f: with open(user_file, 'r', encoding='utf-8') as f:
data = json.load(f) data = json.load(f)
if isinstance(data, dict) and data.get("wallpaper"): if isinstance(data, dict):
print(json.dumps(data), flush=True) 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 return
except Exception: except Exception:
pass pass
print(json.dumps({"wallpaper": ""}), flush=True)
print(json.dumps({"wallpaper": "", "variant": target_variant, "theme_wallpapers": {}}), flush=True)
if __name__ == '__main__': if __name__ == '__main__':
read_wallpaper() read_wallpaper()

View File

@ -6,9 +6,30 @@ import sys
def save_wallpaper(): def save_wallpaper():
if len(sys.argv) < 2: if len(sys.argv) < 2:
return 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') 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: try:
with open(user_file, 'w', encoding='utf-8') as f: with open(user_file, 'w', encoding='utf-8') as f:
json.dump(data, f, indent=2) json.dump(data, f, indent=2)

View File

@ -166,12 +166,13 @@ Item {
let imgPath = getVariantWallpaper(v.name) let imgPath = getVariantWallpaper(v.name)
if (WallpaperService) { if (WallpaperService) {
WallpaperService.applyWallpaper(imgPath) WallpaperService.applyWallpaper(imgPath, v.name)
} else { } else {
wallpaperPath = imgPath.startsWith("file://") ? imgPath : "file://" + imgPath wallpaperPath = imgPath.startsWith("file://") ? imgPath : "file://" + imgPath
let rawPath = imgPath.replace("file://", "") let rawPath = imgPath.replace("file://", "")
Quickshell.execDetached(["plasma-apply-wallpaperimage", rawPath]) 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"]) Quickshell.execDetached(["sh", "-c", "wallust run '" + rawPath + "' || ~/.cargo/bin/wallust run '" + rawPath + "' 2>/dev/null || true"])
// Persist selected theme variant to disk // Persist selected theme variant to disk
@ -197,8 +198,17 @@ Item {
} }
function getVariantWallpaper(varName) { 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) { if (WallpaperService && WallpaperService.wallpapers) {
let cur = varName.toLowerCase().trim()
for (let i = 0; i < WallpaperService.wallpapers.length; i++) { for (let i = 0; i < WallpaperService.wallpapers.length; i++) {
let wp = WallpaperService.wallpapers[i] let wp = WallpaperService.wallpapers[i]
if ((wp.variant || "").toLowerCase().trim() === cur) { if ((wp.variant || "").toLowerCase().trim() === cur) {