diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-29 17:06:48 +0100 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-29 17:06:48 +0100 |
| commit | 68ee0a175acfa3940ed9e19c0e1aad714f799e47 (patch) | |
| tree | 26430589f81340b102599d599e027349c0dd3fbc /desktop | |
| parent | 4b6b7caa0b674a0cefdc8a893d0133c05568633b (diff) | |
| download | quickshell-68ee0a175acfa3940ed9e19c0e1aad714f799e47.tar.gz quickshell-68ee0a175acfa3940ed9e19c0e1aad714f799e47.zip | |
wallpaper: a screen can draw from a gallery folder instead of its hearts
Every wallpaper in the gallery is wide, so hearting a whole folder one
thumbnail at a time is the long way to say "this folder". Each screen
now has a source on the engine page: its hearted list, or one gallery
folder picked by chip, stored as the Wallpapers.groups key in Prefs
(folderH, folderV, "" for the hearts).
A folder that has left the gallery gives an empty pool, so that screen
is left alone rather than quietly falling back to its hearts. The
hearted list stays saved behind a folder source and comes back with the
Hearted chip. Switching source needs nothing from the shuffle: draw()
already drops bag entries that are no longer in the pool.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/Prefs.qml | 8 | ||||
| -rw-r--r-- | desktop/modules/appearance/WallEngine.qml | 16 | ||||
| -rw-r--r-- | desktop/modules/appearance/WallEngineTab.qml | 31 |
3 files changed, 48 insertions, 7 deletions
diff --git a/desktop/Prefs.qml b/desktop/Prefs.qml index 9a9b0b7..8634f87 100644 --- a/desktop/Prefs.qml +++ b/desktop/Prefs.qml @@ -51,10 +51,11 @@ Singleton { property int settingsSidebar: 200 // The wallpaper engine (modules/appearance/WallEngine.qml): on or off, - // the interval, a list of paths per screen, and each screen's home, the - // wallpaper switching off returns to. In here rather than in list files: + // the interval, a list of paths per screen, the gallery folder a screen + // draws from instead of its list ("" for the list), and each screen's + // home, the wallpaper switching off returns to. In here rather than in list files: // the lists can be empty, and an empty FileView write writes nothing. - readonly property var wallEngineDefaults: ({ on: false, minutes: 30, h: [], v: [], homeH: "", homeV: "" }) + readonly property var wallEngineDefaults: ({ on: false, minutes: 30, h: [], v: [], folderH: "", folderV: "", homeH: "", homeV: "" }) property var wallEngine: wallEngineDefaults function setWallEngine(changes) { const w = Object.assign({}, root.wallEngine, changes); @@ -122,6 +123,7 @@ Singleton { on: we.on === true, minutes: Number.isInteger(we.minutes) && we.minutes >= 1 ? we.minutes : 30, h: paths(we.h), v: paths(we.v), + folderH: str(we.folderH), folderV: str(we.folderV), homeH: str(we.homeH), homeV: str(we.homeV), }; } diff --git a/desktop/modules/appearance/WallEngine.qml b/desktop/modules/appearance/WallEngine.qml index 9d90245..fe45f7b 100644 --- a/desktop/modules/appearance/WallEngine.qml +++ b/desktop/modules/appearance/WallEngine.qml @@ -31,6 +31,18 @@ Singleton { function list(which) { return which === "V" ? cfg.v : cfg.h; } function listed(path, which) { return list(which).indexOf(path) >= 0; } + // A gallery folder by its Wallpapers.groups key, "" for the hearted list. + function folder(which) { return which === "V" ? cfg.folderV : cfg.folderH; } + function setFolder(which, key) { Prefs.setWallEngine(which === "V" ? { folderV: key } : { folderH: key }); } + // What a tick draws from. A folder that is no longer in the gallery + // gives nothing, so that screen is left alone rather than falling back + // to the list behind the user's back. + function pool(which) { + const key = folder(which); + if (key === "") return list(which).filter(present); + const g = Wallpapers.groups.find(g => g.key === key); + return g ? g.files : []; + } // ponytail: present means in the gallery's last scan, so a file deleted // since stays drawable until a rescan, and wallp then skips it. function present(path) { return Wallpapers.files.indexOf(path) >= 0; } @@ -64,8 +76,8 @@ Singleton { // A screen whose list is empty, or whose pick is already up, is left out. function tick() { if (Wallpapers.applying) return; - const h = Shuffle.draw(cfg.h.filter(present), bagH, Wallpapers.currentH); - const v = Shuffle.draw(cfg.v.filter(present), bagV, Wallpapers.currentV); + const h = Shuffle.draw(pool("H"), bagH, Wallpapers.currentH); + const v = Shuffle.draw(pool("V"), bagV, Wallpapers.currentV); const ph = h.pick !== Wallpapers.currentH ? h.pick : ""; const pv = v.pick !== Wallpapers.currentV ? v.pick : ""; if (Wallpapers.run(ph, pv, "tick")) { diff --git a/desktop/modules/appearance/WallEngineTab.qml b/desktop/modules/appearance/WallEngineTab.qml index 95e2df2..caa01f4 100644 --- a/desktop/modules/appearance/WallEngineTab.qml +++ b/desktop/modules/appearance/WallEngineTab.qml @@ -67,24 +67,51 @@ Item { required property var modelData readonly property var paths: WallEngine.list(modelData.which) readonly property string home: modelData.which === "V" ? WallEngine.cfg.homeV : WallEngine.cfg.homeH + readonly property string folder: WallEngine.folder(modelData.which) + readonly property var group: Wallpapers.groups.find(g => g.key === folder) ?? null width: col.width spacing: 8 Text { - text: `${screen.modelData.name}: ${screen.paths.length} hearted` + text: screen.modelData.name + ": " + + (screen.folder === "" ? `${screen.paths.length} hearted` + : screen.group ? `${screen.group.files.length} in ${screen.group.name}` + : "the folder is gone, so this screen stays as it is") + (WallEngine.on && screen.home !== "" ? `, home ${Wallpapers.label(screen.home)}` : "") color: Theme.subtext font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } } + // Where the timer draws from: the hearts, or one gallery + // folder in their place. + Flow { + width: col.width + spacing: 6 + Tab { + text: "Hearted" + selected: screen.folder === "" + onClicked: WallEngine.setFolder(screen.modelData.which, "") + } + Repeater { + model: Wallpapers.groups + Tab { + required property var modelData + text: modelData.name + selected: screen.folder === modelData.key + onClicked: WallEngine.setFolder(screen.modelData.which, modelData.key) + } + } + } + Text { - visible: screen.paths.length === 0 + visible: screen.folder === "" && screen.paths.length === 0 text: "Heart a wallpaper on the Wallpaper page, with this screen selected, to add it." color: Theme.overlay font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } } Flow { + visible: screen.folder === "" width: col.width spacing: 8 |
