Compare commits

...

5 Commits

Author SHA1 Message Date
xuwenwei 41f39232c2 Rename Win resources: RustDesk -> SoonDesk
Sync the Windows-side branding with the macOS changes from 7edd248.

Changes:
- flutter/windows/runner/Runner.rc: FileDescription, ProductName
- flutter/windows/runner/main.cpp: app_name L"RustDesk" -> L"SoonDesk"
- flutter/windows/CMakeLists.txt: project name + BINARY_NAME

Note: librustdesk.dll name on the Rust side is unchanged — it's the
library crate name (libs/hbb_common/Cargo.toml defines it) and changing
it would require touching the dylib name in build scripts. The SoonDesk
.exe loads librustdesk.dll as before; only the user-visible strings
and the exe name change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 13:56:36 +08:00
xuwenwei 53ba2d753e Hide 'powered by RustDesk' link on login page
loadPowered() in flutter/lib/common.dart now always returns SizedBox.shrink()
for the SoonDesk fork. The link is misleading for a non-official build
and clutters the login page.

Upstream behavior (controlled by the 'hide-powered-by-me' builtin option)
is preserved in commented-out form for reference.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 13:48:03 +08:00
xuwenwei 7edd24854f Rename app from RustDesk to SoonDesk
Changes:
- libs/hbb_common/src/config.rs: APP_NAME = 'SoonDesk' (single source of truth)
- flutter/lib/desktop/widgets/tabbar_widget.dart: hard-coded tab title
- flutter/macos/Runner/Configs/AppInfo.xcconfig: PRODUCT_NAME, BUNDLE_ID
- flutter/macos/Runner.xcodeproj/project.pbxproj: hard-coded BUNDLE_ID override
- flutter/lib/web/bridge.dart: comment about why isCustomClient comparison unchanged

This single APP_NAME change drives:
- Window title (src/ui.rs:87 frame.set_title(&crate::get_app_name()))
- macOS app bundle display name (CFBundleName via $(PRODUCT_NAME))
- Linux .desktop file name
- Config / log directory paths (~/Library/Logs/SoonDesk/)
- Lang translation strings: src/lang.rs auto-replaces 'RustDesk' in all
  translations with APP_NAME when is_rustdesk() returns false (since
  APP_NAME is no longer 'RustDesk').

Protocol-level 'RustDesk' references are preserved (PunchHoleRequest
fields, etc.) so we still interop with upstream RustDesk servers and
clients.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 12:22:28 +08:00
xuwenwei f32373643e Default ON: enable-keyboard, enable-clipboard, enable-file-transfer
Per user feedback: these 3 features are core remote-support functionality
(typing, copying, sending files). 6d587a8 set them to N to save bandwidth
on the 5 Mbps self-hosted hbbs (114.55.133.123), but the user wants
them on by default. Users can still flip them off per-session.

Still OFF by default (kept from 6d587a8):
- enable-audio
- enable-tunnel
- enable-record-session
- enable-camera

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 00:16:50 +08:00
xuwenwei 6d587a840e Default-off 6 options (file-transfer, clipboard, keyboard, tunnel, record-session, camera) + force-on 2 NAT punch options
For 4 users on 5 Mbps server (114.55.133.123) where file transfers were saturating bandwidth:

Turn OFF by default (users can still flip on per-session):
- enable-file-transfer: THE KILLER (1 GB upload = 2 GB server bandwidth)
- enable-clipboard: 50 kbps + privacy
- enable-keyboard: only needed for typing-on-remote
- enable-tunnel: prevents using server as jump host
- enable-record-session: only when explicitly recording
- enable-camera: 500 kbps; rarely used for support
- enable-audio: (already in c94a72a)

Force ON (overrides RustDesk's conservative default for self-hosted servers):
- enable-udp-punch, enable-ipv6-punch: src/common.rs:1107 turns these off
  when rendezvous server is non-public. That's a safety measure meant for
  untrusted public servers, but our self-hosted server is fully trusted.
  Force-enabling boosts P2P success rate → less relay (21117) traffic →
  less server bandwidth.
2026-06-09 00:31:42 +08:00
10 changed files with 87 additions and 36 deletions
+26 -21
View File
@@ -3690,27 +3690,32 @@ Color? disabledTextColor(BuildContext context, bool enabled) {
} }
Widget loadPowered(BuildContext context) { Widget loadPowered(BuildContext context) {
if (bind.mainGetBuildinOption(key: "hide-powered-by-me") == 'Y') { // Custom fork (SoonDesk): never show the "powered by RustDesk" link.
return SizedBox.shrink(); // For non-official builds this is misleading (we're not "powered by"
} // upstream RustDesk), and clutters the login page.
return MouseRegion( return SizedBox.shrink();
cursor: SystemMouseCursors.click, // (Upstream behavior kept below for reference.)
child: GestureDetector( // if (bind.mainGetBuildinOption(key: "hide-powered-by-me") == 'Y') {
onTap: () { // return SizedBox.shrink();
launchUrl(Uri.parse('https://rustdesk.com')); // }
}, // return MouseRegion(
child: Opacity( // cursor: SystemMouseCursors.click,
opacity: 0.5, // child: GestureDetector(
child: Text( // onTap: () {
translate("powered_by_me"), // launchUrl(Uri.parse('https://rustdesk.com'));
overflow: TextOverflow.clip, // },
style: Theme.of(context) // child: Opacity(
.textTheme // opacity: 0.5,
.bodySmall // child: Text(
?.copyWith(fontSize: 9, decoration: TextDecoration.underline), // translate("powered_by_me"),
)), // overflow: TextOverflow.clip,
), // style: Theme.of(context)
).marginOnly(top: 6); // .textTheme
// .bodySmall
// ?.copyWith(fontSize: 9, decoration: TextDecoration.underline),
// )),
// ),
// ).marginOnly(top: 6);
} }
// max 300 x 60 // max 300 x 60
@@ -641,7 +641,7 @@ class _DesktopTabState extends State<DesktopTab>
Offstage( Offstage(
offstage: !showTitle, offstage: !showTitle,
child: const Text( child: const Text(
"RustDesk", "SoonDesk",
style: TextStyle(fontSize: 13), style: TextStyle(fontSize: 13),
).marginOnly(left: 2)) ).marginOnly(left: 2))
]).marginOnly( ]).marginOnly(
+6
View File
@@ -1611,6 +1611,12 @@ class RustdeskImpl {
// is_custom_client() checks if app name is not "RustDesk" // is_custom_client() checks if app name is not "RustDesk"
return mainGetAppNameSync(hint: hint) != "RustDesk"; return mainGetAppNameSync(hint: hint) != "RustDesk";
} }
// NOTE: We don't change the comparison string here. The upstream
// `is_custom_client` semantics are: "true when this build is NOT the
// official RustDesk build." For our SoonDesk fork, APP_NAME is
// "SoonDesk" (set in libs/hbb_common/src/config.rs), which still
// satisfies != "RustDesk" → isCustomClient returns true. So this
// check is correct as-is for the SoonDesk fork.
bool isDisableSettings({dynamic hint}) { bool isDisableSettings({dynamic hint}) {
// Checks HARD_SETTINGS["disable-settings"] == "Y" // Checks HARD_SETTINGS["disable-settings"] == "Y"
@@ -455,7 +455,7 @@
../../target/profile, ../../target/profile,
); );
MACOSX_DEPLOYMENT_TARGET = 10.15; MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PRODUCT_BUNDLE_IDENTIFIER = com.cardsoon.soondesk;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0; SWIFT_VERSION = 5.0;
@@ -600,7 +600,7 @@
../../target/debug, ../../target/debug,
); );
MACOSX_DEPLOYMENT_TARGET = 10.15; MACOSX_DEPLOYMENT_TARGET = 10.15;
PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PRODUCT_BUNDLE_IDENTIFIER = com.cardsoon.soondesk;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
"SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h;
@@ -637,7 +637,7 @@
__cgpreloginapp, __cgpreloginapp,
/dev/null, /dev/null,
); );
PRODUCT_BUNDLE_IDENTIFIER = com.carriez.rustdesk; PRODUCT_BUNDLE_IDENTIFIER = com.cardsoon.soondesk;
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
"SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h; "SWIFT_OBJC_BRIDGING_HEADER[arch=*]" = Runner/bridge_generated.h;
@@ -5,10 +5,10 @@
// 'flutter create' template. // 'flutter create' template.
// The application's name. By default this is also the title of the Flutter window. // The application's name. By default this is also the title of the Flutter window.
PRODUCT_NAME = RustDesk PRODUCT_NAME = SoonDesk
// The application's bundle identifier // The application's bundle identifier
PRODUCT_BUNDLE_IDENTIFIER = com.carriez.flutterHbb PRODUCT_BUNDLE_IDENTIFIER = com.cardsoon.soondesk
// The copyright displayed in application information // The copyright displayed in application information
PRODUCT_COPYRIGHT = Copyright © 2025 Purslane Ltd. All rights reserved. PRODUCT_COPYRIGHT = Copyright © 2026 Cardsoon. All rights reserved.
+2 -2
View File
@@ -1,10 +1,10 @@
# Project-level configuration. # Project-level configuration.
cmake_minimum_required(VERSION 3.14) cmake_minimum_required(VERSION 3.14)
project(rustdesk LANGUAGES CXX) project(soondesk LANGUAGES CXX)
# The name of the executable created for the application. Change this to change # The name of the executable created for the application. Change this to change
# the on-disk name of your application. # the on-disk name of your application.
set(BINARY_NAME "rustdesk") set(BINARY_NAME "soondesk")
# Explicitly opt into modern CMake behaviors to avoid warnings with recent # Explicitly opt into modern CMake behaviors to avoid warnings with recent
# versions of CMake. # versions of CMake.
+2 -2
View File
@@ -90,12 +90,12 @@ BEGIN
BLOCK "040904e4" BLOCK "040904e4"
BEGIN BEGIN
VALUE "CompanyName", "Purslane Ltd" "\0" VALUE "CompanyName", "Purslane Ltd" "\0"
VALUE "FileDescription", "RustDesk Remote Desktop" "\0" VALUE "FileDescription", "SoonDesk Remote Desktop" "\0"
VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "FileVersion", VERSION_AS_STRING "\0"
VALUE "InternalName", "rustdesk" "\0" VALUE "InternalName", "rustdesk" "\0"
VALUE "LegalCopyright", "Copyright © 2025 Purslane Ltd. All rights reserved." "\0" VALUE "LegalCopyright", "Copyright © 2025 Purslane Ltd. All rights reserved." "\0"
VALUE "OriginalFilename", "rustdesk.exe" "\0" VALUE "OriginalFilename", "rustdesk.exe" "\0"
VALUE "ProductName", "RustDesk" "\0" VALUE "ProductName", "SoonDesk" "\0"
VALUE "ProductVersion", VERSION_AS_STRING "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0"
END END
END END
+1 -1
View File
@@ -63,7 +63,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
std::vector<std::string> rust_args(c_args, c_args + args_len); std::vector<std::string> rust_args(c_args, c_args + args_len);
free_c_args(c_args, args_len); free_c_args(c_args, args_len);
std::wstring app_name = L"RustDesk"; std::wstring app_name = L"SoonDesk";
FUNC_RUSTDESK_GET_APP_NAME get_rustdesk_app_name = (FUNC_RUSTDESK_GET_APP_NAME)GetProcAddress(hInstance, "get_rustdesk_app_name"); FUNC_RUSTDESK_GET_APP_NAME get_rustdesk_app_name = (FUNC_RUSTDESK_GET_APP_NAME)GetProcAddress(hInstance, "get_rustdesk_app_name");
if (get_rustdesk_app_name) { if (get_rustdesk_app_name) {
wchar_t app_name_buffer[512] = {0}; wchar_t app_name_buffer[512] = {0};
+11 -1
View File
@@ -69,7 +69,17 @@ lazy_static::lazy_static! {
static ref ONLINE: Mutex<HashMap<String, i64>> = Default::default(); static ref ONLINE: Mutex<HashMap<String, i64>> = Default::default();
pub static ref PROD_RENDEZVOUS_SERVER: RwLock<String> = RwLock::new("".to_owned()); pub static ref PROD_RENDEZVOUS_SERVER: RwLock<String> = RwLock::new("".to_owned());
pub static ref EXE_RENDEZVOUS_SERVER: RwLock<String> = Default::default(); pub static ref EXE_RENDEZVOUS_SERVER: RwLock<String> = Default::default();
pub static ref APP_NAME: RwLock<String> = RwLock::new("RustDesk".to_owned()); // Custom fork: rename the app from "RustDesk" to "SoonDesk".
// This single constant drives:
// - Window title and menu bar text
// - macOS app bundle display name (set separately in Info.plist)
// - Linux .desktop file name
// - Config / log directory names
// - All Rust-side references to "RustDesk"
// is_rustdesk() at src/common.rs:1009 still compares against "RustDesk",
// so it will now return false for this fork. Update there too if that
// helper is used in any policy check.
pub static ref APP_NAME: RwLock<String> = RwLock::new("SoonDesk".to_owned());
static ref KEY_PAIR: Mutex<Option<KeyPair>> = Default::default(); static ref KEY_PAIR: Mutex<Option<KeyPair>> = Default::default();
static ref USER_DEFAULT_CONFIG: RwLock<(UserDefaultConfig, Instant)> = RwLock::new((UserDefaultConfig::load(), Instant::now())); static ref USER_DEFAULT_CONFIG: RwLock<(UserDefaultConfig, Instant)> = RwLock::new((UserDefaultConfig::load(), Instant::now()));
pub static ref NEW_STORED_PEER_CONFIG: Mutex<HashSet<String>> = Default::default(); pub static ref NEW_STORED_PEER_CONFIG: Mutex<HashSet<String>> = Default::default();
+32 -2
View File
@@ -2102,15 +2102,45 @@ pub fn load_custom_client() {
read_custom_client(&data.trim()); read_custom_client(&data.trim());
} }
// Custom fork: hardcode enable-audio = N as the default. User can still flip it on in Settings. // Custom fork: hardcode bandwidth-heavy / sensitive defaults to off.
// Reason: RustDesk's official custom.txt path requires ed25519-signed base64 (see // Reason: RustDesk's official custom.txt path requires ed25519-signed base64 (see
// read_custom_client at line 2191 — decode64 + sign::verify with key // read_custom_client at line 2191 — decode64 + sign::verify with key
// "5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM="), which we can't produce without the // "5Qbwsde3unUcJBtrx9ZkvUmwFNoExHzpryHuPUdqlWM="), which we can't produce without the
// official signing key. So we bypass custom.txt and inject directly into DEFAULT_SETTINGS. // official signing key. So we bypass custom.txt and inject directly into DEFAULT_SETTINGS.
// entry().or_insert() preserves the priority chain: OVERWRITE_SETTINGS → CONFIG2 → DEFAULT_SETTINGS. // entry().or_insert() preserves the priority chain: OVERWRITE_SETTINGS → CONFIG2 → DEFAULT_SETTINGS,
// so users can still override any of these in their own RustDesk2.toml.
//
// Why each one is off (user has 4 users on 5 Mbps server, file transfers were saturating it):
// enable-audio — not needed for 4-user remote support; saves 64 kbps/session
// enable-tunnel — TCP tunneling = users abusing server as a jump host
// enable-record-session — only needed if explicitly recording
// enable-camera — 500 kbps; rarely used for support
//
// Note: enable-keyboard, enable-clipboard, enable-file-transfer were
// originally set to N here, but the user requested they default to ON
// (these are core remote-support features: typing, copying, sending
// files to/from the remote machine). The user can still flip them off
// per-session via the Settings UI.
{ {
let mut defaults = config::DEFAULT_SETTINGS.write().unwrap(); let mut defaults = config::DEFAULT_SETTINGS.write().unwrap();
defaults.entry("enable-audio".to_string()).or_insert("N".to_string()); defaults.entry("enable-audio".to_string()).or_insert("N".to_string());
defaults.entry("enable-tunnel".to_string()).or_insert("N".to_string());
defaults.entry("enable-record-session".to_string()).or_insert("N".to_string());
defaults.entry("enable-camera".to_string()).or_insert("N".to_string());
}
// Force-enable UDP and IPv6 NAT punch for the self-hosted server scenario.
// Background: get_local_option() at src/common.rs:1107 turns off UDP/IPv6 punch
// when the rendezvous server is non-public (i.e. self-hosted). That conservativeness
// is meant to protect users from untrusted public servers, but for OUR self-hosted
// server (114.55.133.123, fully controlled by the user), it unnecessarily
// degrades P2P success rate → more relay traffic → more 21117 bandwidth.
// Force Y here so P2P success rate is high; relay (21117) only kicks in when
// P2P truly fails.
{
let mut locals = config::OVERWRITE_LOCAL_SETTINGS.write().unwrap();
locals.entry("enable-udp-punch".to_string()).or_insert("Y".to_string());
locals.entry("enable-ipv6-punch".to_string()).or_insert("Y".to_string());
} }
} }