Omahub
← All plugins
H

Omasmash

by haydenmckay

Beautiful, theme-aware keyboard smash with a real lock screen underneath. Hand the keyboard to a toddler and they can't reach your agents — and neither can you, on the tenth “fix it, and don't make any mistakes.”

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
915001b
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

Review recommended

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Medium
AI risk level
Medium
Recommendation
review
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
915001b
Reviewed
1 month ago

No obfuscation, destructive install behavior, or hidden exfiltration was found; the installer is conservative and the code is unusually careful about the lock lifecycle. The real risk is functional: this is a pre-alpha service that takes a compositor-enforced Wayland session lock and accepts a PAM password, so a crash or bug while locked can strand the user, and the project's own notes say key unlock paths are not yet tested with real input. A human should verify Service.qml and the recovery paths on real Omarchy hardware before publishing.

  • Pre-alpha session-lock service: if the process dies or wedges while the lock is held, the compositor keeps the screen locked; recovery depends on an untested PAM/passphrase path, IPC, and TTY access, so lockout is a realistic risk.
  • The PAM fallback means users may type their real account password into this QML process; the sampled code appears designed not to display or log it, but the full Service.qml should be reviewed to confirm no exposure through status()/IPC or crash logs.
  • The project's own docs note that the Hyprland submap hotkey-blocking passed only in the nested legacy-parser harness and did nothing on a real Lua-configured session, so the advertised hotkey-blocking/panic behavior needs verification on actual Omarchy.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/haydenmckay/omarchy-omasmash --enable
Appearance #Hyprland #quickshell

Omasmash

Omasmash

Beautiful, theme-aware keyboard smash with a real lock screen underneath.

Hand the keyboard to a toddler and they can't reach your agents — and neither can you, on the tenth "fix it, and don't make any mistakes."

Every keypress paints a big letter in your active theme's colours, every click splashes, every drag trails — and the machine underneath stays untouchable.

Status: pre-alpha. The session-lock premise test passes (docs/premise-test.md), but the passphrase and corner-hold unlock paths have not been tested with real input yet. Read RECOVERY before you run it — all of it.

Why this isn't a web page

The existing smash toys are browser based, and a browser tab cannot hold the input. Escape, or any of a dozen key combos, drops fullscreen — and now the keyboard is pointed at your email. Even BabySmash, the 2008 Windows original, could only block input on a best-effort basis from inside a normal app.

Omasmash is built on ext-session-lock-v1, the Wayland session-lock protocol — the same mechanism behind Omarchy's real lock screen. Input exclusivity is enforced by the compositor, not by a focus grab. While it is up, nothing else on the system receives keyboard or pointer input. No Escape, no Alt-Tab, no alt-clicking the window away.

So: Omasmash is a lock screen that plays instead of asking for a password.

What it looks like

demo

It opens by flying the camera through a corridor of letters, hits, and drops you into the play surface.

It follows your theme

themes

Tokyo Night, Gruvbox, Rosé Pine, Everforest — including light ones.

Every other keyboard-smash toy looks like itself. This one looks like your desktop.

Theming

Colours come from your active theme, live. Omasmash reads ~/.local/state/omarchy/current/theme/colors.toml directly rather than going through the shell's Color singleton, because that singleton only exposes five roles and a play surface wants the whole crayon box. Your wallpaper is drawn behind the play surface, dimmed, so it still reads as your desktop.

Switch themes and it follows — the palette is re-read when current/theme.name changes.

Starting it

Three ways in, all of them the same toggle underneath — it locks if unlocked and unlocks if locked, so one action does both.

From the app menu. Hit SUPER, type omasmash. This requires having run bin/omasmash-install — omarchy plugin add installs the plugin, not a desktop entry, so the menu entry does not appear on its own.

From a hotkey. Bind a chord to omasmash-toggle. No keybinding is installed by this project — binding a chord that locks your session is your call. See docs/hotkey.md for a suggested bind and how to pick one a toddler cannot reach with a flat palm.

From a terminal, which is also how you get out of trouble:

omasmash-toggle                    # if you ran omasmash-install
omarchy-shell omasmash lock        # always available
omarchy-shell omasmash unlock

Unlocking

Three ways out, in order of everyday usefulness:

  1. Type the passphrase — omarchy by default. Seven characters in sequence is effectively unreachable by random smashing. Nothing is displayed while you type.
  2. Hold the top-right corner for three seconds — there is a small "or hold here" plate there, which fills as you hold. Discoverable for an adult, impossible while flailing. It sits opposite the passphrase hint so that reaching for one cannot trigger the other.
  3. Type your real password and press Enter. There is no visible field — keystrokes accumulate invisibly and Enter submits them to PAM. This always works, even if you changed the passphrase and forgot it. Safe to use in front of people: nothing you type is ever displayed (see why).

This is a child lock, not a security lock

Say it plainly: the passphrase is a known string. It stops a toddler, and it stops you from doing damage while you smash. It does not stop a person with physical access to your machine, and it is not a substitute for omarchy.lock. Do not walk away from an unattended machine with only Omasmash up and consider it locked.

Hotkeys are blocked too

ext-session-lock-v1 stops input reaching other clients, but Hyprland resolves its own keybinds before delivery — so without more work SUPER+Q and SUPER+SHIFT+E still fire through a lock screen, and a toddler can close windows or kill your session through it.

Omasmash puts Hyprland into a submap while active, which makes every other bind on the system inert. The submap carries exactly one chord:

SUPER + CTRL + ALT + SHIFT + Escape     # restores keybinds, then unlocks

Deliberately awkward, because it must never be reachable by a palm on the keyboard — and because a process that dies holding the submap would otherwise leave you a desktop with no shortcuts at all. The service also clears the submap unconditionally on startup, since nothing else on the system will.

Typed characters are never shown

Press k and you get some other letter, or a dinosaur. The glyph is random, deliberately — it is what makes the password route above safe to use in a room with other people in it. Full reasoning, and the one case for turning it off, in docs/security.md.

Emoji also arrive on their own, at intervals that keep changing. A letter every time is a machine; a letter every time except when a rocket shows up is worth staying for.

RECOVERY

ext-session-lock-v1 gives the compositor the last word: if the locking client dies while the lock is held, the screen stays locked. That is the protocol working as designed — it is what stops someone unlocking your machine by crashing your lock screen — but for a toy it is a genuine risk of locking yourself out. Layers of defence, cheapest first:

1. The paint watchdog (automatic). The play surface drives a canary from the render loop. If it stops advancing for two consecutive five-second samples, the service concludes the surface has stopped painting and releases the lock itself — verified end to end, about twelve seconds from stall to unlock (test).

It covers rendering stopping while the event loop still runs. It cannot cover a dead process, and it cannot cover a wedged QML event loop — the watchdog runs in the same engine, so an infinite loop stops it too. That is what the routes below are for.

2. Your PAM password, typed on the play surface followed by Enter. Nothing you type is displayed — see docs/security.md.

3. IPC unlock, from another machine or an SSH session:

~/Work/omarchy-omasmash/bin/omasmash unlock

Works whenever the process is alive and answering, including when the screen is showing nothing useful.

4. hl.clear_crashed_lockscreen. Hyprland can be told to drop a lock whose client has died, without a TTY:

hyprctl dispatch 'hl.clear_crashed_lockscreen()'

5. The TTY escape. If the process is dead and the compositor is still holding the lock:

Ctrl+Alt+F2          # switch to a text console
<log in>
pkill -f omasmash     # or: pkill quickshell
Ctrl+Alt+F1          # switch back

Omarchy's own stranded-lock handling then applies: a freshly started instance detects a lock it did not take (via omarchy-hyprland-session-locked) and adopts it, giving you a surface that can accept your PAM password.

Verify you can get to a TTY on your machine before you run the first lock test. That is the floor under everything else here. On a systemd machine, Ctrl+Alt+F2 spawns a login on demand only if autovt@.service resolves to a valid getty@.service and logind's NAutoVTs covers that VT — check both rather than assuming.

Prerequisite: allow_session_lock_restore

Recovery step 3 only works if Hyprland has misc:allow_session_lock_restore = true. Omarchy sets this by default (default/hypr/looknfeel.lua). If you have turned it off, there is no in-session recovery at all: a new client trying to take over a stranded lock is killed by the compositor with a fatal Wayland protocol error, and only a TTY will get you back in. Verify with:

hyprctl getoption misc:allow_session_lock_restore

See docs/premise-test.md for the full reproduction.

Known upstream issues this inherits

  • Omarchy #6888 — stranded-lock recovery never completes.
  • Omarchy #7478 — lock screen crash-loops roughly every 18s after DPMS-off.

Both are live against the session-lock path Omasmash is built on, and both are part of the premise test's acceptance criteria.

Requirements and what this plugin touches

Everything here ships with Omarchy — there is nothing extra to install.

Used For
hyprctl Registering and switching the keybind submap, and reading it back
omarchy-shell The toggle and panic scripts reach the service over shell IPC
omarchy-hyprland-session-locked Detecting a stranded lock left by a dead client
bash The scripts in bin/
PAM (/etc/pam.d/omarchy-lock-password) The password unlock route, shared with Omarchy's own lock screen

Privilege boundaries, stated plainly, because nothing downstream checks them for you:

  • It takes a real session lock. While active, the compositor gives it exclusive input and will keep the screen locked if this process dies. See RECOVERY before first use.
  • It changes your global keybinds. While active it puts Hyprland into a submap, which makes every other keybind on your system inert until it releases. It clears the submap on unlock and again on startup.
  • It authenticates against PAM, using Omarchy's existing omarchy-lock-password configuration. It does not read, store, or transmit your password; keystrokes go to PAM and are never displayed (see docs/security.md).
  • No network access. No telemetry. Nothing written outside the plugin directory.

Development-only extras, not needed to run it: grim, ffmpeg and imagemagick for bin/omasmash-capture, and a nested Hyprland for bin/omasmash-nested.

Installing

omarchy plugin add https://github.com/haydenmckay/omarchy-omasmash --enable
omarchy-restart-shell

The restart is not optional: the Omarchy shell runs with its file watcher disabled, so it will not pick up a newly installed or updated plugin until it restarts.

Optionally, to make Omasmash searchable in the SUPER menu and put the CLI on your PATH:

~/.config/omarchy/plugins/io.github.haydenmckay.omasmash/bin/omasmash-install

It installs a desktop entry, an icon, and three symlinks in ~/.local/bin — and nothing else, and nothing it does not own. Every target is checked first; if anything is already there that this installer did not create, it lists them, changes nothing, and exits. Pass --force to replace them deliberately, or --uninstall to remove only what it recorded creating.

No hotkey is installed — binding a chord that locks your session is your decision. See docs/hotkey.md.

Or just ask your agent

You are probably running one. Paste this at it:

Install the Omasmash plugin for Omarchy from
https://github.com/haydenmckay/omarchy-omasmash

Then:
1. omarchy plugin add the repo and enable it, then omarchy-restart-shell
   (the shell has its file watcher disabled and will not pick it up otherwise)
2. Run bin/omasmash-install from the installed plugin directory so it appears
   in the app menu
3. Bind a hotkey to omasmash-toggle. Pick a chord a toddler cannot hit with a
   flat palm, and check it against `hyprctl binds` first so you do not
   clobber an existing Omarchy binding
4. Before locking anything, read the RECOVERY section of the README back to me
   and confirm I can reach a TTY on this machine

Step 4 is not padding. This takes a real session lock, and the compositor will keep the screen locked if the process dies — you want to know your way out before you need it, not after.

Binding a hotkey means editing your Hyprland config, which this project will never do on its own. Asking your agent to do it is your consent; it is not the same as the installer doing it behind you.

Removing

omarchy plugin remove io.github.haydenmckay.omasmash
omarchy-restart-shell

If you ran omasmash-install, undo it first — it removes only the files it recorded creating, so nothing of yours goes with it:

bin/omasmash-install --uninstall

Development

Runs as a standalone Quickshell instance, not an installed plugin — a crash here cannot take your bar down with it, and restarts take about a second instead of bouncing the whole shell.

bin/omasmash preview   # windowed visual preview -- no lock, no compositor
bin/omasmash full      # fullscreen preview -- still no lock, Escape quits
bin/omasmash run       # the real service (does NOT lock on its own)
bin/omasmash lock      # lock
bin/omasmash unlock    # release
bin/omasmash status    # JSON: lock state, theme, watchdog, hotkeys, PAM

Use the previews for anything visual — they hot-reload and cannot lock you out. The nested compositor is only needed for changes to the lock lifecycle itself.

Run every lock, crash, and kill -9 test inside the nested compositor, where a stranded lock strands a window instead of your machine:

bin/omasmash-nested          # nested Hyprland with Omasmash inside
bin/omasmash-nested --kill   # from the host, if it wedges

Licence

MIT.