OpenRiot v7.9.9 — Self-Copy, Self-Doubt, Self-Respect
“The only thing worse than a bug you can’t find is a bug that finds itself.” — The OpenRiot Crew, watching
fsutil.CopyFiletruncatecolors.tomlto zero bytes because the source and destination were the same file
Release Overview
v7.9.9 is the release where we discovered that CopyConfigs() was deploying
files to the same path they already lived in, O_TRUNC was doing its job,
and suddenly every template had "" for every color. The polybar was blank.
The rofi was blank. The settings menu looked like a CSS file that gave up.
We fixed it. Then we made Helix dynamic. Then we made the purple cluster on the right side of the polybar actually purple instead of “purple, I guess.” Then we made the settings menu border purple so you know you’re in Settings and not Apps or Games. Then we documented the entire color architecture so nobody ever has to learn this lesson twice.
v7.9.8 was pixel-perfect. v7.9.9 is self-aware.
The Self-Copy Bug
Root cause: Three rules in packages.yaml copied config/icons/*,
colors.toml, and docs/* into ~/.local/share/openriot/config/... —
which is exactly where they already live in the git checkout.
fsutil.CopyFile() opens the destination with O_TRUNC, then copies
from the source. When they’re the same file, the source is now empty.
Empty TOML → blank template values → broken polybar, broken rofi, broken
everything.
Fixes:
- Removed the self-copying rules from
packages.yaml - Added
filepath.Clean(src) == filepath.Clean(dest)guard tofsutil.CopyFile()so this can never happen again - Updated
docs/Colors.mdwith an entire Derivation Architecture section explaining why you must never target~/.local/share/openriot/...fromCopyConfigs()
| File | Change |
|---|---|
install/packages.yaml |
Removed self-copy rules for icons/*, |
colors.toml, docs/* |
|
source/fsutil/copy.go |
Self-copy guard with filepath.Clean |
docs/Colors.md |
Full Derivation Architecture docs |
Dynamic Helix Colors
The Helix theme (config/helix/themes/openriot.toml) used to be static.
Hardcoded hex values. Inherits from ao. When you changed colors.toml,
Helix stayed the same color it was in 2023.
Now it inherits term16_dark and overrides the entire [palette] with
keys from colors.toml:
black→BaseBGred→SemanticErrorgreen→AccentFGyellow→SemanticWarningblue→SemanticInfomagenta→ExtendedPurplecyan→SemanticCyanwhite→BaseFG
Run openriot --helix-setup to render the template. Or just run
curl -fsSL https://OpenRiot.org/setup.sh | sh and it happens automatically.
| File | Change |
|---|---|
config/helix/themes/openriot.toml.tmpl |
NEW — term16_dark + |
| dynamic palette | |
config/helix/config.toml |
theme = "openriot" |
source/helix/helix.go |
NEW — Setup() renders template |
source/commands/commands.go |
--helix-setup registered |
source/commands/helpers.go |
--helix-setup in dynamic config loop |
install/packages.yaml |
Removed preserve_if_exists for helix/* |
Polybar Purple Cluster
The right-most group of polybar modules — screenrec, settings, power, lock —
all use ExtendedPurple. It was #8B7CF6 (slightly muddy). Now it’s
#A78BFA (brighter, more vibrant, actually reads as purple in daylight).
| File | Change |
|---|---|
config/colors.toml |
extended.purple → #A78BFA |
Settings Menu Border
The settings rofi menu used theme.GetAccent() for its border — which is
green (#9ECE6A), the same color as the apps menu and games menu. You
couldn’t tell which menu you were in.
Now it uses theme.GetPurple() (#A78BFA). You know it’s Settings because
it looks like settings. Purple is the color of configuration.
| File | Change |
|---|---|
source/theme/colors.go |
GetPurple() helper added |
source/settings/settings.go |
GetAccent() → GetPurple() for border |
APM / Power Management
The apmd flags in packages.yaml were just -A (adaptive performance).
Now they’re -A -a -z 5:
-A— adaptive performance mode-a— ignore BIOS suspend requests when on AC power-z 5— auto-suspend when battery drops below 5%
Unplugged and idle? The screen locks. Fifteen minutes later, the system
sleeps. Because xautolock and apmd are a team now.
| File | Change |
|---|---|
install/packages.yaml |
apmd flags -A → flags -A -a -z 5 |
The Music Player, and the Music We Love
OpenRiot ships with rmpc — a Rust TUI client for MPD — and a single
alias that makes it effortless:
alias music='rmpc'
Type music in any terminal. Your library is there. No GUI. No bloat.
Just your collection, indexed, searchable, and fast.
What’s in your ~/Music matters. Ours has:
- Alkaline Trio — because some of us grew up in basements
- Barenaked Ladies — because Canada understands irony
- Beck — because Odelay is a verb now
- Bruce Springsteen — because highways exist
- CAKE — because the distance is a song, not a problem
- Cat Stevens — because sometimes you need tea and a guitar
- Chris Isaak — because Wicked Game never left rotation
- Counting Crows — because August was infinite once
- Cracker — because Low has the only correct tempo
- Dave Matthews & Tim Reynolds — because you need at least one live album
- Dido — because Trip Hop was a real thing
- Foo Fighters — because Dave Grohl is the most consistent human alive
- Gorillaz — because Damon Albarn never stops
- Green Day — because Dookie is a document of a specific era
- Guns N’ Roses — because Appetite is perfect
- Jack White — because distortion is a lifestyle
- Lou Reed — because Walk on the Wild Side is three chords and truth
- Macklemore — because Thrift Shop is about OpenBSD hardware philosophy
That’s just what’s visible. There’s more. There’s always more.
Press Super+Shift+K or type music. MPD is already running. The FIFO
is at /tmp/mpd.fifo. cava is reading it. The visualizer is green.
🧾 Files Changed
| File | Change |
|---|---|
config/helix/themes/openriot.toml.tmpl |
NEW — term16_dark + |
| dynamic palette | |
source/helix/helix.go |
NEW — Setup() renders Helix theme |
config/helix/config.toml |
theme = "openriot" |
config/colors.toml |
extended.purple → #A78BFA |
source/theme/colors.go |
GetPurple() helper |
source/settings/settings.go |
Settings border → purple |
install/packages.yaml |
Removed 3 self-copy rules; apmd flags |
-A -a -z 5; removed preserve_if_exists for helix |
|
source/fsutil/copy.go |
Self-copy guard |
source/commands/commands.go |
--helix-setup registered |
source/commands/helpers.go |
--helix-setup in render loop |
docs/Colors.md |
NEW — full color architecture docs |
🗣️ Final Words
“v7.9.8 made the launcher icon look like it belonged. v7.9.9 made sure the launcher icon actually had colors to render with.”
No more self-copies. No more blank templates. No more wondering why your polybar looks like a Windows 95 error dialog. The colors are real. The music is playing. The battery knows when to sleep.
— The OpenRiot Crew
“We fixed a bug that was copying files to themselves. If that doesn’t describe software engineering in 2026, nothing does.”