[ui] remove TURN service toggle and simplify relay settings
@@ -319,10 +319,7 @@ int ConfigCenter::SetTurnMode(TURN_MODE mode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ConfigCenter::SetTurn(bool enable_turn, bool force_relay) {
|
||||
if (!enable_turn) {
|
||||
return SetTurnMode(TURN_MODE::DISABLED);
|
||||
}
|
||||
int ConfigCenter::SetForceRelay(bool force_relay) {
|
||||
if (!force_relay) {
|
||||
return SetTurnMode(TURN_MODE::AUTO_UDP_TCP);
|
||||
}
|
||||
@@ -479,10 +476,6 @@ ConfigCenter::TURN_MODE ConfigCenter::GetTurnMode() const {
|
||||
return turn_mode_;
|
||||
}
|
||||
|
||||
bool ConfigCenter::IsEnableTurn() const {
|
||||
return turn_mode_ != TURN_MODE::DISABLED;
|
||||
}
|
||||
|
||||
bool ConfigCenter::IsForceRelay() const {
|
||||
return turn_mode_ == TURN_MODE::FORCE_UDP || turn_mode_ == TURN_MODE::FORCE_TCP;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class ConfigCenter {
|
||||
int SetScreenCaptureMethod(ScreenCaptureMethod method);
|
||||
int SetVideoEncodeFormat(VIDEO_ENCODE_FORMAT video_encode_format);
|
||||
int SetTurnMode(TURN_MODE turn_mode);
|
||||
int SetTurn(bool enable_turn, bool force_relay);
|
||||
int SetForceRelay(bool force_relay);
|
||||
int SetServerHost(const std::string& signal_server_host);
|
||||
int SetServerPort(int signal_server_port);
|
||||
int SetServerEndpoint(const std::string& address, int port);
|
||||
@@ -63,7 +63,6 @@ class ConfigCenter {
|
||||
ScreenCaptureMethod GetScreenCaptureMethod() const;
|
||||
VIDEO_ENCODE_FORMAT GetVideoEncodeFormat() const;
|
||||
TURN_MODE GetTurnMode() const;
|
||||
bool IsEnableTurn() const;
|
||||
bool IsForceRelay() const;
|
||||
bool IsEnableSrtp() const;
|
||||
std::string GetSignalServerHost() const;
|
||||
|
||||
@@ -1488,7 +1488,6 @@ void GuiApplication::ResetSettingsUi(bool gallery_window) {
|
||||
auto& main = ui_->Window(gallery_window);
|
||||
main->set_language_index(language_button_value_);
|
||||
main->set_codec_index(video_encode_format_button_value_);
|
||||
main->set_turn_enabled(enable_turn_);
|
||||
main->set_ip_direct_enabled_draft(config_center_->IsIpDirectEnabled());
|
||||
main->set_settings_save_error("");
|
||||
main->set_force_relay_enabled(config_center_->IsForceRelay());
|
||||
@@ -4559,7 +4558,6 @@ bool GuiApplication::SaveSettingsFromUi(bool gallery_window) {
|
||||
language_button_value_ =
|
||||
localization::detail::ClampLanguageIndex(main->get_language_index());
|
||||
video_encode_format_button_value_ = std::clamp(main->get_codec_index(), 0, 1);
|
||||
enable_turn_ = main->get_turn_enabled();
|
||||
enable_self_hosted_ = main->get_self_hosted_enabled();
|
||||
#if !defined(__OHOS__)
|
||||
enable_autostart_ = main->get_autostart_enabled();
|
||||
@@ -4575,7 +4573,7 @@ bool GuiApplication::SaveSettingsFromUi(bool gallery_window) {
|
||||
config_center_->SetVideoEncodeFormat(
|
||||
static_cast<ConfigCenter::VIDEO_ENCODE_FORMAT>(
|
||||
video_encode_format_button_value_));
|
||||
config_center_->SetTurn(enable_turn_, main->get_force_relay_enabled());
|
||||
config_center_->SetForceRelay(main->get_force_relay_enabled());
|
||||
main->set_force_relay_enabled(config_center_->IsForceRelay());
|
||||
#if !defined(__OHOS__)
|
||||
config_center_->SetAutostart(enable_autostart_);
|
||||
@@ -4641,7 +4639,6 @@ void GuiApplication::ApplySettingsFromConfig(bool reconnect) {
|
||||
localization_language_index_ = localization::detail::ClampLanguageIndex(language_button_value_);
|
||||
localization_language_ = config_center_->GetLanguage();
|
||||
video_encode_format_button_value_ = static_cast<int>(config_center_->GetVideoEncodeFormat());
|
||||
enable_turn_ = config_center_->IsEnableTurn();
|
||||
enable_self_hosted_ = config_center_->IsSelfHosted();
|
||||
enable_autostart_ = config_center_->IsEnableAutostart();
|
||||
enable_daemon_ = config_center_->IsEnableDaemon();
|
||||
@@ -4655,7 +4652,6 @@ void GuiApplication::ApplySettingsFromConfig(bool reconnect) {
|
||||
std::snprintf(signal_server_port_self_, sizeof(signal_server_port_self_), "%s", port_text.c_str());
|
||||
language_button_value_last_ = language_button_value_;
|
||||
video_encode_format_button_value_last_ = video_encode_format_button_value_;
|
||||
enable_turn_last_ = enable_turn_;
|
||||
enable_self_hosted_last_ = enable_self_hosted_;
|
||||
enable_autostart_last_ = enable_autostart_;
|
||||
enable_daemon_last_ = enable_daemon_;
|
||||
|
||||
@@ -237,8 +237,6 @@ struct TranslationRow {
|
||||
"Video Encode Format:", u8"Формат кодека видео:") \
|
||||
X(av1, u8"AV1", "AV1", "AV1") \
|
||||
X(h264, u8"H.264", "H.264", "H.264") \
|
||||
X(enable_turn, u8"启用中继服务:", \
|
||||
"Enable TURN Service:", u8"Включить TURN-сервис:") \
|
||||
X(force_relay, u8"强制中继连接:", "Force Relay:", u8"Только через реле:") \
|
||||
X(self_hosted_server_config, u8"自托管配置", "Self-Hosted Config", \
|
||||
u8"Конфигурация self-hosted") \
|
||||
|
||||
@@ -465,7 +465,6 @@ int SettingsManager::Load() {
|
||||
static_cast<int>(owner_.config_center_->GetLanguage()));
|
||||
owner_.video_encode_format_button_value_ =
|
||||
static_cast<int>(owner_.config_center_->GetVideoEncodeFormat());
|
||||
owner_.enable_turn_ = owner_.config_center_->IsEnableTurn();
|
||||
owner_.enable_self_hosted_ = owner_.config_center_->IsSelfHosted();
|
||||
owner_.enable_autostart_ = owner_.config_center_->IsEnableAutostart();
|
||||
owner_.enable_daemon_ = owner_.config_center_->IsEnableDaemon();
|
||||
@@ -484,7 +483,6 @@ int SettingsManager::Load() {
|
||||
owner_.language_button_value_last_ = owner_.language_button_value_;
|
||||
owner_.video_encode_format_button_value_last_ =
|
||||
owner_.video_encode_format_button_value_;
|
||||
owner_.enable_turn_last_ = owner_.enable_turn_;
|
||||
owner_.enable_self_hosted_last_ = owner_.enable_self_hosted_;
|
||||
owner_.enable_autostart_last_ = owner_.enable_autostart_;
|
||||
|
||||
|
||||
@@ -150,13 +150,11 @@ struct UserSettingsState {
|
||||
char connection_login_identity_[17] = "";
|
||||
int language_button_value_ = 0;
|
||||
int video_encode_format_button_value_ = 0;
|
||||
bool enable_turn_ = true;
|
||||
char signal_server_ip_[256] = "api.crossdesk.cn";
|
||||
char signal_server_port_[6] = "9099";
|
||||
bool enable_self_hosted_ = false;
|
||||
int language_button_value_last_ = 0;
|
||||
int video_encode_format_button_value_last_ = 0;
|
||||
bool enable_turn_last_ = true;
|
||||
bool enable_self_hosted_last_ = false;
|
||||
bool enable_autostart_ = false;
|
||||
bool enable_autostart_last_ = false;
|
||||
|
||||
@@ -72,7 +72,6 @@ export global UiStrings {
|
||||
in-out property <string> capture-method: "Capture method";
|
||||
in-out property <string> capture-method-auto: "Auto";
|
||||
in-out property <string> codec: "Video codec";
|
||||
in-out property <string> turn-relay: "TURN relay";
|
||||
in-out property <string> force-relay: "Force relay";
|
||||
in-out property <string> self-hosted: "Self-hosted server";
|
||||
in-out property <string> autostart: "Start with system";
|
||||
@@ -625,13 +624,9 @@ export component MainWindow inherits Window {
|
||||
in property <bool> capture-method-visible: false;
|
||||
in-out property <int> capture-method-index: 0;
|
||||
in-out property <int> codec-index: 0;
|
||||
in-out property <bool> turn-enabled: true;
|
||||
in-out property <bool> ip-direct-enabled-draft: true;
|
||||
in property <string> settings-save-error;
|
||||
in-out property <bool> force-relay-enabled: false;
|
||||
changed turn-enabled => {
|
||||
if !root.turn-enabled { root.force-relay-enabled = false; }
|
||||
}
|
||||
in-out property <bool> self-hosted-enabled: false;
|
||||
in-out property <bool> autostart-enabled: false;
|
||||
in property <bool> autostart-system-managed: false;
|
||||
@@ -2672,13 +2667,12 @@ export component MainWindow inherits Window {
|
||||
}
|
||||
}
|
||||
SettingsGroup {
|
||||
title: GalleryStrings.tr("网络连接", "Network", "Сеть"); rows: 4;
|
||||
title: GalleryStrings.tr("网络连接", "Network", "Сеть"); rows: 3;
|
||||
SettingsToggleRow {
|
||||
label: GalleryStrings.tr("启用 IP 直连", "Enable direct IP", "Прямое IP-подключение");
|
||||
checked <=> root.ip-direct-enabled-draft;
|
||||
}
|
||||
SettingsToggleRow { label: UiStrings.turn-relay; checked <=> root.turn-enabled; enabled: !root.settings-session-active; }
|
||||
SettingsToggleRow { label: UiStrings.force-relay; checked <=> root.force-relay-enabled; enabled: root.turn-enabled && !root.settings-session-active; }
|
||||
SettingsToggleRow { label: UiStrings.force-relay; checked <=> root.force-relay-enabled; enabled: !root.settings-session-active; }
|
||||
SettingsToggleRow {
|
||||
checked <=> root.self-hosted-enabled; enabled: !root.settings-session-active; divider: false;
|
||||
SettingsButton { x: 0px; y: 2px; width: parent.width - 60px; height: 32px; quiet: true; align-left: true; text: UiStrings.self-hosted; enabled: !root.settings-session-active; clicked => { root.self-host-settings-open = true; } }
|
||||
|
||||
@@ -93,7 +93,6 @@ inline int ApplyMainWindowStrings(
|
||||
strings.set_capture_method_auto(
|
||||
Text(localization::screen_capture_method_auto[language]));
|
||||
strings.set_codec(Text(localization::video_encode_format[language]));
|
||||
strings.set_turn_relay(Text(localization::enable_turn[language]));
|
||||
strings.set_force_relay(Text(localization::force_relay[language]));
|
||||
strings.set_self_hosted(
|
||||
Text(localization::self_hosted_server_config[language]));
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
## 对等连接失败
|
||||
|
||||
在 **☰ → 设置** 中勾选 **启用中继服务**,点击“确认”后重新连接。自托管用户还需检查 Coturn 是否正常运行,以及中继端口 TCP/UDP、媒体端口范围 UDP 是否放通。
|
||||
默认连接策略已允许 TURN 中继回退。可在 **☰ → 设置** 中开启 **强制中继连接**,保存后重新连接以排查直连问题。自托管用户还需检查 Coturn 是否正常运行,以及中继端口 TCP/UDP、媒体端口范围 UDP 是否放通。
|
||||
|
||||
公共服务的兼容性变更也会影响旧客户端;请核对 [Release 说明](https://github.com/kunkundi/crossdesk/releases),尽量让两端使用兼容的近期版本。
|
||||
|
||||
@@ -85,7 +85,7 @@ Windows 安装包和便携包内置了 Amyuni 的 `usbmmidd_v2` 虚拟显示器
|
||||
| --- | --- |
|
||||
| Server disconnected / TLS error | Network access, signaling endpoint, certificate dates, hostname, and system trust. See [self-hosting](SELF_HOSTING_EN.md). |
|
||||
| Remote device offline | Keep the host running, connect both sides to the same signaling server, and copy its current ID again. |
|
||||
| P2P connection failed | Enable TURN relay in Settings and reconnect. For self-hosting, check Coturn and relay/media firewall ports. Review [release compatibility notes](https://github.com/kunkundi/crossdesk/releases). |
|
||||
| P2P connection failed | The default connection policy already allows TURN relay fallback. Enable Force Relay in Settings, save, and reconnect to troubleshoot direct connections. For self-hosting, check Coturn and relay/media firewall ports. Review [release compatibility notes](https://github.com/kunkundi/crossdesk/releases). |
|
||||
| Black screen / no input on macOS | Grant Screen Recording and Accessibility, then reopen the app. A changed app path or signature may require fresh permission grants. |
|
||||
| No capture on Linux Wayland | Check the Wayland build option, host PipeWire 0.3, and desktop portal permission. Compare with an X11 session. See [Linux build instructions](BUILD_EN.md#linux). |
|
||||
| Linux host has no monitor or graphical session | Start CrossDesk normally to automatically discover and select your existing desktop, preserving its Dock and apps; no display number is needed. A bare Xvfb shows only CrossDesk on a black background; use an existing session or install Xfce and specify `--headless-session startxfce4`. See [Linux headless operation](HEADLESS_EN.md). |
|
||||
|
||||
@@ -95,7 +95,7 @@ sudo security add-trusted-cert -d -r trustRoot \
|
||||
|
||||
- **未连接服务器 / TLS 错误:** 先检查地址、信令端口、证书有效期、证书主机名及根证书信任。
|
||||
- **已连服务器但设备离线:** 确认两端连接同一服务、被控端仍在运行,并重新复制当前 ID。
|
||||
- **P2P 连接失败:** 检查“启用中继服务”、Coturn 状态、TURN 端口和媒体端口范围,并核对客户端与服务端版本兼容性。
|
||||
- **P2P 连接失败:** 默认已允许中继回退;可开启“强制中继连接”排查直连问题。检查 Coturn 状态、TURN 端口和媒体端口范围,并核对客户端与服务端版本兼容性。
|
||||
- **配置修改未生效:** 在配置目录重新执行 `sudo docker compose up -d`;单纯重启容器不会应用修改过的环境变量。
|
||||
|
||||
日志、备份和迁移操作请参考 [服务端维护说明](https://github.com/kunkundi/crossdesk-server)。
|
||||
|
||||
@@ -149,8 +149,7 @@ sudo apt install "./crossdesk-virtual-desktop-xfce-linux-amd64-<version>.deb"
|
||||
| 采集方式(Windows) | 自动 / DXGI / WGC / GDI;无显示器主机使用“自动”启用自动适配 |
|
||||
| 视频编码格式 | H.264 / AV1;H.264 自动优先使用硬件编解码,不可用或初始化失败时回退到软件;桌面端 AV1 使用软件编解码 |
|
||||
| 启用 IP 直连 | 默认开启;保存后即时启停 IP 直连。关闭会断开 IP 会话、停止监听并隐藏主窗口模式按钮,重启后保持 |
|
||||
| 启用中继服务 | 允许借助 TURN 中继建立连接;P2P 连接失败时先检查此项 |
|
||||
| 强制中继连接 | 启用中继服务后可勾选,让连接通过中继建立;关闭中继服务会同时关闭此项 |
|
||||
| 强制中继连接 | 关闭时自动选择连接方式,允许 P2P 和 TURN 中继回退;开启时仅通过中继连接 |
|
||||
| 保存远程画面预览 | 默认开启,保存远程画面预览;关闭后缩略图区域显示被控端平台,并清除已有预览,保留连接记录和密码 |
|
||||
| 被连接时开启隐私屏 | 设置本机被远程连接时是否自动启用隐私屏;会话中可从控制端工具栏切换 |
|
||||
| 自托管配置 | 填写服务器地址和信令服务端口,并勾选启用 |
|
||||
|
||||
@@ -149,8 +149,7 @@ Open **☰ → Settings** in the top-right corner, choose **General / DeskHub**,
|
||||
| Capture Method (Windows) | Auto / DXGI / WGC / GDI; choose Auto for automatic headless adaptation |
|
||||
| Video Encode Format | H.264 / AV1; H.264 automatically prefers hardware codecs, with software fallback when unavailable or initialization fails; desktop AV1 uses software codecs |
|
||||
| Enable direct IP | Enabled by default; saving starts or stops direct IP immediately. Disabling disconnects IP sessions, stops listeners, and hides the mode button; the choice persists across restarts |
|
||||
| Enable TURN Service | Allow relay-assisted connections; check this setting if P2P fails |
|
||||
| Force Relay | Require relay connections when TURN is enabled; turning TURN off also disables this option |
|
||||
| Force Relay | When off, automatically select a connection path with P2P and TURN relay fallback; when on, use relay connections only |
|
||||
| Save remote screen previews | On by default. When disabled, the thumbnail area shows the remote device’s platform and existing previews are cleared; connection records and passwords are preserved |
|
||||
| Privacy screen on connect | Automatically enable privacy when this computer is controlled remotely; the controller can toggle it from the session toolbar |
|
||||
| Self-Hosted Config | Set the server address and signaling port, then enable the checkbox |
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
## 来源 / Sources
|
||||
|
||||
- **2026-10-25** 删除“启用中继服务”开关后,从当前工作区组件重新生成 `desktop-settings-*` 和 `desktop-settings-network-*` 共 4 张中英文截图,展示可独立操作的“强制中继连接”。
|
||||
- **2026-10-25** 从 `ae6f81e8` 的实际 Slint 组件重新生成 16 张中英文截图:更新主窗口、常规设置、桌面墙设置、自托管及关于共 10 张,新增 IP 直连主界面、记住密码弹窗和网络设置共 6 张。使用 Slint 1.17.1、macOS arm64 和 2× 软件渲染。
|
||||
- 捕获程序在**工程外临时目录**中复用现有 [`slint_ui_smoke_test`](../../apps/desktop/tests/slint_ui_smoke_test.cpp) 的截图辅助函数,并注入演示界面状态;没有启动应用运行时、打开监听端口或建立远控会话。没有修改产品组件或工程内测试,临时源码、可执行程序与 PPM 均位于工程外。
|
||||
- 主窗口展示 ID / IP 模式切换、桌面墙入口和各自的近期设备;IP 模式展示地址编辑、六位密码和默认端口 52888,网络设置展示“启用 IP 直连”及关闭说明。IP 近期设备的 `LAN` 标记表示记录类型,不代表在线探测结果。
|
||||
@@ -13,7 +14,7 @@
|
||||
- 缩略图沿用既有公开页面截图:`fixtures/source.png` 来自 [CrossDesk Xmake 源码页](https://github.com/kunkundi/crossdesk/blob/ios-support/xmake.lua),`fixtures/website.png` 来自 [CrossDesk 官网](https://www.crossdesk.cn/),两者采集于 2026-09-07。它们只用于展示预览效果,不代表这些页面正在对应设备上运行,页面中的版本信息也不代表最新发布。
|
||||
- `web-client.png` 保留 **2026-09-25** 从 [Web 客户端](https://web.crossdesk.cn/) 采集的 1280 × 720 连接首页,页面版本为 `2026.09.24.2`,ID 与密码为空。本次未重新采集 Web 页面;桌面设备预览继续复用这张图片。
|
||||
|
||||
On **2026-10-25**, 16 images were rendered from the actual Slint components at `ae6f81e8`: ten refreshed images (main window, General settings, DeskHub settings, self-hosting, and About) and six additions (Direct IP mode, its password dialog, and Network settings), in Chinese and English. The capture-only program reused the existing helper functions in an external temporary directory, using Slint 1.17.1 on macOS arm64 at 2× scale. No product components or repository tests were changed, and no listeners or remote sessions were opened. IDs, IPs, passwords, device records, connection states, and update results are illustrative; `LAN` labels indicate record type, not an online check. The checked Remember password box is a demonstration choice. The other six desktop screenshots remain from 2026-10-19, public-page fixtures from 2026-09-07, and the Web image from 2026-09-25. Native mobile screenshots are not included.
|
||||
On **2026-10-25**, 16 images were rendered from the actual Slint components at `ae6f81e8`: ten refreshed images (main window, General settings, DeskHub settings, self-hosting, and About) and six additions (Direct IP mode, its password dialog, and Network settings), in Chinese and English. Later that day, the four General and Network settings images were refreshed from the working tree after removing Enable TURN Service, showing the independent Force Relay switch. The capture-only program reused the existing helper functions in an external temporary directory, using Slint 1.17.1 on macOS arm64 at 2× scale. Capture did not modify product components or repository tests, and no listeners or remote sessions were opened. IDs, IPs, passwords, device records, connection states, and update results are illustrative; `LAN` labels indicate record type, not an online check. The checked Remember password box is a demonstration choice. The other six desktop screenshots remain from 2026-10-19, public-page fixtures from 2026-09-07, and the Web image from 2026-09-25. Native mobile screenshots are not included.
|
||||
|
||||
## 文件 / Files
|
||||
|
||||
@@ -112,7 +113,6 @@ int main() {
|
||||
!RegisterFontAwesome(server->window())) return 2;
|
||||
window->set_local_id("123 456 789");
|
||||
window->set_local_password("Ab12Cd");
|
||||
window->set_turn_enabled(true);
|
||||
window->window().set_size(slint::LogicalSize({640.0f, 472.0f}));
|
||||
return RunCaptureMode(options, window, stream, server);
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 157 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 146 KiB |