OpenRiot v5.4 — The SSD Migration Arc
“Your SSD is not a pet. It does not recognize you by smell. Moving it to a new machine is like teleporting into a different dimension — everything looks the same, but the laws of physics are wrong.” — Ancient OpenBSD proverb, probably carved into a ThinkPad somewhere
Release Overview
When you rip an OpenBSD install out of a desktop and slam it into a ThinkPad T14s like a shonen protagonist pulling a bankai, things get weird. The ethernet port you never had starts haunting you. Your WiFi driver speaks a different dialect. Polybar forgets what a click is. And your laptop sulks when you close the lid, even though it’s plugged into HDMI and supposed to be an adult about it.
OpenRiot v5.4 is the arc where we fix all of it. Like a ninja dismantling a security system in a single fluid motion — silent, precise, and slightly overdramatic.
Also: No Age Verification. Not because we have anything to hide, but you’re an adult running OpenBSD and if you need a popup to ask if you’re 18 to look at your own desktop environment, you’ve already lost. We don’t pad our release notes with consent banners and we don’t make you click “I agree” to use a terminal. That’s a Linux thing.
🖱️ Clickareas of Destiny — Polybar Goes Super Saiyan
The Problem: You moved your SSD. You rebooted. Polybar suddenly forgot how to accept clicks like a petulant child. Workspaces on the left? Dead. Icons on the right? Also dead. Why? Because the default clickareas = 32 is about as useful as a senzu bean after you’ve already lost the fight. With 20+ modules and workspace icons generating clickable zones, we were silently overflowing the limit and watching polybar discard handlers like they were filler episodes.
The Fix: clickareas = 64 in config/polybar/config.ini. Double the capacity. Double the clicks. Zero filler.
📡 The WiFi Blues — A Tragedy in Three Acts
Act I: The Vanishing Icon
Your laptop’s WiFi driver (probably iwx) doesn’t report dBm signal strength the same way your desktop’s iwm did. When getSignal() returned 0, the old code said “cool, return an empty string” and the WiFi icon ghosted out of polybar. Like a character written out of the manga because the author forgot they existed.
Fixed: getWifiIcon() now returns a default icon even when signal is 0. No more vanishing protagonists.
Act II: The Shell Timeout That Wasn’t
CheckConnectivity() was calling timeout 3 ping 8.8.8.8. On OpenBSD. Where timeout doesn’t exist in base. This is like trying to cast a spell from a different magic system. It failed silently, cleared the connectivity cache, and every 60 seconds your WiFi module decided you were offline.
Fixed: Replaced with Go context.WithTimeout. Actual timeouts. Actual pings. Actual connectivity.
Act III: The Phantom Ethernet
ThinkPad T14s has an em0 soldered to the motherboard with no actual connector — a ghost interface, a hollow technique, a phantom limb. The old getEthInterface() returned ("em0", false) on status: no carrier, which made GetEth() show a disconnected-cable icon for hardware that doesn’t physically exist.
Fixed: getEthInterface() now ONLY returns when it finds status: active. No carrier → no interface → no icon. GetEth() returns "" instead of a sad cable icon. axen0 (your real USB ethernet) now gets evaluated properly instead of being blocked by a phantom.
Bonus: WiFi Connection Detection
The old code checked inet as proof of WiFi connection. Stale DHCP leases on iwx0 falsely reported “connected” even when join was absent. Like claiming you’re in a relationship because you still have their hoodie.
Fixed: WiFi is only “connected” when join appears in ifconfig. No join, no icon.
🖥️ The HDMI Unified Theory — One Icon to Rule Them All
The Problem: The old laptop-monitor module was broken. It required 3+ active monitors to appear (via xrandr --listactivemonitors), so you literally never saw it. It had no click handler. And closing the laptop lid while on HDMI? machdep.lidaction=1 suspended the system anyway, because OpenBSD’s kernel doesn’t care about your external monitor feelings.
The New Arc: We deleted laptop-monitor entirely and forged a single hdmi module in source/display/hdmi.go.
Command palette: | Mode | Icon | State | |——|——|——-| | Laptop + HDMI | | Both displays active | | HDMI Only | | Laptop display off, lid sleep disabled |
ToggleHDMI() mechanics:
- Click once → laptop display OFF,
machdep.lidaction=0, notification “HDMI Only ” - Click again → laptop display ON,
machdep.lidaction=1, notification “Laptop + HDMI ” pkill -9 polybarruns after every switch because xrandr rearrangements make polybar look like abstract art- Notification timeout bumped to
8000ms— long enough to actually read
Detecting disabled displays: getLaptopDisplay() now uses plain xrandr (not --listmonitors) so it finds eDP-1 even after you’ve turned it off. Turning it back on works even when the display is invisible to active monitor lists.
🔋 The Lid Sleep Betrayal
source/detect/detect.go — SuspendIfUndocked() used to suspend on battery regardless of whether you’re presenting on a 4K monitor to executives. Now it checks display.HasExternalDisplay(). HDMI connected? No suspend. On battery with no external display? Sleep tight.
⚡ Polybar Spacing — Tightening the Panel Lines
For 1080p and 1440p screens, module-margin = 2 was pushing the right-side modules so far apart that the date/time got shoved left like a side character losing screentime. Reduced to 1 for 1920+ widths. The right side is now balanced like a well-choreographed fight scene.
Also: sep added between battery and power lock. Visual rhythm restored.
🖱️ The Bibata Cursor — The Final Boss Returns
Firefox, Signal (Electron), and Qt apps were ignoring XCURSOR_THEME and showing the default X11 cursor. Why? Missing ~/.icons/default/index.theme — the fallback pointer that X11 checks before giving up. GTK apps found Bibata fine. Everyone else was left in cursor purgatory.
Fixed: source/assets/assets.go — installBibata() now always creates:
~/.icons/default/index.theme
[Icon Theme]
Name=Default
Comment=Default cursor theme
Inherits=Bibata-Modern-Ice
Even if Bibata is already installed. Every single run. Because ninjas don’t leave fallback chains broken — they fix them in the shadows while you’re not looking.
🐧 A Brief Interlude: Why This Would Never Happen on Linux
On Linux, moving your SSD to a new machine means re-generating initramfs, fighting UUID mismatches, rebuilding the GRUB config, recompiling kernel modules for the new audio codec, and then crying into your Arch Wiki bookmarks while systemd-resolved decides your DNS servers are a social construct. Oh, and somewhere in there, pipewire stops working because you forgot to install wireplumber on Tuesday after a full moon.
On OpenBSD? You just move the disk. It boots. The only thing that changes is the network interface name and maybe the WiFi driver. OpenRiot v5.4 exists because we thought the migration would be seamless. It was — at the OS level. Our own assumptions about static hardware were the only thing that broke. The OS didn’t flinch. Your desktop Linux install would have flinched so hard it would have demanded you reinstall from scratch and posted a passive-aggressive GitHub issue about it.
OpenBSD: Secure. Stable. Slightly judgmental.
🗂️ Files Changed
| File | What We Did |
|---|---|
config/polybar/config.ini |
clickareas = 64; modules-right updated; added [module/hdmi]; removed [module/laptop-monitor]; sep between battery/power; colors unified to fg2 |
source/polybar/polybar.go |
module-margin = 1 for 1080p/1440p |
source/network/network.go |
context.WithTimeout for ping; signal=0 returns icon; getEthInterface() only active; WiFi checks join only |
source/display/hdmi.go |
NEW — unified HDMI toggle module |
source/display/laptopmonitor.go |
DELETED — superseded by hdmi module |
source/detect/detect.go |
SuspendIfUndocked() respects external displays |
source/commands/commands.go |
Wired --hdmi, --hdmi-toggle; removed --laptop-monitor |
source/assets/assets.go |
installBibata() creates ~/.icons/default/index.theme fallback |
🗣️ Final Words
“A ninja doesn’t fight the hardware. A ninja becomes the hardware. Then the ninja fixes the hardware’s cursor fallback chain while everyone else is asleep.”
v5.3 is the release where moving your SSD to a new machine doesn’t feel like waking up in the wrong anime. Your clicks work. Your WiFi shows up. Your ethernet doesn’t lie. Your HDMI toggles. Your lid behaves. And your cursor is finally, actually, consistently beautiful.
v5.4 is a mountain of HDMI + Bug fixes and a clear rebellion against Age Verification and the Big Brother apparatus.
No age verification required. No systemd. No snap. No flatpak. No popups asking if you’re okay. You’re running OpenBSD. You were never okay and you never needed to be.
Upgrade when ready:
curl -fsSL https://OpenRiot.org/setup.sh | sh
Or run setup.sh --local if you’re already living in the repo.
— The OpenRiot Crew
“Same SSD. New machine. No fear.”