Virtual Display on KDE Wayland: Krfb-Virtualmonitor + Sunshine Streaming
My setup
- CachyOS (Arch-based)
- KDE Plasma 6 + Wayland
- NVIDIA RTX 2070 Mobile, proprietary driver 570
- Sunshine v2025.x
Steps
1. Install dependencies
sudo pacman -S krfb kscreenkrfb provides the krfb-virtualmonitor command, and kscreen provides kscreen-doctor for adjusting resolution and refresh rate.
2. Create the virtual display
krfb-virtualmonitor --resolution 2560x1440 --name sunshine-vm --password pass --port 5905 &Parameter notes:
--resolution: Initial resolution. Give it a large value (e.g., 2560x1440 or 3840x2160) — you can switch to a specific resolution later withkscreen-doctor--name: Pick whatever you like. You’ll reference this inkscreen-doctorcommands--password/--port: VNC password and port. You don’t need VNC access for Moonlight, but these are required arguments
After running, open System Settings → Display & Monitor — you should see the new virtual display.
Verify:
kscreen-doctor -o | grep -A5 Virtual3. Configure Sunshine
This is the critical step: Sunshine’s default capture mode is kms, which can’t see krfb-virtualmonitor outputs (those exist at the Wayland compositor level, not the DRM/KMS level). You need to switch to kwin mode.
Sunshine Web UI → Configuration → Advanced → Force Capture Method → select kwin.
Restart Sunshine:
systemctl --user restart sunshine4. Setting refresh rate
krfb-virtualmonitor has no --refresh parameter — it defaults to 60 Hz. To change it:
# Unit is mHz: 120 Hz = 120000
kscreen-doctor output.Virtual-sunshine-vm.addCustomMode.1920.1080.120000.full
# Apply
kscreen-doctor output.Virtual-sunshine-vm.mode.1920x1080@120Note the different formats: addCustomMode takes dots (1920.1080.120000), while mode uses the conventional format (1920x1080@120). Don’t mix them up.
Verify:
kscreen-doctor -o | grep -A10 VirtualYou should see the * marker next to the current mode and refresh rate.
5. Optional: manage the virtual display with systemd
If you don’t want to manually start the virtual display every time, wrap it in a user service for autostart.
# ~/.config/systemd/user/krfb-virtualmonitor.service
[Unit]
Description=Virtual display for Sunshine streaming
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=simple
ExecStart=/usr/bin/krfb-virtualmonitor --resolution 2560x1440 --name sunshine-vm --password pass --port 5905
ExecStartPost=/bin/sh -c 'sleep 3 && /usr/bin/kscreen-doctor output.Virtual-sunshine-vm.addCustomMode.1920.1080.120000.full && /usr/bin/kscreen-doctor output.Virtual-sunshine-vm.mode.1920x1080@120'
Restart=on-failure
RestartSec=5
[Install]
WantedBy=graphical-session.targetsystemctl --user daemon-reload
systemctl --user enable --now krfb-virtualmonitor.serviceThis must be a user service. A system service doesn’t have access to $WAYLAND_DISPLAY and $XDG_RUNTIME_DIR, so krfb-virtualmonitor can’t connect to KWin.
The ExecStartPost command does three things: waits 3 seconds for KDE to register the virtual display → registers a custom mode (addCustomMode) → switches to it (.mode.). addCustomMode only registers — it doesn’t switch. You always need .mode. afterward.
To also set the display scale:
ExecStartPost=/bin/sh -c 'sleep 3 && /usr/bin/kscreen-doctor output.Virtual-sunshine-vm.addCustomMode.2560.1440.120000.full && /usr/bin/kscreen-doctor output.Virtual-sunshine-vm.mode.2560x1440@120 && /usr/bin/kscreen-doctor output.Virtual-sunshine-vm.scale.1.5'Keep --resolution, addCustomMode, and .mode. values consistent. Adjust scale as needed (1.5 = 150%).
Fractional scaling: For non-integer values like
1.5, enable “Allow fractional scaling” in System Settings → Display & Monitor first, or setXwaylandScaleOverride=150in~/.config/kwinrcand restart kwin.
If you’d rather not keep the virtual display running all the time, you can tie it to Sunshine’s service lifecycle for on-demand start/stop:
# ~/.config/systemd/user/sunshine.service.d/override.conf
[Unit]
Wants=krfb-virtualmonitor.service
After=krfb-virtualmonitor.serviceThis pulls in the virtual display when Sunshine starts and stops it when Sunshine exits.
Display switching
Moonlight has a built-in shortcut: Shift + Ctrl + Alt + F1 ~ F12 to switch between virtual desktops/displays.
Connect via Moonlight, then press this combo to toggle between your physical display and the virtual one. No need for do/undo scripts that disable physical monitors — just switch. Whatever is on the physical screen doesn’t affect the stream.
If you have three or more displays (e.g., laptop panel + external monitor + virtual display), F1/F2/F3 map to different outputs.