# RustDesk Guide ## Project Layout ### Directory Structure * `src/` Rust app * `src/server/` audio / clipboard / input / video / network * `src/platform/` platform-specific code * `src/ui/` legacy Sciter UI (deprecated) * `flutter/` current UI * `libs/hbb_common/` config / proto / shared utils * `libs/scrap/` screen capture * `libs/enigo/` input control * `libs/clipboard/` clipboard * `libs/hbb_common/src/config.rs` all options ### Key Components - **Remote Desktop Protocol**: Custom protocol implemented in `src/rendezvous_mediator.rs` for communicating with rustdesk-server - **Screen Capture**: Platform-specific screen capture in `libs/scrap/` - **Input Handling**: Cross-platform input simulation in `libs/enigo/` - **Audio/Video Services**: Real-time audio/video streaming in `src/server/` - **File Transfer**: Secure file transfer implementation in `libs/hbb_common/` ### UI Architecture - **Legacy UI**: Sciter-based (deprecated) - files in `src/ui/` - **Modern UI**: Flutter-based - files in `flutter/` - Desktop: `flutter/lib/desktop/` - Mobile: `flutter/lib/mobile/` - Shared: `flutter/lib/common/` and `flutter/lib/models/` ## Rust Rules * Avoid `unwrap()` / `expect()` in production code. * Exceptions: * tests; * lock acquisition where failure means poisoning, not normal control flow. * Otherwise prefer `Result` + `?` or explicit handling. * Do not ignore errors silently. * Avoid unnecessary `.clone()`. * Prefer borrowing when practical. * Do not add dependencies unless needed. * Keep code simple and idiomatic. ## Tokio Rules * Assume a Tokio runtime already exists. * Never create nested runtimes. * Never call `Runtime::block_on()` inside Tokio / async code. * Do not hide runtime creation inside helpers or libraries. * Do not hold locks across `.await`. * Prefer `.await`, `tokio::spawn`, channels. * Use `spawn_blocking` or dedicated threads for blocking work. * Do not use `std::thread::sleep()` in async code. ## Editing Hygiene * Change only what is required. * Prefer the smallest valid diff. * Do not refactor unrelated code. * Do not make formatting-only changes. * Keep naming/style consistent with nearby code. ## Localization (`src/lang/*.rs`) Each file is a `HashMap`. Layout: * `template.rs` is the master list of every key. **Never edit it** as part of translation work. * `en.rs` holds only the keys whose English display text differs from the key itself. * Every other file (`de.rs`, `fr.rs`, …) carries the full key set; an untranslated entry has an empty value: `("key", "")`. ### Finding the English source for a key When filling an empty entry, determine the source English text with this rule: * If `key` exists in `en.rs` **with a non-empty value**, that value is the source text (look it up in `en.rs`). * Otherwise the **key string itself is the source text** (the key is already plain English). Then translate that source into the file's target language (infer the language from the file's existing non-empty entries / filename). ### Translation hygiene * Only fill empty values. Never change keys, and never touch existing non-empty translations. * Preserve placeholders (`{}`) and escape sequences (`\n`, `\"`) exactly as in the source. * Do not translate brand or technical tokens: `RustDesk`, `Socks5`, `TLS`, `UAC`, `Wayland`, `X11`, `TCP`, `UDP`, `2FA`, `RDP`, `D3D`, etc. * Copy URL values (e.g. `doc_*` keys) verbatim from `en.rs`.