WayShine is a light Linux-focused fork of Sunshine.
Its only product goal is to add native Linux virtual display management for Moonlight streaming while keeping Sunshine's upstream architecture, history, and upgrade path intact.
WayShine adds a strict Linux virtual display path on top of Sunshine's existing
display_device layer.
The v1 implementation targets:
- Linux hosts
- KDE Plasma Wayland
- NVIDIA proprietary driver
- boot-time SDR EDID virtual display
- exact mode switching before capture
- explicit failure when the requested Moonlight mode is unavailable
The important product rule is:
WayShine v1 supports exact client resolutions only if they are predeclared in the installed EDID profile. Missing modes fail explicitly; there is no silent fallback to physical displays or 1080p.
WayShine is intentionally not a broad rewrite of Sunshine.
The v1 scope does not include:
- arbitrary dynamic resolutions
- runtime EDID regeneration
- Apollo/SudoVDA-style hotplug display creation
- HDR virtual display support
- Windows or macOS virtual display features
- a parallel capture or encoder stack
Encoder internals stay upstream Sunshine unless a virtual display integration bug proves otherwise.
The v1 model uses a known-good SDR EDID profile loaded by the kernel at boot:
drm.edid_firmware=<CONNECTOR>:edid/<EDID_FILE> video=<CONNECTOR>:e
At stream launch, WayShine performs a synchronous preflight before app launch and before capture:
- Parse the requested Moonlight resolution and FPS through Sunshine's
display_deviceconfiguration path. - Verify the requested mode exists in the installed EDID profile.
- Verify the mode is visible in
/sys/class/drm/<connector>/modes. - Map the DRM connector to a KDE/KScreen output.
- Apply the mode atomically through the P0 KDE backend.
- Verify the applied mode before allowing capture to continue.
If any step is ambiguous or fails, the stream is rejected.
The first KDE Wayland backend is intentionally conservative:
kscreen-doctoris used as the P0 display-control backend.- It is wrapped behind WayShine's
LinuxDisplayControlBackendabstraction. - A later native helper linked against libkscreen can replace it without changing Sunshine integration points.
- Direct GDBus KScreen control is out of the critical path until a dedicated proof of concept validates stability, atomicity, and restore behavior.
This keeps the first implementation practical while avoiding a dependency on an undocumented DBus contract.
Diagnose the virtual display setup:
wayshine --linux-vdisplay-doctor
wayshine --linux-vdisplay-doctor --jsonInstall the bundled SDR EDID profile on a mutable Fedora-style system:
sudo wayshine --linux-vdisplay-install --connector DP-2 --profile sdr-defaultRemove the installed profile and kernel args:
sudo wayshine --linux-vdisplay-remove --connector DP-2Bazzite and other rpm-ostree systems are treated as partially supported in P0. The doctor can report the state, but automated persistence of EDID firmware, initramfs, and kernel args is not considered verified yet.
Minimal virtual display options:
linux_vdisplay_enabled = enabled
linux_vdisplay_connector = DP-2
linux_vdisplay_profile = sdr-default
linux_vdisplay_backend = kscreen_doctor
linux_vdisplay_mode_policy = exact
linux_vdisplay_restore_on_startup = enabledWayShine reuses Sunshine's existing dd_* display-device options for
resolution, refresh rate, primary display, only-display, and revert behavior.
For strict capture mapping, either set output_name to the virtual connector
or use a dd_configuration_option that makes the virtual output primary or the
only active display.
WayShine preserves Sunshine's Git history so GitHub can maintain the official fork relationship.
- GitHub parent:
LizardByte/Sunshine - Upstream remote:
https://github.com/LizardByte/Sunshine.git - Upstream default branch:
master - WayShine default branch:
main - WayShine baseline:
v2026.508.45922
Project-specific changes should remain small, Linux-scoped, and easy to review on top of Sunshine.
Initialize dependencies after cloning:
git submodule update --init --recursive --depth 1Run the Linux Docker matrix:
scripts/wayshine-build-linux.shRun the lighter CI-style matrix without CUDA:
WAYSHINE_BUILD_TARGET=sunshine-build \
WAYSHINE_LINUX_BUILD_ARGS="--skip-cuda" \
scripts/wayshine-build-linux.shRun a native Linux build:
scripts/wayshine-build-native-linux.shStart from a clean main, then merge a new Sunshine release tag on an upgrade
branch:
scripts/wayshine-merge-upstream.sh vYYYY.MDD.HHMMSSAfter resolving conflicts, run the Linux build matrix and update
UPSTREAM.lock. Do not squash upstream release merges; visible merge commits
make future Sunshine upgrades easier.
For the full workflow, see docs/wayshine/maintenance.md.
For a fresh Codex or Copilot agent, read these first:
AGENTS.mdFORK.mdUPSTREAM.lockdocs/wayshine/maintenance.md
Do not add unrelated fork features. WayShine should stay a small Sunshine fork focused on native Linux virtual display management.