The stream rendered but ignored keyboard and mouse. Sunshine injects input through uinput exclusively — it has no support for the Wayland virtual keyboard/pointer protocols — so the compositor has to have a libinput backend to see those devices. WLR_BACKENDS=headless creates only the headless backend, so sway had zero input devices against the kernel's 24. libinput needs a seat, and a systemd --user service belongs to no logind session, so libseat needs seatd. seatd is now enabled on this host. Its socket defaults to group `seat`, which does not help here: the user manager's group list is fixed when it starts, Linger=yes means that is at boot, and so adding connor to `seat` would not take effect until a reboot — re-logging in changes nothing. The drop-in points seatd at `video`, a group connor already holds for GPU access, which makes this deterministic instead of dependent on group-propagation timing. sway now reports 7 input devices including libvirtualhid Mouse and Keyboard, which are Sunshine's. hosts/mainframe/etc/ is a new tree for system-level config; install flags it the same way it flags sbin.
34 lines
1.5 KiB
Desktop File
34 lines
1.5 KiB
Desktop File
[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.
|