Coin Toss — settle anything from the Omarchy bar
A coin in the Omarchy Quattro bar. Type what you're stuck on, hit space, watch it spin. The side comes from /dev/urandom, and every verdict is written down.

Why a coin needs writing down
A coin you can re-flip until you like the answer isn't deciding anything — it's a slot machine you play until it agrees with you. So this one keeps a log: the question, the side, the time. The tally under SETTLED shows how the coin has actually been falling, which is usually the fastest way to notice you've been asking the same question all afternoon.
The other half is the randomness. Math.random() is a seeded PRNG with no guarantees worth the name — fine for a bouncing ball, not fine for something you've agreed to be bound by. Each toss reads one byte from /dev/urandom and takes its low bit: a uniform bit off a uniform byte, so there's no modulo, no rejection sampling, and nothing to argue about afterwards.
The spin is theatre played over a side the kernel already picked. Toss.spinPlan() chooses the number of half-turns and the face parity together, so the animation is arithmetically unable to land on the wrong face — test/run.js asserts exactly that across every turn count. If /dev/urandom can't be read at all the toss still happens, on Math.random(); a worse coin beats a stuck widget.
Use it
In the bar — left click opens the panel, right click flips on the spot without opening anything, middle click clears the lingering result.
In the panel:
| Key | What |
|---|---|
space / enter |
Flip |
c |
Type a question (enter in the field flips) |
x |
Forget every verdict |
esc |
Close |
From a keybinding — the plugin doesn't touch your Hyprland config, so add this to ~/.config/hypr/bindings.lua yourself:
o.bind("SUPER + ALT + C", "Coin toss", "omarchy-shell shell toggle com.aktivesolutions.cointoss")
It doesn't have to be a coin
Rename the two sides and it becomes whatever binary you're stuck on — Ship it / Wait, Yes / No, Tabs / Spaces, You cook / I cook. The log stores the side, not the label, so renaming re-reads old verdicts in the new vocabulary instead of lying about them.
Settings live in the widget's shell.json entry, and Omarchy surfaces them in the bar widget settings UI:
| Setting | Default | What |
|---|---|---|
headsLabel |
Heads |
What the heads side is called |
tailsLabel |
Tails |
What the tails side is called |
animate |
true |
Spin the coin. Off = instant verdict |
showResultInBar |
true |
Put the verdict next to the bar icon |
resultLingerSeconds |
8 |
How long the bar keeps it. 0 = until the next toss |
historyLimit |
20 |
Verdicts to remember. 0 = remember nothing |
notify |
false |
notify-send on every toss |
Install
omarchy plugin add https://github.com/alkevintan/omarchy-cointoss --enable
--enable adds the widget to your bar and asks which section to put it in. Without it the plugin is installed but inert until you run omarchy plugin enable com.aktivesolutions.cointoss.
Remove
omarchy plugin remove com.aktivesolutions.cointoss
rm -rf ~/.local/state/omarchy/cointoss # optional: the verdict log
omarchy plugin remove takes the widget back out of shell.json and deletes the plugin directory. Nothing else on your system is touched — the plugin never edits your Hyprland config, your theme, or any file outside its own directory and its own state directory.
Requirements
Omarchy Quattro (Quickshell). Nothing else to install:
| Needs | For | Already on Omarchy |
|---|---|---|
od, mkdir (coreutils) |
Reading a byte of entropy, creating the state directory | yes |
notify-send (libnotify) |
Only if you turn the notify setting on |
yes |
No network access, no daemon, no background process, no bundled binaries.
Where things live
| Path | What |
|---|---|
BarWidget.qml |
Bar button and panel — the only entry point |
Toss.js |
Log bookkeeping, entropy decoding, spin geometry. No QML types, so it runs under node |
test/run.js |
node test/run.js — 34 assertions over Toss.js |
~/.local/state/omarchy/cointoss/history.json |
The log. Delete it to forget everything |
A hand-mangled or truncated history.json degrades to "no history" rather than to a broken widget: the parser drops entries it can't read and keeps the ones it can.
Like every Omarchy plugin, this runs unsandboxed in the shell process. It's one QML file and one JS file, both short — read them before you trust them.
Licence
MIT — see LICENSE.