[Unit] Description=Headless Wayland compositor for Sunshine Documentation=https://docs.lizardbyte.dev/projects/sunshine/ ConditionHost=mainframe [Service] Type=simple # headless for the virtual output, libinput so there is an input backend at # all. With WLR_BACKENDS=headless alone wlroots creates no libinput backend, # so the compositor has zero input devices and Sunshine's uinput keyboard and # mouse are never picked up — the stream shows the desktop and ignores you. # # libinput needs a seat, and a systemd --user service sits in no logind # session, so libseat falls back to seatd. That is why seatd.service is enabled # on this host and connor is in the seat group. Environment=WLR_BACKENDS=headless,libinput Environment=LIBSEAT_BACKEND=seatd # Do not fail to start when no input device is present yet; Sunshine creates # its virtual ones only once a client connects. Environment=WLR_LIBINPUT_NO_DEVICES=1 # Pin the compositor to the NVIDIA card (card0 = 01:00.0, renderD129), which is # also what sunshine.conf names as its encoder. Without this wlroots picks the # Intel iGPU and every captured frame crosses GPUs. Environment=WLR_DRM_DEVICES=/dev/dri/card0 Environment=XDG_CURRENT_DESKTOP=sway ExecStart=/usr/bin/sway -c %h/.config/sway/headless.conf ExecStopPost=/usr/bin/systemctl --user stop sunshine.service Restart=on-failure RestartSec=5s # Deliberately NOT WantedBy=default.target. The 3060 also holds the local LLM, # and this stack costs ~220 MiB of VRAM. Start it with `stream on`; the # idle-stop timer puts it away again.