diff options
| author | Danilo M. <danix@danix.xyz> | 2026-10-23 16:28:23 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-10-23 16:28:23 +0200 |
| commit | a027a6c929d885c54e0e19952ef4fffdfbce8268 (patch) | |
| tree | 661c250b1edc599947e4dea2c4fb195ffe781dc0 | |
| parent | 783340342e79417b7bc120d278c993252a247bd2 (diff) | |
| download | quickshell-a027a6c929d885c54e0e19952ef4fffdfbce8268.tar.gz quickshell-a027a6c929d885c54e0e19952ef4fffdfbce8268.zip | |
companion: ListFile.js, the wallpaper list as plain text
Toggling keeps comments and every other line, so a hand-edited list
survives the picker's heart. wallp.conf's outputs map a monitor to the
H or V wallpaper.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
| -rw-r--r-- | desktop/companion/ListFile.js | 44 | ||||
| -rw-r--r-- | desktop/companion/test_mood.js | 19 |
2 files changed, 63 insertions, 0 deletions
diff --git a/desktop/companion/ListFile.js b/desktop/companion/ListFile.js new file mode 100644 index 0000000..d074c80 --- /dev/null +++ b/desktop/companion/ListFile.js @@ -0,0 +1,44 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +.pragma library + +// The wallpapers the companion blushes at, as a plain text file: one +// absolute path per line, blank lines and lines starting with # skipped. +// Pure, so test_mood.js drives it; Admired.qml reads and writes the file. + +function parse(text) { + const out = []; + for (const l of text.split("\n")) { + const p = l.trim(); + if (p !== "" && p[0] !== "#") out.push(p); + } + return out; +} + +// text with path's line removed if it is listed, else appended. Comments +// and every other line stay as they are. +function toggle(text, path) { + const lines = text === "" ? [] : text.replace(/\n$/, "").split("\n"); + const kept = lines.filter(l => l.trim() !== path); + if (kept.length === lines.length) kept.push(path); + return kept.length ? kept.join("\n") + "\n" : ""; +} + +// wallp.conf's OUTPUT_H and OUTPUT_V, as { connector: "H" | "V" }. An exec +// loop, because QML's engine has no String.matchAll. +function outputs(conf) { + const out = {}; + const re = /^\s*OUTPUT_([HV])\s*=\s*(\S+)/gm; + let m; + while ((m = re.exec(conf)) !== null) out[m[2]] = m[1]; + return out; +} diff --git a/desktop/companion/test_mood.js b/desktop/companion/test_mood.js index 90ebdd6..96d1232 100644 --- a/desktop/companion/test_mood.js +++ b/desktop/companion/test_mood.js @@ -20,6 +20,9 @@ const src = fs.readFileSync(__dirname + "/Mood.js", "utf8") .replace(/^\.pragma library$/m, ""); const M = new Function(src + "\nreturn { T, click, clickFrame, pick, outfit, mockAllowed, canSpeak, monologue };")(); +const lsrc = fs.readFileSync(__dirname + "/ListFile.js", "utf8") + .replace(/^\.pragma library$/m, ""); +const L = new Function(lsrc + "\nreturn { parse, toggle, outputs };")(); const NOW = 10000000; // A snapshot with nothing going on, overridden per case. @@ -119,4 +122,20 @@ assert.strictEqual(M.monologue("other", 0, NOW, 0), false); assert.strictEqual(M.monologue("bored", NOW - M.T.monologueCooldown + 1, NOW, 0), false); assert.strictEqual(M.monologue("bored", NOW - M.T.monologueCooldown, NOW, 0), true); +// The wallpaper list: paths, blank lines and # comments skipped. +assert.deepStrictEqual(L.parse(""), []); +assert.deepStrictEqual(L.parse("# mine\n/a.png\n\n /b.png \n#/c.png\n"), ["/a.png", "/b.png"]); +// Toggling adds a missing path and removes a listed one, leaving +// comments and every other line as they were. +assert.strictEqual(L.toggle("", "/a.png"), "/a.png\n"); +assert.strictEqual(L.toggle("# mine\n/b.png", "/a.png"), "# mine\n/b.png\n/a.png\n"); +assert.strictEqual(L.toggle("# mine\n/a.png\n/b.png\n", "/a.png"), "# mine\n/b.png\n"); +assert.strictEqual(L.toggle("/a.png\n", "/a.png"), ""); +// A commented-out path is not listed, so toggling it adds a live line. +assert.strictEqual(L.toggle("#/a.png\n", "/a.png"), "#/a.png\n/a.png\n"); +// wallp.conf's outputs, by connector. +assert.deepStrictEqual(L.outputs("# x\nOUTPUT_H=DP-1\nOUTPUT_V=DP-3\nDEFAULT_H=~/h.png\n"), + { "DP-1": "H", "DP-3": "V" }); +assert.deepStrictEqual(L.outputs(""), {}); + console.log("ok"); |
