Omarchy
Install the Punktfunk host on Omarchy 4.x — one setup command wires up the firewall, autostart, the app menu and toasts the Omarchy way.
Omarchy 4.x ("Quattro") is Arch underneath, so the packages, the repo and pacman all work
exactly as on the Arch page. What is different is everything around the install:
ufw is on by default, autostart is a user unit tied to the uwsm session, apps belong in the
Omarchy menu, and updates go through omarchy update. One command handles all of it.
Omarchy already ships Sunshine as an installable service and preinstalls moonlight-qt. Punktfunk is the remote desktop on this box — leave Sunshine off unless you are migrating. Both services default to TCP 47990 even with GameStream off; see Sunshine on the same box before you run them together.
One command instead? The guided installer (preview) does everything on this page — it detects the distro, installs the host, joins the groups, opens the firewall and starts it:
curl -fsSL https://punktfunk.unom.io/install.sh | shThe steps below are the same thing by hand, and stay the documented path.
1. GPU driver
Same as Arch:
- NVIDIA:
sudo pacman -S --needed nvidia-utils - AMD / Intel: the Mesa stack you already have (
vulkan-radeon/vulkan-intel,libva-mesa-driver/intel-media-driver).
2. Install the host
curl -fsS https://git.unom.io/api/packages/unom/arch/repository.key | sudo pacman-key --add -sudo pacman-key --lsign-key E0CA04465C99C936E0B0C6510A317015A34DDD69grep -q '^\[punktfunk\]' /etc/pacman.conf || printf '\n[punktfunk]\nServer = https://git.unom.io/api/packages/unom/arch/$repo/$arch\n' | sudo tee -a /etc/pacman.conf >/dev/nullsudo pacman -Sysudo pacman -S punktfunk-host punktfunk-web punktfunk-scripting punktfunk-clientpunktfunk-omarchy setuppunktfunk-web is the browser console and is optional but recommended — it is where the deep
settings live. (punktfunk-scripting adds the plugin runner that fills your game library.)
Not pacman -Syu <package> — that is the Arch line and Omarchy refuses it. Omarchy installs a
pacman hook that aborts any transaction carrying both -S and -u, so it can funnel system
upgrades through omarchy update; the Arch one-liner dies with "Woah partner…" and installs
nothing. -Sy refreshes the databases without a system upgrade and is not blocked, and -S then
installs. Everything else about the repo is identical to Arch.
Omarchy pins Arch packages to a frozen snapshot mirror, so its system libraries may sit behind
rolling Arch. If pacman reports an unsatisfiable dependency, the package is newer than your
snapshot — wait for the next omarchy update, or build from
source.
3. Wire it into Omarchy
punktfunk-omarchy setupThat one command, each step idempotent and each one reversible:
| Step | What it does |
|---|---|
| Groups | offers to add you to input (virtual gamepads) and punktfunk (the virtual Steam Deck pad). Both apply at your next login. |
| Autostart | enables punktfunk-host as a user service so it comes up at login. It also installs the graphical-session.target binding — see Autostart and your session for when that does more than nothing. |
| Firewall | adds ufw rules scoped to your local networks and a dormant tailscale0 rule, each tagged punktfunk-omarchy so remove finds them again. |
| Browser trust (optional) | trusts the console's certificate in Chromium (~/.pki/nssdb), so it opens with no security warning at all. |
| App menu | installs "Punktfunk Web Console" as an Omarchy webapp — it appears in Apps (Super+Space) and opens already logged in, in its own window. |
| Bar widget | the Punktfunk Quickshell widget in the bar — a hero plus SESSION, PAIRING, DEVICES and DISPLAY, without opening the console. It replaces the tray icon, which is hidden while the widget is enabled. |
| Toasts (optional) | pairing requests and stream start/stop as Omarchy notifications, with Approve / Deny buttons on the pairing one. |
| Idle (optional) | keeps the screen awake for the length of a stream and restores your own setting afterwards. |
| Theme (optional) | a ~/.config/omarchy/themed/ template so the console and the Linux client follow omarchy-theme-set. |
| Client menu (optional) | when punktfunk-client is installed: the Punktfunk submenu — the app, the game console, and your saved hosts as connect and wake rows. Host administration lives in its own Punktfunk Host submenu. |
The (optional) steps are rows on the guided installer's own settings screen, answered there
and not asked again here. Run punktfunk-omarchy setup by hand and it takes all of them; each
has an option to decline one (--toasts=0, --theme=0). The bar widget is not optional: it
carries status, pairing and the console, so it replaces the tray rather than sitting beside it.
Check any time with punktfunk-omarchy status, and undo all of it with punktfunk-omarchy remove (your pairings and ~/.config/punktfunk are left alone).
4. Pair
Open Punktfunk Web Console from Apps and pair your first device — or stay in the terminal:
punktfunk-host ctl pair arm # opens a pairing window and prints the PIN
punktfunk-host ctl pending # devices knocking, with names and fingerprint tails
punktfunk-host ctl approve 1See the ctl reference for the full verb list.
Dedicated display vs This screen
What the client sees is a capture-mode switch, not a preset.
| Mode | What streams |
|---|---|
| Dedicated display (default) | A virtual display at the client's exact size and refresh. |
| This screen | The primary (or only) monitor on this box, untouched. |
Pick one from Punktfunk Host in Apps (Super+Space), from the bar panel's DISPLAY
section, or:
punktfunk-omarchy mode dedicated
punktfunk-omarchy mode mirror
punktfunk-omarchy mode --status--status reads local config only: it checks PUNKTFUNK_CAPTURE_MONITOR in host.env before
display-settings.json, and that override wins. The menu's checked rows do not start the host.
This screen is the Streamed screen pin;
Dedicated clears it. Changing the mode restarts a running host, ends its active stream, and applies
to the next connection.
Keep-alive and window re-home
Omarchy runs Hyprland. A disconnect leaves the named headless output up for the keep-alive window; a matching reconnect recasts that same head instead of minting an empty one. Exclusive topology keeps physical monitors dark until real teardown.
When the head does come down, its workspace moves onto a remaining physical monitor. Windows are never destroyed with the stream. A box with no physical left skips the move.
Release a kept head from the console (Virtual displays → Release) or with
punktfunk-host ctl display release. ctl display lists live and lingered heads on this
compositor.
The bar panel
setup installs a Quickshell widget in the Omarchy bar. Click opens a panel in the same
shape as Tailscale, network and audio: a hero, then one scrolling column.
| Section | What it is |
|---|---|
| Hero | Rotating phrases while streaming; the trailing switch starts and stops the user unit. |
| SESSION | Facts, stop / end-game, and a compact sparkline while live. |
| PAIRING | Expands when a device waits; an arm row when the host is idle. |
| DEVICES | Both planes, unpair on the row. |
| DISPLAY | Dedicated / This screen, then the virtual-display presets. |
Right-click the bar mark to stop a live session, or to open the web console when nothing is
streaming. The pairing toast is the pairing-pending hook (Approve / Deny); the panel only
updates its badge. Keyboard: j / k move, Enter activates, Esc closes.
The widget replaces the tray icon while it is enabled. DISPLAY does not list live heads —
Dedicated / This screen and the presets are the daily surface; ctl display lists lingered
ones if you need them.
The client on Omarchy
The other direction — this box as the screen, streaming from a host elsewhere — is just as integrated, and needs none of the host setup above. The guided installer and the step-2 line above already include it on Omarchy; standalone it is one package:
sudo pacman -S punktfunk-clientThe theme follows you automatically. The client reads the active theme's own colors.toml
(no template, no registration), so the app, and the couch console with it, wear your colours and
track omarchy-theme-set live. Two switches turn it off if you'd rather keep Punktfunk's look:
Follow the Omarchy theme in the app's preferences, and Follow system theme in the
console's Interface settings. Both exist only on Omarchy.
Your hosts in the menu (Super+Space). Opt in once —
punktfunk-client --omarchy-menu on # or flip "Hosts in the Omarchy menu" in preferences— and Punktfunk becomes a submenu: one connect row per saved host (type the host's name in
the menu's search and press enter to stream), a wake row where a MAC is known, Open
Punktfunk and the Game console. The rows follow your saved hosts from then on: pairing or
forgetting a host anywhere — the app, the couch console, the CLI — rewrites them.
--omarchy-menu off removes exactly Punktfunk's block and leaves the rest of your
omarchy-menu.jsonc alone.
Autostart and your session
Omarchy offers two Hyprland entries at the login screen, and they differ in a way that matters here:
| Session | What it runs | graphical-session.target |
|---|---|---|
| Hyprland | start-hyprland | never starts |
| Hyprland (uwsm-managed) | uwsm start … Hyprland | starts with the session |
punktfunk-omarchy setup enables the host as a user service, so it comes up at login either
way. What the second session additionally buys is that the host restarts when the session does,
instead of surviving a logout holding a Wayland socket that died with the old compositor.
On the plain Hyprland session that target never starts — which is also why Omarchy's own
omarchy-crash-watch and omarchy-sleep-lock units sit enabled-but-dead there. punktfunk-omarchy status tells you which situation you are in.
It is rarely worth switching sessions just for this: on Hyprland the host re-derives the live compositor on every connect, so the stale-socket failure the binding guards against on KDE and GNOME does not really arise. If you want it anyway, pick Hyprland (uwsm-managed) at the login screen — nothing about Punktfunk needs changing.
Firewall and the video data plane
punktfunk-omarchy setup opens the control ports the Omarchy way — scoped to RFC1918 ranges rather
than to the whole world:
ufw allow from 192.168.0.0/16 to any app punktfunk-native comment "punktfunk-omarchy"The video data plane has no rule, and that is expected. It binds an ephemeral UDP port chosen
per session, so there is nothing fixed to open. Under ufw's default deny-incoming the client's
first packet is dropped and the session falls back to a blind send: the host's own outbound packet
creates the conntrack entry, and the return path rides it. On a LAN — which is the whole point of
hosting here — this works, and it is why punched=false in the logs is normal rather than a fault.
If you want strict control instead, pin the port and open exactly it:
echo 'PUNKTFUNK_DATA_PORT=9779' >> ~/.config/punktfunk/host.env
sudo ufw allow from 192.168.0.0/16 to any port 9779 proto udp comment "punktfunk-omarchy"
systemctl --user restart punktfunk-hostThe cost is one concurrent session on that port; extra sessions fall back to ephemeral ports again.
Tailscale is ready before its interface appears. Setup immediately installs the tagged
allow in on tailscale0 rule. Ufw accepts the named interface before it exists and keeps the rule
dormant until tailscale0 appears. punktfunk-omarchy remove deletes it.
Updating
Punktfunk updates with everything else:
omarchy updateOur repo rides that transaction once it is configured, and it snapshots with snapper first. The web
console therefore shows updates as notify-only on Omarchy and points at this command rather than
offering a one-click apply: a bare pacman -Syu is blocked by Omarchy's own guard, and going around
it would skip the snapshot your rollback depends on.
A snapper rollback reverts /usr — the binaries — while ~/.config/punktfunk and your pairings
live in /home and persist. Nothing needs re-pairing after a rollback.
Sunshine on the same box
Punktfunk is the remote desktop on this box. Leave Sunshine off unless you are migrating.
The packages can share a machine during a trial, but the services do not run together unchanged:
- The management ports collide. Sunshine's web UI and Punktfunk's management API both default to TCP 47990. Stop Sunshine, or move Punktfunk's management API before starting both.
- The GameStream plane collides. Moonlight compatibility uses 47984/47989/48010 and 47998/47999/48000 — exactly Sunshine's TCP and UDP ports. Ours are off by default; leave them off unless you are migrating, and only one host can bind them.
To migrate: omarchy remove service sunshine, then turn GameStream on only if you still want
stock Moonlight clients. More in Switching from Sunshine.
GameStream is the Moonlight hatch
Native Punktfunk clients do not need GameStream. Stock Moonlight does. It is a trusted-LAN hatch, not the default:
- Punktfunk Host → GameStream in Apps (
Super+Space) punktfunk-omarchy gamestream— pinsPUNKTFUNK_GAMESTREAM=1, restarts the host, opens the extra ufw profile
A Moonlight client shows a PIN on the device; enter it with Punktfunk Host → Moonlight PIN. Do not turn GameStream on while Sunshine still holds those ports.
Screen sharing keeps working
Omarchy ships its own screen-share picker (hyprland-preview-share-picker), the one every browser
share on the box goes through. Punktfunk needs that same setting to select a headless output
without a dialog, so while a stream runs it borrows the setting — and defers to your picker
whenever no Punktfunk selection is pending. Your browser shares behave exactly as before, during a
session and after it, and the original value is written back when the last stream ends. If a host
is killed mid-session, punktfunk-omarchy remove puts it back too.
Keyboard shortcut (optional)
Punktfunk claims no chord — Omarchy occupies most of Super+*. Add your own to
~/.config/hypr/bindings.lua:
o.bind("SUPER + SHIFT + P", "Punktfunk", { webapp = "https://localhost:47992" })Wake-on-LAN and disk encryption
Omarchy enables full-disk encryption by default. Wake-on-LAN still wakes the machine, but a cold boot stops at the LUKS passphrase prompt — nothing can stream until someone types it. Wake from suspend is unaffected, so suspend rather than shut down a box you want to wake into.
Troubleshooting
Run punktfunk-omarchy status first — it checks the units, the ufw rules, your groups, the portal
and Hyprland's permission mode in one pass.
Black frames, or input that does nothing. Check whether Hyprland's permission enforcement is on:
hyprctl -j getoption ecosystem:enforce_permissionsIf it is, the compositor is silently denying screencopy and virtual input — there is no error, only black frames and dropped input. Grant the host in your Hyprland config:
o.permission("/usr/bin/punktfunk-host", "screencopy", "allow")
o.permission("/usr/bin/punktfunk-host", "plugin", "allow")No picture at all. xdg-desktop-portal-hyprland must be running — it is what capture goes
through. systemctl --user status xdg-desktop-portal-hyprland.
The host is not running after a reboot. punktfunk-omarchy status will say whether it is bound
to the desktop session; if not, re-run punktfunk-omarchy setup.
Physical monitors stayed dark after disconnect. Exclusive topology plus keep-alive — the
named head is still up. Release it from the console or punktfunk-host ctl display release. See
Virtual displays.
More in Troubleshooting and on the Hyprland page, which covers the compositor-level details this page assumes.
Uninstall
punktfunk-omarchy remove # the Omarchy wiring
sudo pacman -R punktfunk-host punktfunk-web # the packagesremove reverses every step of setup — units, drop-in, ufw rules, certificate trust, the webapp,
the bar widget, the hooks and the theme template — and restores both the screen-share picker and
the tray icon. Your config and pairings survive both; see Uninstall to clear
those too.