diff options
Diffstat (limited to 'desktop/companion/Admired.qml')
| -rw-r--r-- | desktop/companion/Admired.qml | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/desktop/companion/Admired.qml b/desktop/companion/Admired.qml new file mode 100644 index 0000000..eee76d1 --- /dev/null +++ b/desktop/companion/Admired.qml @@ -0,0 +1,101 @@ +// 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 Singleton + +import Quickshell +import Quickshell.Io +import QtQuick +import ".." +import "ListFile.js" as LF + +// The wallpapers the companion blushes at, and what wallp has on each +// monitor. The companion reads both; the wallpaper picker toggles entries. +// What is on each monitor is read from wallp's own files here rather than +// through the appearance module's Wallpapers, which scans every wallpaper +// on creation, and the companion runs all session. +Singleton { + id: root + + readonly property string home: Quickshell.env("HOME") + readonly property string defaultPath: + (Quickshell.env("XDG_CONFIG_HOME") || root.home + "/.config") + "/keystone/companion-blush.txt" + readonly property string path: + Prefs.companionBlushFile !== "" ? Prefs.companionBlushFile.replace(/^~(?=\/|$)/, root.home) : root.defaultPath + + property string listText: "" + readonly property var paths: LF.parse(root.listText) + function listed(p) { return p !== "" && root.paths.indexOf(p) >= 0; } + + // The wallpaper on a monitor, by connector name; "" for one wallp does + // not set. + property var outputs: ({}) + property string wallH: "" + property string wallV: "" + function on(monitor) { + const w = root.outputs[monitor]; + return w === "H" ? root.wallH : w === "V" ? root.wallV : ""; + } + + // ponytail: a list file created by hand after start may not be watched + // until a restart (the watch is on a path that did not exist); the + // heart writes through the process below, which sets listText itself. + FileView { + path: root.path + watchChanges: true + printErrors: false + onFileChanged: reload() + onLoaded: root.listText = text() + onLoadFailed: root.listText = "" + } + FileView { + path: root.home + "/.config/wallp/wallp.conf" + watchChanges: true + printErrors: false + onFileChanged: reload() + onLoaded: root.outputs = LF.outputs(text()) + } + FileView { + path: root.home + "/.config/wallp/wall_h" + watchChanges: true + printErrors: false + onFileChanged: reload() + onLoaded: root.wallH = text().trim() + } + FileView { + path: root.home + "/.config/wallp/wall_v" + watchChanges: true + printErrors: false + onFileChanged: reload() + onLoaded: root.wallV = text().trim() + } + + // Through cat rather than FileView.setText, because the list can become + // empty and setText("") on a path the view has not loaded writes no + // file (AGENTS.md). + function toggle(p) { + writer.data = LF.toggle(root.listText, p); + root.listText = writer.data; + writer.command = ["sh", "-c", 'mkdir -p "$(dirname "$1")" && cat > "$1"', "sh", root.path]; + writer.stdinEnabled = true; + writer.running = false; + writer.running = true; + } + Process { + id: writer + property string data: "" + onStarted: { + writer.write(writer.data); + writer.stdinEnabled = false; + } + onExited: code => { if (code !== 0) console.warn("Admired: writing", root.path, "failed"); } + } +} |
