Files
BetterDesk/rdclient-desktop

BetterDesk RdClient Desktop

Tauri v2 desktop shell for the RdClient operator UI. The app loads your panels /remote dashboard in the main window and opens each remote session in a separate window (/remote/:deviceId), similar to RustDesk.

This is production-ready Phase C+ of the RdClient roadmap: server validation, LAN discovery, settings/reset, encrypted peer passwords, full panel i18n, codec fallbacks on Linux, and generator-built installers with embedded panel URL.

Prerequisites

  • Node.js 18+ (for @tauri-apps/cli)
  • Rust stable (1.77+; tested with Fedoras toolchain)
  • Linux: webkit2gtk-4.1, libayatana-appindicator3, librsvg2, patchelf (Tauri Linux deps)

Platforms

OS Support
Windows Native Tauri / WebView2
Linux X11 Native GTK + WebKitGTK
Linux Wayland Native Wayland with automatic WebKit workarounds (KDE, GNOME, NVIDIA)

Session detection and GDK/WebKit env setup run in src-tauri/src/linux_display.rs before GTK starts (also available via scripts/rdclient-launcher.sh for packaged installs).

TLS (HTTP / self-signed / Let's Encrypt)

RdClient targets self-hosted operator panels. By default it accepts:

  • http:// panel URLs (no TLS)
  • https:// with self-signed BetterDesk installer certs
  • https:// with Let's Encrypt or commercial CAs (including incomplete intermediate chains on LAN)
Platform Mechanism
Linux Patched WebKitGTK TLSErrorsPolicy::Ignore on each WebContext (vendor/wry)
Windows WebView2 --ignore-certificate-errors

Strict validation (system trust store only):

BETTERDESK_TLS_STRICT=1 npm run dev

Use strict mode only when the panel serves a complete, publicly trusted chain and you do not need LAN/self-signed access.

Linux troubleshooting (Gdk error 71 / Wayland)

If the window fails to open on Wayland with:

Gdk-Message: Error 71 (Protocol error) dispatching to Wayland display.

the app already applies common fixes automatically. You can override:

Variable Effect
BETTERDESK_UI_BACKEND=x11 Force XWayland / X11 (GDK_BACKEND=x11)
BETTERDESK_UI_BACKEND=wayland Force native Wayland
BETTERDESK_WEBKIT_DISABLE_DMABUF=1 Set WEBKIT_DISABLE_DMABUF_RENDERER=1 (disables GPU compositing — use if blank window / flicker)
BETTERDESK_WEBKIT_NO_MEDIA_ACCEL=1 Skip GStreamer VA-API hints for WebKit media decode
BETTERDESK_WEBKIT_NO_WORKAROUND=1 Skip all automatic WebKit/GDK tweaks
BETTERDESK_WEBKIT_NO_COMPOSITING=1 Set WEBKIT_DISABLE_COMPOSITING_MODE=1 (last resort)

NVIDIA + Wayland: the binary sets __NV_DISABLE_EXPLICIT_SYNC=1 when /proc/driver/nvidia/version exists and keeps DMA-BUF enabled for GPU compositing. NVIDIA + X11: DMA-BUF is disabled automatically (blank-window workaround).

GPU / codecs: Wayland keeps WebKit DMA-BUF/GPU compositing enabled by default. Vendor-specific VA-API drivers are auto-selected (Intel iHD, AMD radeonsi, NVIDIA when nvidia-vaapi-driver is installed). GStreamer ranks hardware decoders (vaav1dec, vah264dec, …) above software. WebView2 on Windows enables GPU rasterization, AV1/HEVC HW decode, and WebCodecs.

Linux packages (recommended for AV1 / smooth remote):

GPU Packages (Fedora example)
Intel libva-intel-media-driver, gstreamer1-vaapi, gstreamer1-plugins-bad-free
AMD mesa-va-drivers, gstreamer1-vaapi, gstreamer1-plugins-bad-free
NVIDIA nvidia-vaapi-driver (optional VA-API), gstreamer1-plugins-bad-free

Verify VA-API: vainfo (should list AV1/H264/VP9 profiles). WebKitGTK 2.44+ and GStreamer 1.24+ are required for WebCodecs + DMA-BUF zero-copy.

If the window is blank or flickers, set BETTERDESK_WEBKIT_DISABLE_DMABUF=1.

Examples:

# Force X11 session (works on XWayland)
BETTERDESK_UI_BACKEND=x11 npm run dev

# Wayland with extra-safe WebKit flags
BETTERDESK_WEBKIT_DISABLE_DMABUF=1 npm run dev

Quick start

cd rdclient-desktop
npm install
npm run dev

Clean rebuild (no Cargo cache)

If Connect still does nothing after pulling changes, force a full rebuild:

cd rdclient-desktop
./scripts/rebuild-clean.sh

Production bundle instead of dev:

./scripts/rebuild-clean.sh build

Important: the dashboard HTML/JS is loaded from your panel URL (/remote). Updating only the desktop binary is not enough for UI tweaks — run Settings → Updates on the panel (or deploy web-nodejs) so /js/remote-dashboard.js is current. The desktop shell also injects a Connect bridge, so Connect works even before the panel JS update once you run a freshly built binary.

  1. On first launch, enter your panel base URL (e.g. https://desk.example.com) or pick a server from LAN discovery.
  2. Sign in at /remote/login when prompted (same as the web RdClient).
  3. Use Connect on a device — the desktop opens a new window instead of a browser tab.
  4. Open Settings (gear icon in the dashboard header) to change URL, TLS mode, language, sign out, or Reset client (clears config, cookies, and saved passwords).

Environment & embedded URL

Source Purpose
BETTERDESK_SERVER_URL Auto-configure panel URL before setup UI
betterdesk-rdclient.json next to the binary Installer-embedded { "server_url": "https://…" } from Generator
UDP / mDNS LAN discovery Setup UI lists panels on the local network

Password storage

  • Operator login (“Remember me”): RdClientSecureStore in IndexedDB (AES-GCM).
  • Device password (“Remember device password”): same vault, per deviceId (peer:{id} keys). Passwords never leave the device.
  • Reset client: clears config.json, WebView cookies/storage, and the vault.

LAN discovery

The panel publishes itself via UDP (port 21119, always on) and optionally mDNS _betterdesk._tcp when bonjour-service is installed and PANEL_MDNS is not off.

Build

npm run build

Installers/binaries are under src-tauri/target/release/bundle/.

How it works

Piece Role
src/setup.html First-run: LAN discovery list + manual panel URL
src/settings.html Local settings: URL, TLS, language, sign out, reset
src-tauri/src/lib.rs Tauri commands: probe, discover, settings, sign out, reset, sessions
src-tauri/src/config.rs Persists extended config + embedded/env URL helpers
src-tauri/src/server_probe.rs Validates panel via /api/bd/server-info
src-tauri/src/discovery.rs UDP LAN browse (BetterDesk announce protocol)
src-tauri/src/linux_display.rs Linux X11/Wayland session + WebKitGTK workarounds
src-tauri/src/tls_policy.rs Windows WebView2 + strict-mode env
scripts/rdclient-launcher.sh Optional wrapper for release binaries
vendor/wry/ Linux WebKit TLS policy patch (see vendor/README.md)
web-nodejs/public/js/remote-dashboard.js Detects window.__TAURI__ and calls open_session

Config file: config.json in the OS app config directory (com.betterdesk.rdclient).

Dependency note (brotli / alloc-no-stdlib)

Cargo.lock pins a git patch for alloc-no-stdlib so brotli (via Tauri) compiles with a single allocator version. If a fresh cargo update reintroduces alloc-no-stdlib 2.x and the build fails, run once from src-tauri/:

cargo update -p alloc-no-stdlib@2.0.4 --precise 3.0.0

Verify matrix (manual)

Platform Check
Linux Wayland Setup discovery, login, VP9/H.264 session (no AV1 loop), settings reset
Linux X11 Same as Wayland; test BETTERDESK_UI_BACKEND=x11 if needed
Windows x64 WebView2 present, Connect, remember passwords, MSI/portable from Generator
Fedora deb/rpm Installed bundle from Generator when build host has toolchain

Roadmap (not in this release)

  • Operator JWT + OS keychain login (POST /api/bd/operator/login)
  • WebSocket relay Bearer auth for long-lived desktop sessions
  • Native Rust video decoder (if WebCodecs insufficient on Linux)

License

AGPL-3.0 (same as BetterDesk on dev).