From 30db6792073e83c1a60e8d01999ce6613db1f1b0 Mon Sep 17 00:00:00 2001 From: ItsLemmy Date: Sat, 29 Nov 2025 11:22:53 -0500 Subject: [PATCH] Wallpapers: moved persistent data to their own file in ~/.cache/noctalia/wallpapers.json !! no migration path, user will have to set their wallpaper at least once !! --- Assets/settings-default.json | 4 +- Commons/Settings.qml | 3 +- Commons/ShellState.qml | 18 ++----- Services/UI/WallpaperService.qml | 89 +++++++++++++++++++------------- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/Assets/settings-default.json b/Assets/settings-default.json index e999a313..b30c3a85 100644 --- a/Assets/settings-default.json +++ b/Assets/settings-default.json @@ -154,9 +154,7 @@ "wallhavenPurity": "100", "wallhavenResolutionMode": "atleast", "wallhavenResolutionWidth": "", - "wallhavenResolutionHeight": "", - "defaultWallpaper": "", - "monitors": [] + "wallhavenResolutionHeight": "" }, "appLauncher": { "enableClipboardHistory": false, diff --git a/Commons/Settings.qml b/Commons/Settings.qml index 489eedf4..fb0cd049 100644 --- a/Commons/Settings.qml +++ b/Commons/Settings.qml @@ -34,7 +34,6 @@ Singleton { readonly property string defaultAvatar: Quickshell.env("HOME") + "/.face" readonly property string defaultVideosDirectory: Quickshell.env("HOME") + "/Videos" readonly property string defaultWallpapersDirectory: Quickshell.env("HOME") + "/Pictures/Wallpapers" - readonly property string defaultWallpaper: Quickshell.shellDir + "/Assets/Wallpaper/noctalia.png" // Signal emitted when settings are loaded after startupcale changes signal settingsLoaded @@ -77,7 +76,7 @@ Singleton { Timer { id: saveTimer running: false - interval: 1000 + interval: 500 onTriggered: { root.saveImmediate(); } diff --git a/Commons/ShellState.qml b/Commons/ShellState.qml index 0b72f817..a7d499cd 100644 --- a/Commons/ShellState.qml +++ b/Commons/ShellState.qml @@ -61,9 +61,6 @@ Singleton { schemes: [], timestamp: 0 }) - - // WallpaperService: current wallpapers per screen - property var wallpapers: ({}) } onLoaded: { @@ -86,7 +83,7 @@ Singleton { // Debounced save timer Timer { id: saveTimer - interval: 300 + interval: 500 onTriggered: performSave() } @@ -174,16 +171,6 @@ Singleton { }; } - // Wallpapers (WallpaperService) - function setWallpapers(wallpapersData) { - adapter.wallpapers = wallpapersData; - save(); - } - - function getWallpapers() { - return adapter.wallpapers || {}; - } - // ----------------------------------------------------- function buildStateSnapshot() { try { @@ -196,8 +183,9 @@ Singleton { doNotDisturb: NotificationService.doNotDisturb, noctaliaPerformanceMode: PowerProfileService.noctaliaPerformanceMode, barVisible: BarService.isVisible, + wallpapers: WallpaperService.currentWallpapers || {}, + // ------------- display: shellStateData.display || {}, - wallpapers: shellStateData.wallpapers || {}, notificationsState: shellStateData.notificationsState || {}, changelogState: shellStateData.changelogState || {}, colorSchemesList: shellStateData.colorSchemesList || {} diff --git a/Services/UI/WallpaperService.qml b/Services/UI/WallpaperService.qml index f6c5cc4a..c33222da 100644 --- a/Services/UI/WallpaperService.qml +++ b/Services/UI/WallpaperService.qml @@ -22,12 +22,15 @@ Singleton { property var wallpaperLists: ({}) property int scanningCount: 0 - readonly property bool scanning: (scanningCount > 0) // Cache for current wallpapers - can be updated directly since we use signals for notifications property var currentWallpapers: ({}) property bool isInitialized: false + property string wallpaperCacheFile: "" + + readonly property bool scanning: (scanningCount > 0) + readonly property string defaultWallpaper: Quickshell.shellDir + "/Assets/Wallpaper/noctalia.png" // Signals for reactive UI updates signal wallpaperChanged(string screenName, string path) @@ -83,40 +86,19 @@ Singleton { translateModels(); - // Load wallpapers from ShellState first (faster), then fall back to Settings - currentWallpapers = ({}); + // Initialize cache file path + Qt.callLater(() => { + if (typeof Settings !== 'undefined' && Settings.cacheDir) { + wallpaperCacheFile = Settings.cacheDir + "wallpapers.json"; + wallpaperCacheView.path = wallpaperCacheFile; + } + }); - if (typeof ShellState !== 'undefined' && ShellState.isLoaded) { - var cachedWallpapers = ShellState.getWallpapers(); - if (cachedWallpapers && Object.keys(cachedWallpapers).length > 0) { - currentWallpapers = cachedWallpapers; - Logger.d("Wallpaper", "Loaded wallpapers from ShellState"); - } else { - // Fall back to Settings if ShellState is empty - loadFromSettings(); - } - } else { - // ShellState not ready yet, load from Settings - loadFromSettings(); - } - - isInitialized = true; + // Note: isInitialized will be set to true in wallpaperCacheView.onLoaded Logger.d("Wallpaper", "Triggering initial wallpaper scan"); Qt.callLater(refreshWallpapersList); } - function loadFromSettings() { - var monitors = Settings.data.wallpaper.monitors || []; - for (var i = 0; i < monitors.length; i++) { - if (monitors[i].name && monitors[i].wallpaper) { - currentWallpapers[monitors[i].name] = monitors[i].wallpaper; - } - } - Logger.d("Wallpaper", "Loaded wallpapers from Settings"); - - // Migration is now handled in Settings.qml - } - // ------------------------------------------------- function translateModels() { // Wait for i18n to be ready by retrying every time @@ -250,7 +232,7 @@ Singleton { // ------------------------------------------------------------------- // Get specific monitor wallpaper - now from cache function getWallpaper(screenName) { - return currentWallpapers[screenName] || Settings.defaultWallpaper; + return currentWallpapers[screenName] || root.defaultWallpaper; } // ------------------------------------------------------------------- @@ -290,10 +272,8 @@ Singleton { // Update cache directly currentWallpapers[screenName] = path; - // Save to ShellState (wallpaper paths now only stored here, not in Settings) - if (typeof ShellState !== 'undefined' && ShellState.isLoaded) { - ShellState.setWallpapers(currentWallpapers); - } + // Save to cache file with debounce + saveTimer.restart(); // Emit signal for this specific wallpaper change root.wallpaperChanged(screenName, path); @@ -529,4 +509,43 @@ Singleton { } } } + + // ------------------------------------------------------------------- + // Cache file persistence + // ------------------------------------------------------------------- + FileView { + id: wallpaperCacheView + printErrors: false + watchChanges: false + + adapter: JsonAdapter { + id: wallpaperCacheAdapter + property var wallpapers: ({}) + } + + onLoaded: { + // Load wallpapers from cache file + root.currentWallpapers = wallpaperCacheAdapter.wallpapers || {}; + Logger.d("Wallpaper", "Loaded wallpapers from cache file:", Object.keys(root.currentWallpapers).length, "screens"); + root.isInitialized = true; + } + + onLoadFailed: error => { + // File doesn't exist yet or failed to load - initialize with empty state + root.currentWallpapers = {}; + Logger.d("Wallpaper", "Cache file doesn't exist or failed to load, starting with empty wallpapers"); + root.isInitialized = true; + } + } + + Timer { + id: saveTimer + interval: 500 + repeat: false + onTriggered: { + wallpaperCacheAdapter.wallpapers = root.currentWallpapers; + wallpaperCacheView.writeAdapter(); + Logger.d("Wallpaper", "Saved wallpapers to cache file"); + } + } }