aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-09-29 10:40:57 +0200
committerDanilo M. <danix@danix.xyz>2026-09-29 10:40:57 +0200
commita955a93101aae45bca030c4ea9074ddda86a2fc9 (patch)
tree6ed641634a51eca252d5912de7593f9f8f2347e8
parenta08ffb69ac7553350e1e5259bb0101ea997a70ae (diff)
downloadgrub-theme-udt-a955a93101aae45bca030c4ea9074ddda86a2fc9.tar.gz
grub-theme-udt-a955a93101aae45bca030c4ea9074ddda86a2fc9.zip
Title the panel with the machine's pretty name
Read PRETTY_HOSTNAME from /etc/machine-info, falling back to NAME from /etc/os-release. The name stays on the machine rather than in the repo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
-rw-r--r--README.md6
-rwxr-xr-xbuild32
-rw-r--r--theme.txt.in3
3 files changed, 34 insertions, 7 deletions
diff --git a/README.md b/README.md
index 104863d..fd7a6c4 100644
--- a/README.md
+++ b/README.md
@@ -12,6 +12,12 @@ assembles the complete theme in `dist/udt/`: `theme.txt`, the PNG slices in
the same colours, the `.pf2` fonts and `background.jpg`, a GRUB-readable copy
of `~/.cache/udt/wpaper`. Both outputs are gitignored.
+The panel title is the machine's pretty name, `PRETTY_HOSTNAME` in
+`/etc/machine-info`, or the OS name from `/etc/os-release` when that is not
+set. To set it, as root:
+
+ echo 'PRETTY_HOSTNAME="My Machine"' > /etc/machine-info
+
The accent is the scheme's fixed `accent` role, not the wallpaper-tracking
one: nothing at boot can read that.
diff --git a/build b/build
index 5e14ce0..5397388 100755
--- a/build
+++ b/build
@@ -13,6 +13,7 @@ dist/udt/ untouched. Never touches /boot: root copies dist/udt/ there.
"""
import os
import re
+import shlex
import shutil
import struct
import subprocess
@@ -132,15 +133,27 @@ def font(fname, pattern, size, name):
return cached
-def os_name():
- for line in Path("/etc/os-release").read_text().splitlines():
- if line.startswith("NAME="):
- return line[5:].strip('"')
- return "GNU/Linux"
+def shell_var(path, key):
+ """KEY's value from a KEY="value" file (machine-info, os-release), or None."""
+ try:
+ lines = Path(path).read_text().splitlines()
+ except FileNotFoundError:
+ return None
+ for line in lines:
+ if line.startswith(f"{key}="):
+ return " ".join(shlex.split(line[len(key) + 1:])) or None
+ return None
+
+
+def title():
+ """The machine's pretty name if root has set one, else the OS name."""
+ name = (shell_var("/etc/machine-info", "PRETTY_HOSTNAME")
+ or shell_var("/etc/os-release", "NAME") or "GNU/Linux")
+ return name.replace('"', "'") # it lands inside a quoted theme.txt string
def assemble(stage, text, c, wallpaper, fonts):
- (stage / "theme.txt").write_text(text.replace("%TITLE%", os_name()))
+ (stage / "theme.txt").write_text(text.replace("%TITLE%", title()))
slices = {
"panel.png": (8, 8, (*c["bg_alt"], PANEL_ALPHA)),
# The selected item: a 4px accent bar on the left, surface behind.
@@ -183,6 +196,13 @@ def selftest():
assert set(re.findall(r"@[A-Z_]+@", tpl)) <= PLACEHOLDERS, "template token udt does not fill"
for _, _, name in FONTS.values():
assert f'"{name}"' in tpl, f"template does not use font {name}"
+ with tempfile.NamedTemporaryFile("w") as f:
+ f.write('PRETTY_HOSTNAME="A B\'s C"\nEMPTY=\n')
+ f.flush()
+ assert shell_var(f.name, "PRETTY_HOSTNAME") == "A B's C"
+ assert shell_var(f.name, "EMPTY") is None
+ assert shell_var(f.name, "MISSING") is None
+ assert shell_var("/nonexistent", "X") is None
print("selftest ok")
diff --git a/theme.txt.in b/theme.txt.in
index 173077d..e327445 100644
--- a/theme.txt.in
+++ b/theme.txt.in
@@ -18,7 +18,8 @@ terminal-width: "100%"
terminal-height: "100%"
terminal-border: "0"
-# %TITLE% is filled in by ./build from /etc/os-release.
+# %TITLE% is filled in by ./build: PRETTY_HOSTNAME from /etc/machine-info,
+# else NAME from /etc/os-release.
+ label {
left = 3%
top = 8%