727aced411
The xcap native path does JPEG-encode-in-Rust → base64 → IPC → atob → createImageBitmap → canvas.drawImage → canvas.captureStream → VP9 per frame, all CPU-bound and mostly on the main thread — at 1080p30 that lands well past one render quantum, producing visible frame-by-frame stutter. chromeMediaSource+getUserMedia hands the capture to Chromium's native desktop-capture backend and directly into the PeerConnection, so it's the same path the OS picker uses and has no per-frame JS cost. Reorders the capture attempts so chromeMediaSource is tried first; xcap stays around as a fallback for WebView2 versions that reject the legacy constraint. System audio still goes through WASAPI in both paths, since getUserMedia's chromeMediaSource audio constraint throws AbortError on Window captures — splitting the streams is what makes both work. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chat-app/desktop
Tauri v2 + React + Vite + Tailwind desktop client (macOS / Windows / Linux).
Prerequisites
- Node 22+, pnpm 9+
- Rust + Cargo (install via https://rustup.rs)
- Platform build deps:
- macOS: Xcode Command Line Tools
- Linux:
libwebkit2gtk-4.1-dev,build-essential,libssl-dev(Debian/Ubuntu) - Windows: Microsoft C++ Build Tools + WebView2
Dev
# from repo root
pnpm install
pnpm desktop:dev # tauri dev — launches Vite + native window
pnpm desktop:build # production bundle per platform
Layout
src/— React app (Vite bundles intodist/).src-tauri/— Rust backend.main.rswires Tauri plugins.vite.config.ts— port1420, HMR on1421, aliases to shared packages.
Secure Storage
Session tokens + user private keys live in Stronghold (tauri-plugin-stronghold).
Local message history lives in SQLite (tauri-plugin-sql), DB file encrypted at rest.