aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/modules/appearance/Udt.qml
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-22 17:25:15 +0200
committerDanilo M. <danix@danix.xyz>2026-10-22 17:25:15 +0200
commit9d9e67a14967fe756c357b0ece3d9f339f8afa17 (patch)
treecc443f3a54979f2ba0a0cf050917ec4876997c67 /desktop/modules/appearance/Udt.qml
parent38b64dda38c76fa11424cba8ed012cd94a56362e (diff)
downloadquickshell-9d9e67a14967fe756c357b0ece3d9f339f8afa17.tar.gz
quickshell-9d9e67a14967fe756c357b0ece3d9f339f8afa17.zip
settings: a Theme status page for unified-desktop-theme
Shows the live scheme, accent and both wallpapers, the scheme and wallpapers linking to their own pages, then every udt consumer in a software and a hardware list, each with a Re-apply button running `install.sh <name>`, and Re-apply all in the header. The list comes from `install.sh --list`, so a consumer added in unified-desktop-theme shows up here with no edit. One run at a time, and none during a scheme switch. QML's JS engine has no Object.fromEntries either: it threw a TypeError that only reached the log and left the page without its list. Noted in AGENTS.md beside String.matchAll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'desktop/modules/appearance/Udt.qml')
-rw-r--r--desktop/modules/appearance/Udt.qml55
1 files changed, 55 insertions, 0 deletions
diff --git a/desktop/modules/appearance/Udt.qml b/desktop/modules/appearance/Udt.qml
index a4bf296..98fbba7 100644
--- a/desktop/modules/appearance/Udt.qml
+++ b/desktop/modules/appearance/Udt.qml
@@ -150,4 +150,59 @@ Singleton {
code === 0 ? "" : `install.sh exited ${code}, its output is in the steps window`);
}
}
+
+ // The consumers come from install.sh itself, one c_<name> function each,
+ // so adding one in unified-desktop-theme needs no edit here.
+ property list<string> consumers: []
+ // name -> what it themes, the comment on its function line.
+ property var consumerInfo: ({})
+ // name -> "software" or "hardware", for the page's two lists.
+ property var consumerKind: ({})
+ function refreshStatus() {
+ statusProc.running = false;
+ statusProc.running = true;
+ }
+
+ Process {
+ id: statusProc
+ command: [`${root.repo}/install.sh`, "--list"]
+ stdout: StdioCollector {
+ onStreamFinished: {
+ const rows = text.trim().split("\n").filter(s => s.length).map(l => l.split("\t"));
+ // QML's JS engine has no Object.fromEntries.
+ const info = {}, kind = {};
+ for (const [n, k, d] of rows) { kind[n] = k; info[n] = d ?? ""; }
+ root.consumerInfo = info;
+ root.consumerKind = kind;
+ root.consumers = rows.map(r => r[0]);
+ }
+ }
+ }
+
+ // One run at a time, so two never race over the generated files.
+ // "*" is every consumer at once, install.sh with no argument.
+ // install.sh hands a failure's output to the steps window itself.
+ property string reapplying: ""
+ // name -> true (ok) / false (failed), for the run this session.
+ property var reapplied: ({})
+ function reapply(name) {
+ if (applying || reapplying !== "") return;
+ reapplying = name;
+ reapplyProc.command = [`${root.repo}/install.sh`].concat(name === "*" ? [] : [name]);
+ reapplyProc.running = true;
+ }
+ function isReapplying(name) { return reapplying === "*" || reapplying === name; }
+
+ Process {
+ id: reapplyProc
+ onExited: code => {
+ const next = Object.assign({}, root.reapplied);
+ // ponytail: a full run marks every row by the one exit code, since
+ // install.sh stops at the first failure without naming it.
+ for (const n of root.reapplying === "*" ? root.consumers : [root.reapplying])
+ next[n] = code === 0;
+ root.reapplied = next;
+ root.reapplying = "";
+ }
+ }
}