aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AGENTS.md14
-rwxr-xr-xbin/udt-accent46
2 files changed, 52 insertions, 8 deletions
diff --git a/AGENTS.md b/AGENTS.md
index 9576bc6..068587e 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -199,16 +199,22 @@ One colour moves: `@accent`. `bin/udt-accent` reads the current wallpaper,
extracts its signature colour, and snaps it to the nearest of ten Catppuccin
accents by perceptual hue in CIELAB. `wallp` calls it on every wallpaper change.
-It writes nine things: `~/.cache/udt/udt-accent.rasi` (rofi),
+It writes ten things: `~/.cache/udt/udt-accent.rasi` (rofi),
`~/.cache/udt/udt-border.lua` (Hyprland), `~/.cache/udt/hyprlock-border.conf`
(hyprlock, the same three hues as the window border, as a hyprlang gradient),
`~/.cache/wal/colors.json` (Firefox, via pywalfox),
`~/.cache/udt/udt-palette.qml` (quickshell),
`~/.local/share/udt/sddm-theme.conf` (the SDDM greeter, palette plus wallpaper,
read through a root-made `theme.conf.user` symlink), and the accent
-substitution in three generated files: Sublime's installed
+substitution in four generated files: Sublime's installed
`Packages/User/udt.sublime-color-scheme`, grub-theme-udt's `theme.txt` (its
-`# udt:` line) and `templates/homepage/custom.css` (its `--udt-accent` line).
+`# udt:` line), `templates/homepage/custom.css` (its `--udt-accent` line) and
+conky-theme-udt's `conky.conf` (its `color1` and `color5` lines, the `heading`
+role, which is the scheme accent in every scheme, and `highlight`, the icons
+and bars, which takes the accent's next hue on the wheel, the border's leading
+neighbour, so it stays apart from the headings). conky watches that file's inode with
+inotify and reloads on a write, so it is rewritten in place: an atomic rename
+would end the watch silently.
It then starts `udt-homepage` and `udt-grub` detached, for the two outputs
that need a root step on another filesystem or host, and `udt-keyboard`, which
lights an Ajazz AK820 Pro in the accent through `ak820-ctl` (a no-op without
@@ -328,7 +334,7 @@ profile, and the new tab stays blank.
Not everything tracks the wallpaper. rofi, quickshell, Hyprland borders,
hyprlock's border (through `~/.cache/udt/hyprlock-border.conf`), Sublime's
-colour scheme, Firefox, GRUB, the homepage, the AK820 Pro keyboard, the LED strip and the TRADFRI bulbs do; conky, Qt, GTK, waybar, hyprlock's panel palette
+colour scheme, Firefox, GRUB, the homepage, conky's headings and icons, the AK820 Pro keyboard, the LED strip and the TRADFRI bulbs do; the rest of conky, Qt, GTK, waybar, hyprlock's panel palette
(from `templates/hyprlock/hyprlock-palette.conf`) and Sublime's UI chrome sit
on the scheme's accent, lavender by default, which is also the fallback
when a wallpaper is too grey to snap. Qt and GTK apps only reread a theme on restart,
diff --git a/bin/udt-accent b/bin/udt-accent
index 1388db1..ebbac91 100755
--- a/bin/udt-accent
+++ b/bin/udt-accent
@@ -54,6 +54,13 @@ QML_OUTPUT = CACHE / "udt-palette.qml"
REPO = Path(__file__).resolve().parent.parent
GRUB_THEME = REPO.parent / "grub-theme-udt" / "theme.txt"
HOMEPAGE_CSS = REPO / "templates" / "homepage" / "custom.css"
+# conky's heading role is the scheme accent in every scheme, so it follows the
+# wallpaper's. highlight (titles' icons, bars, the moon) left on the scheme's
+# own hue kept the dashboard that hue whatever the wallpaper, so it takes the
+# accent's next hue on the wheel, the border's leading neighbour: related to
+# the heading, still told apart from it. color1 is heading and color5
+# highlight in conky.conf.in.
+CONKY_CONF = REPO.parent / "conky-theme-udt" / "conky.conf"
# The installed rofi palette, itself generated by udt-palette. Read rather than
# duplicated so the QML singleton carries exactly the colours rofi uses, under
@@ -429,12 +436,15 @@ def write_firefox(image):
print(f"udt-accent: firefox new tab not updated: {exc}", file=sys.stderr)
-def rewrite(path, pattern, value):
+def rewrite(path, pattern, value, in_place=False):
"""Replace group 1's tail in the first line matching pattern with value.
For generated files whose accent is replaced by matching the line that
carries it, not a placeholder, so a second run rewrites the first run's
accent. A missing file is not an error: its consumer may not be here.
+
+ `in_place` keeps the inode, for a reader that watches the file itself
+ rather than its directory: an atomic rename would silently end the watch.
"""
try:
text = path.read_text()
@@ -443,7 +453,10 @@ def rewrite(path, pattern, value):
new, count = re.subn(pattern, lambda m: m.group(1) + value, text,
count=1, flags=re.M)
if count and new != text:
- write_atomic(path, new, mode=path.stat().st_mode & 0o777)
+ if in_place:
+ path.write_text(new)
+ else:
+ write_atomic(path, new, mode=path.stat().st_mode & 0o777)
def write_sublime(name):
@@ -467,6 +480,21 @@ def write_homepage(name):
rewrite(HOMEPAGE_CSS, r"^(\s*--udt-accent:\s*)[^;]*", f"{r} {g} {b}")
+def write_conky(name):
+ """The accent on conky.conf's color1 line (heading), its next hue on color5
+ (highlight).
+
+ In place: conky watches the config's inode with inotify and reloads on a
+ write, so no restart is needed, but a rename would end the watch. A torn
+ read is not a risk in practice, since conky acts on the event at its next
+ update, long after this small write has finished.
+ """
+ after = hue_neighbours(name)[1]
+ for slot, hexval in (("color1", ACCENTS[name]), ("color5", ACCENTS[after])):
+ rewrite(CONKY_CONF, rf"^(\s*{slot}\s*=\s*')#[0-9a-fA-F]{{6}}",
+ hexval, in_place=True)
+
+
def icon_theme():
"""The icon theme the appearance drawer selected, or "" if unreadable.
@@ -616,6 +644,7 @@ def main(image):
# Before the helpers below start, which build and stage these two.
write_grub(name)
write_homepage(name)
+ write_conky(name)
# Hyprland only rereads its config on request, and may not be running.
subprocess.run(["hyprctl", "reload"], capture_output=True, check=False)
@@ -664,8 +693,8 @@ def selftest():
assert '"#f5a97f"' not in second and '"#8bd5ca"' in second
assert third == second, "accent substitution is not idempotent"
- # GRUB and homepage go through the same match-the-line rewrite, so the
- # same twice-over test: the scheme's accent first, then the last run's.
+ # GRUB, homepage and conky go through the same match-the-line rewrite, so
+ # the same twice-over test: the scheme's accent first, then the last run's.
with tempfile.TemporaryDirectory() as tmpdir:
f = Path(tmpdir) / "f"
cases = [
@@ -674,15 +703,24 @@ def selftest():
(write_homepage, ".t {\n --udt-accent: 183 189 248;\n}\n",
lambda h: ".t {\n --udt-accent: %d %d %d;\n}\n"
% tuple(bytes.fromhex(h[1:]))),
+ (write_conky,
+ " color1 = '#cc0dbf',\n color4 = '#37daea',\n color5 = '#ef60d9',\n",
+ lambda h: f" color1 = '{h}',\n color4 = '#37daea',\n color5 = "
+ f"'{ACCENTS[hue_neighbours(HEX_NAME[h])[1]]}',\n"),
]
+ HEX_NAME = {v: k for k, v in ACCENTS.items()}
for write, start, want in cases:
globals()["GRUB_THEME"] = globals()["HOMEPAGE_CSS"] = f
+ globals()["CONKY_CONF"] = f
f.write_text(start)
f.chmod(0o644)
+ inode = f.stat().st_ino
for name in list(ACCENTS)[:2]:
write(name)
assert f.read_text() == want(ACCENTS[name]), f.read_text()
assert f.stat().st_mode & 0o777 == 0o644, "rewrite lost the mode"
+ if write is write_conky:
+ assert f.stat().st_ino == inode, "conky rewrite replaced the inode"
# A near-grey has an unstable hue angle and must take the fallback.
assert snap("#888888") == FALLBACK, snap("#888888")