Skip to content

westers/krdp

Repository files navigation

KRdp

Library and examples for creating an RDP server.

Remote Desktop KCM

Remote Desktop Settings Window

Remote Desktop System Settings page (KCM) that lives in the Networking category.

Features:

  • User can toggle the server (running thekrdpserver binary) on and off using a toggle switch.
  • The server can be set to auto-start at session login.
  • The KCM uses SystemD DBus messages to toggle the server on and off and auto-start it.
  • User can easily add, modify, and remove usernames and passwords that are allowed to connect to the server.
  • User can change the port of the server.
    • Do note that the address is currently set to 0.0.0.0, which means any interface that accepts connections for krdpserver will work.
  • Certificates can be auto-generated (this is done by default), or the user can supply their own certificates.
  • Video quality can be changed between responsiveness and quality.
    • Do note that in software encoding mode, the quality slider might not necessarily do anything. This seems to be an encoder issue.
  • Display target can be set to stream the full workspace, primary monitor only, or a specific monitor by ID.
    • A read-only monitor ID map shows which ID corresponds to which screen.
  • VAAPI hardware encoder driver can be configured (automatic, disabled, AMD radeonsi, or Intel iHD).
  • The KCM will do some basic sanity-checking and warn the user about the following issues:
    • Password manager inaccessible (for KRDP user passwords)
    • No supported H264 encoder
    • Failures with generating certificates

Not all setting changes require a server restart. Settings that take effect immediately without disconnecting active sessions:

  • Video quality
  • Display target, monitor ID
  • VAAPI driver mode
  • Autostart on login

Settings that require a server restart (the KCM will show a warning banner):

  • Listening port
  • User credentials (add/modify/remove)
  • System user authentication toggle
  • Certificate configuration (auto-generate toggle, certificate paths)

Running the example server

The example server requires a username and password to be provided on the command line, which will be used when connecting from an RDP client. They can be provided using the -u and -p command line parameters, respectively. For example:

krdpserver -u user -p test

The server will then listen on all interfaces on port 3389, and clients can connect with the username "user" and the password "pass".

Connecting to the example server

To connect to the server, make sure to pass the username and password the server was started with. Note that the username is case-sensitive; this may be especially unexpected for those using Microsoft Windows RDP clients to connect, as system usernames on that platform are generally not case-sensitive.

Currently, the main client that has been used for testing and is confirmed to work is the FreeRDP client. Launch the FreeRDP client with the following command: xfreerdp /u:<username> /p:<password> -clipboard /v:<ip_address>:3389, filling in the username, password and IP address as appropriate. If testing locally, substitute localhost for an IP address.

Security considerations

In addition, a valid TLS certificate and key are required to encrypt the communication between client and server. The server will look for a file called server.crt and server.key in the current working directory, but a different path can be provided using the --certificate and --certificate-key command line parameters. If no valid certificate is found using any of these methods, the server will internally generate a self-signed certificate and use that.

Command Line Options

The following command line options are available for the example server:

-u, --username
The username to use when a client tries to login. Required.
-p, --password
The password to require when a client tries to login. Required.
--port
The port to listen on for connections. Defaults to 3389.
--certificate
The path to a TLS certificate file to use. If not supplied or it cannot be found a temporary self-signed certificate will be generated.
--certificate-key
The path to the TLS certificate key that matches the provided certificate.
--monitor
The index of the monitor to use for streaming video. If not supplied the whole workspace is used.
--quality
Set the video quality, from 0 (lowest) to 100 (highest).

When --monitor is not supplied, KRDP uses persisted config keys:

  • General/MonitorMode=workspace|primary|specific
  • General/MonitorIndex=<id> (used when mode is specific)

The KDE Remote Desktop settings page exposes this as Display target and Monitor ID, and shows the current monitor ID map (0: <screen name>, etc.).

Known Working and Not-Working Clients

The following clients are known to work with the server:

  • XFreeRDP and wlFreeRDP from the FreeRDP project.
  • Remmina, a remote desktop client for Gnome.
  • Thincast Remote Desktop Client
  • Windows Remote Desktop client, at least as shipped with a recent Windows 10.

The following clients are known not to work:

  • Microsoft's Remote Desktop client for Android. While it should support H.264 it seems to not enable it.

Known Issues and Limitations

  • Only video streaming and remote input is supported.
  • Only the NLA security type of RDP is supported.
  • Only one username and password combination is supported for login.
  • Only the "Graphics Pipeline" extension of the RDP protocol is implemented for video streaming. This extension allows using H.264 for video streaming, but it means only clients supporting that extension are supported.
  • H.264 encoding is done using hardware encoding if possible, but currently we only support using VAAPI for this. Most notably this means hardware encoding on NVidia hardware can not be used and software encoding will be used instead. Additionally, on certain hardware there are limits to what size of frame can be encoded by the hardware. In both cases, encoding will fall back to software encoding.
  • KDE's implementation of the Remote Desktop portal is rather limited as shipped with Plasma 5.27. Most notably it does not allow selecting which screen to stream, nor does it have an option to remember the setup and reuse it when the same application requests a new connection. As a workaround, the server will open a remote desktop session on startup and reuse that session for all RDP connections. Additionally, monitor selection can be done using the --monitor command line option.
  • Input on a high DPI screen may be offset incorrectly. This is due to a bug in the Remote Desktop Portal that has been fixed in the meantime. The fix will be released with KDE Plasma 5.27.8.

CLI

While currently not very well supported it is possible to configure KRdp purely from a CLI. This is particularly useful when you have access over SSH but haven't yet configured KRdp.

# Authorize the krdpserver for remote desktop access
flatpak permission-set kde-authorized remote-desktop org.kde.krdpserver yes

# Generate a server certificate
mkdir --parents "$HOME/.local/share/krdpserver"
certificatePath="$HOME/.local/share/krdpserver/krdp.crt"
certificateKeyPath="$HOME/.local/share/krdpserver/krdp.key"
openssl req -nodes -new -x509 -keyout "$certificateKeyPath" -out "$certificatePath" -days 1 -batch

# Configure the certificate and enable system user authentication
kwriteconfig6 --file krdpserverrc --group General --key Certificate "$certificatePath"
kwriteconfig6 --file krdpserverrc --group General --key CertificateKey "$certificateKeyPath"
kwriteconfig6 --file krdpserverrc --group General --key SystemUserEnabled true
# Optional: display target (workspace|primary|specific) and monitor ID
kwriteconfig6 --file krdpserverrc --group General --key MonitorMode workspace
kwriteconfig6 --file krdpserverrc --group General --key MonitorIndex 0
# Optional: VAAPI driver mode (auto|off|radeonsi|iHD)
kwriteconfig6 --file krdpserverrc --group General --key VaapiDriverMode auto

# Enable/restart the systemd service
systemctl --user enable --now app-org.kde.krdpserver.service
systemctl --user restart app-org.kde.krdpserver.service

Running A Local Build Under systemd

When testing changes from your local checkout, use a user service drop-in and a matching desktop entry override so Wayland privilege checks (fake_input and zkde_screencast_unstable_v1) apply to your local binary.

# Build
cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug
cmake --build build -j"$(nproc)"

# Desktop entry override (required when ExecStart points to the build tree)
mkdir -p "$HOME/.local/share/applications"
cp /usr/share/applications/org.kde.krdpserver.desktop "$HOME/.local/share/applications/org.kde.krdpserver.desktop"
sed -i "s#^Exec=.*#Exec=$PWD/build/bin/krdpserver#" "$HOME/.local/share/applications/org.kde.krdpserver.desktop"
kbuildsycoca6 --noincremental

# systemd user drop-in
mkdir -p "$HOME/.config/systemd/user/app-org.kde.krdpserver.service.d"
cat > "$HOME/.config/systemd/user/app-org.kde.krdpserver.service.d/zz-krdp-plasma.conf" <<EOF
[Service]
UnsetEnvironment=LIBVA_DRIVER_NAME
Environment=XDG_DATA_DIRS=%h/.local/share:/usr/local/share:/usr/share
ExecStart=
ExecStart=$PWD/build/bin/krdpserver --plasma --monitor 0
EOF

# Reload and restart
systemctl --user daemon-reload
systemctl --user restart plasma-xdg-desktop-portal-kde app-org.kde.krdpserver

# Verify active command
systemctl --user show app-org.kde.krdpserver.service -p ExecStart

To switch back to the packaged binary:

cat > "$HOME/.config/systemd/user/app-org.kde.krdpserver.service.d/zz-krdp-plasma.conf" <<EOF
[Service]
UnsetEnvironment=LIBVA_DRIVER_NAME
ExecStart=
ExecStart=/usr/bin/krdpserver --plasma --monitor 0
EOF
systemctl --user daemon-reload
systemctl --user restart plasma-xdg-desktop-portal-kde app-org.kde.krdpserver

Useful runtime log command:

journalctl --user -f -o cat -u app-org.kde.krdpserver -u plasma-xdg-desktop-portal-kde

Codec Experiment Flags

KRDP_EXPERIMENTAL_AVC444=1 and KRDP_EXPERIMENTAL_AVC444V2=1 enable AVC444 capability negotiation experiments.

KRDP_EXPERIMENTAL_TRUE_AVC444=1 enables experimental AVC444 wire transport (RDPGFX_AVC444_BITMAP_STREAM, single-stream mode) when AVC444/AVC444v2 is negotiated.

Without KRDP_EXPERIMENTAL_TRUE_AVC444=1, KRDP automatically falls back to AVC420 transport while preserving AVC444 intent for quality tuning.

VAAPI Driver Auto-Selection

On mixed-GPU systems, KRDP now attempts to avoid decode-only VAAPI backends by auto-selecting a non-NVIDIA LIBVA_DRIVER_NAME when possible.

The persisted KCM/config key is General/VaapiDriverMode with these values:

  • auto (default): automatic mixed-GPU selection.
  • off: disable KRDP VAAPI driver auto-selection.
  • radeonsi: force AMD VAAPI driver.
  • iHD: force Intel VAAPI driver (runtime fallback to i965 remains available).

Note for NVIDIA-only systems: current KRDP hardware encode integration is VAAPI-based. NVIDIA acceleration typically uses NVENC instead, so KRDP falls back to software (libx264) unless a non-NVIDIA VAAPI encode path is present. This is an API-path limitation, not raw GPU compute performance.

KRDP can optionally retry once with forced libx264 if the PipeWire stream becomes active but does not deliver encoded packets within the timeout window. This stall watchdog is disabled by default and must be opted into:

systemctl --user set-environment KRDP_ENABLE_STALL_WATCHDOG=1

When enabled, the override is temporary for that retry path and then restored, so panel-selected VAAPI mode continues to apply for subsequent sessions.

Manual environment override examples:

systemctl --user set-environment KRDP_AUTO_VAAPI_DRIVER=0
systemctl --user set-environment KRDP_FORCE_VAAPI_DRIVER=radeonsi

KPipeWire Patch (Damage Metadata)

The local KRDP improvements can use extra encoded-frame metadata from a patched KPipeWire build. The patch is tracked in this repository:

  • patches/kpipewire/0001-damage-metadata-encoded-stream.patch

Apply it in a KPipeWire checkout with:

cd /path/to/kpipewire
git apply /path/to/krdp/patches/kpipewire/0001-damage-metadata-encoded-stream.patch

Performance Tuning Notes

Recent KRDP builds include several latency and artifact-reduction behaviors:

  • Damage-aware region updates with rectangle coalescing.
  • Freshest-frame delivery under load (stale queued frames are dropped).
  • Packet/damage metadata pairing with a short wait budget before full-frame fallback.
  • Tile activity classification (static regions biased for crisp quality, transient regions biased for compression).
  • Progressive refinement: after motion settles, one high-quality full-frame refresh is sent.
  • AVC444-intent fallback bias: if a client asks for AVC444 but local transport is AVC420-only, KRDP slightly raises quality for text/static UI regions.

Useful debug markers:

journalctl --user -f -o cat -u app-org.kde.krdpserver | \
  rg -i 'Dropped stale queued frames|No matching damage metadata|Sent progressive refinement frame|Using AVC444 wire transport mode'

SDDM Autologin

Since SDDM currently has no RDP support, you either need to already be logged in, or let SDDM auto log in to the user.

Mind that your session starts physically unlocked on your PC. Also when you are remote logging into your session it will be physically unlocked.

# Configure autologin for your current user
user=$(whoami)
sudo kwriteconfig6 --file /etc/sddm.conf.d/kde_settings.conf --group Autologin --key User $user

# Enable automatic relogin on logout to avoid scenarios where the system is stuck on sddm
sudo kwriteconfig6 --file /etc/sddm.conf.d/kde_settings.conf --group Autologin --key Relogin true

# Restart sddm to force an autologin (don't run this if you are already logged in :D)
## systemctl restart sddm.service

Smoke Test Script

Use the bundled smoke test helper to rebuild KRDP, restart services, and watch the key log markers used during tuning:

./smoke-test.sh

Useful flags:

./smoke-test.sh --no-build --watch-seconds 180
./smoke-test.sh --no-watch
./smoke-test.sh --no-build --assert-encoder vaapi
./smoke-test.sh --no-build --assert-encoder software

About

KRDP performance-focused fork with damage-aware streaming, low-latency frame scheduling, and metadata-driven quality refinement for Plasma/Wayland RDP.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors