[docs] update README guides and desktop screenshots

This commit is contained in:
dijunkun committed 2026-11-11 22:24:56 +08:00
1 parent 6414f2317f
commit b15a63cc9d
32 files changed
+267 -60

No files matched your search

+30 -8
View File
@@ -118,8 +118,8 @@ sudo apt install "./crossdesk-virtual-desktop-xfce-linux-amd64-<version>.deb"
| 键盘 | 发送组合键;Windows 的 `Ctrl+Alt+Del` 依赖远端服务 |
| 鼠标 | 控制 / 释放远端鼠标 |
| 扬声器 | 播放声音 / 静音 |
| 文件夹 | 选择文件发送到远端,并查看传输进度 |
| 画面设置 | 在当前会话中调整画面质量、采集帧率与画面偏好 |
| 文件夹 | 打开双栏文件浏览窗口,浏览本机和远端目录,双向传输文件与文件夹 |
| 画面设置 | 在当前会话中调整画面质量、采集帧率、受支持的远端分辨率与画面偏好 |
| 网络状态 | 查看流量、丢包率、帧率、分辨率、直连 / 中继、加密状态,以及被控端编码器和控制端解码器 |
| 隐私屏 | 开启或关闭被控电脑的隐私屏;悬停查看当前状态与可用操作 |
| 全屏 | 进入 / 退出全屏 |
@@ -135,6 +135,16 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
桌面端普通会话、桌面墙和移动端(Android、iOS、鸿蒙)的网络状态均显示“被控端编码器”和“控制端解码器”,使用实际的视频编解码器名称,包括回退后的软件编解码器。名称保持单行,超出可用宽度时自动横向滚动,完整显示时保持静止。名称统一采用“实现名称 (编码格式)”,名称首字母大写、技术缩写保留全大写,例如 `VideoToolbox (H.264)`、`NVENC (H.264)`、`NVDEC (H.264)`、`SVT-AV1 (AV1)`、`Dav1d (AV1)` 和 `LibAOM (AV1)`;Media Foundation 额外标注 `HW`(硬件)或 `SW`(软件)。被控端需要支持编码器状态上报;旧版本或尚未获取到的信息显示“—”。
### 浏览目录与传输文件
点击会话工具栏中的文件夹按钮,同时查看本机和远端文件列表。可输入路径、返回上级目录、按名称筛选、选择多个文件或文件夹,再点击 **发送到远端** / **发送到本机**,也可在两栏之间拖放。目标目录需已存在,同名文件按冲突命名规则另存;远端目录浏览需要兼容的被控端。
底部任务列表显示传输状态和进度,支持取消未完成任务与清除已完成记录。图中的路径、文件名和完成状态均为演示数据。
<p align="center">
<img src="images/desktop-files-zh.png" width="960" alt="文件传输窗口:本机和远端文件列表、发送方向与任务状态;数据为演示" />
</p>
### 在会话中调整画面
连接成功后,点击工具栏中的 **画面设置**(滑杆图标),直接选择低 / 中 / 高画质、**30 / 60 fps**,以及帧率优先 / 画质优先 / 平衡。选项会发送给当前被控端,无需断开重连;实际画面效果取决于网络、设备与编码器能力。旧版被控端不支持时,菜单会提示并禁用选项。
@@ -142,9 +152,11 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
被控端为 Windows、macOS 或 Linux X11 时,还可在 **画面设置 → 分辨率** 中选择当前显示器支持的桌面分辨率。调整无需重连,最后一个控制端断开后会恢复连接期间首次调整前的显示模式。Linux 需要使用 X11 采集及支持 RandR 的显示服务器;Wayland、XWayland 和使用自定义缩放或平移的显示配置暂不支持。可选分辨率由显示器或虚拟显示服务器提供,仅提供一个模式的虚拟屏不会额外生成模式。
<p align="center">
<img src="images/desktop-stream-video-settings-zh.png" width="800" alt="当前远程会话的画面设置菜单:画面质量、采集帧率与画面偏好;背景为公开页面演示图" />
<img src="images/desktop-stream-video-settings-zh.png" width="800" alt="当前远程会话的画面设置菜单:分辨率、画面质量、采集帧率与画面偏好;背景为公开页面演示图" />
</p>
桌面和原生移动端会按远端设备及显示器记住已确认成功的分辨率。再次连接时,若该显示器仍支持保存的模式,会重新请求应用;被控端在最后一个控制端断开时恢复原显示模式的行为不变。
<a id="settings"></a>
## 客户端设置与更新
@@ -157,15 +169,15 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
| 设置 | 说明 |
| --- | --- |
| 语言 | 中文、English、Русский |
| 语言 | 默认跟随系统,也可手动选择简体中文、繁体中文、英语、俄语、日语、韩语、德语、法语、西班牙语或巴西葡萄牙语,见 [本地化说明](../localization/README.md) |
| 视频编码格式 | H.264 / AV1;H.264 自动优先使用硬件编解码,不可用或初始化失败时回退到软件;桌面端 AV1 使用软件编解码 |
| 启用 IP 直连 | 默认开启;保存后即时启停 IP 直连。关闭会断开 IP 会话、停止监听并隐藏主窗口模式按钮,重启后保持 |
| 强制中继连接 | 关闭时自动选择连接方式,允许 P2P 和 TURN 中继回退;开启时仅通过中继连接 |
| 保存远程画面预览 | 默认开启,保存远程画面预览;关闭后缩略图区域显示被控端平台,并清除已有预览,保留连接记录和密码 |
| 被连接时开启隐私屏 | 设置本机被远程连接时是否自动启用隐私屏;会话中可从控制端工具栏切换 |
| 自托管配置 | 点击“编辑”填写服务器地址和信令服务端口,使用右侧开关启用 |
| 开机自启 | Windows 安装版 Release:使用现有 ID、密码在登录前提供远控;用户登录后自动启动普通客户端并接管同一身份,恢复完整功能。Windows 便携版和 Debug 不支持此开关。其他桌面平台保存后设置登录桌面时自动启动 |
| 启用守护进程 | Windows / Linux 桌面模式保存后立即启用或停用异常退出后的自动重启,无需重启程序;正常退出或注销不会重新拉起。macOS 下次启动生效,无头控制台模式不启用内置守护 |
| 开机自启 | Windows 安装版 Release:使用现有 ID、密码在登录前提供远控;用户登录后 GUI 自动启动并接入后台服务,恢复完整功能。Windows 便携版和 Debug 不支持此开关。其他桌面平台保存后设置登录桌面时自动启动 |
| 启用守护进程 | Windows / macOS / Linux 桌面模式保存后立即启用或停用异常退出后的自动重启,无需重启程序;正常退出或注销不会重新拉起,无头控制台模式不启用内置守护 |
| 文件保存路径 | 选择接收文件的目录 |
网络连接分组中的 IP 直连开关独立于 ID 连接使用的中继设置:
@@ -195,7 +207,17 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
客户端启动后会在后台检查版本,发现新版本时自动弹出更新提示,可查看更新说明并前往下载页面。关闭提示后,本次运行中的后台检查不会再次弹窗,主窗口菜单入口仍会显示更新提示;重新启动客户端后,如仍有新版本则再次提示。打开 **☰ → 关于** 可查看版本;有新版本时,点击版本信息下方的 **更新日志** 可再次打开更新提示,也可点击 **检查更新** 手动检查。
<p align="center">
<img src="images/desktop-about-zh.png" width="720" alt="关于窗口与检查更新按钮,版本号和检查结果为演示数据" />
<img src="images/desktop-about-zh.png" width="720" alt="关于窗口与检查更新按钮,development 为演示版本,未执行在线版本检查" />
</p>
<a id="feedback"></a>
### 反馈与诊断日志
打开主窗口 **☰ → 反馈与建议**,点击 **前往 GitHub 反馈** 提交问题或建议;点击 **导出诊断日志** 可将 CrossDesk、MiniRTC 日志及基本版本信息保存为 ZIP 文件。导出成功后界面显示保存位置,可在问题中附上日志包,并说明两端系统、版本、连接方式及复现步骤。
<p align="center">
<img src="images/desktop-feedback-zh.png" width="720" alt="反馈与建议:GitHub 反馈入口和导出诊断日志按钮" />
</p>
<a id="ios"></a>
@@ -204,7 +226,7 @@ macOS 保留一个 CrossDesk Dock 应用图标,主窗口与远程控制窗口
仓库的 [`apps/ios`](../apps/ios/README.md) 提供原生控制端,与桌面端使用同一套 MiniRTC 协议。它可以控制远端电脑;当前不提供将 iPhone / iPad 作为被控桌面的功能。
1. 按 [iOS 开发说明](../apps/ios/README.md) 使用 Xcode 构建并签名,安装到 iOS 16+ 的真机。
1. 从 [App Store](https://apps.apple.com/app/id6828859211) 安装,具体系统要求以商店页面为准;也可按 [iOS 开发说明](../apps/ios/README.md) 使用 Xcode 构建并签名,当前源码目标为 iOS 16+。
2. 在首页输入对端 ID,点击连接并填写密码;成功连接后可从“最近连接”中重连。
3. 在设置中选择鼠标模式:**相对位置**像触控板一样移动光标,**绝对位置**将触摸位置直接映射到远端画面。
4. 点击悬浮图标展开菜单,可切换显示器、显示键盘、控制声音或发送文件。收到的文件位于应用的 `Documents/Received`,可通过传输状态旁的分享按钮导出。
+39 -14
View File
@@ -118,8 +118,8 @@ Switch devices using session tabs. Expand the control bar if it is collapsed, an
| Keyboard | Send shortcuts; Windows `Ctrl+Alt+Del` requires the remote service |
| Mouse | Enable / release remote mouse control |
| Speaker | Play / mute remote audio |
| Folder | Select a file to send and view transfer progress |
| Video settings | Adjust video quality, capture frame rate, and video preference during the current session |
| Folder | Open the dual-pane file browser and transfer files or folders between local and remote directories |
| Video settings | Adjust video quality, capture frame rate, supported remote display resolution, and video preference |
| Network statistics | Inspect traffic, packet loss, frame rate, resolution, direct / relay mode, encryption status, the remote encoder, and the local decoder |
| Privacy screen | Enable or disable the host's privacy screen; hover to see its status and available actions |
| Fullscreen | Enter / exit fullscreen |
@@ -135,6 +135,16 @@ On macOS, CrossDesk keeps one application icon in the Dock. The main and remote
Network statistics in both ordinary sessions and DeskHub show the video codecs actually in use, including software fallback. Names use “Implementation (Format)” with an initial capital and uppercase technical abbreviations, such as `VideoToolbox (H.264)`, `NVENC (H.264)`, `NVDEC (H.264)`, `SVT-AV1 (AV1)`, `Dav1d (AV1)`, and `LibAOM (AV1)`; Media Foundation also includes `HW` (hardware) or `SW` (software). The host must support encoder status reporting; older versions and information not yet available display “—”.
### Browse directories and transfer files
Open the folder button in the session toolbar to view local and remote file lists side by side. Enter a path, go to the parent directory, filter by name, select files or folders, then click **Send to remote** / **Send to local**, or drag between panes. The destination directory must exist; conflicting names are saved under an alternate name. Remote directory browsing requires a compatible host.
The task list shows transfer status and progress, with controls to cancel unfinished tasks and clear completed records. Paths, filenames, and completion states in the image are illustrative.
<p align="center">
<img src="images/desktop-files-en.png" width="960" alt="File transfer window with local and remote file lists, transfer direction, and task status; all data is illustrative" />
</p>
### Adjust video during a session
After connecting, open **Video settings** (the sliders icon) in the toolbar. Choose low / medium / high quality, **30 / 60 fps**, and frame-rate priority / quality priority / balanced adaptation. Changes are sent to the current host without reconnecting; actual results depend on the network, device, and encoder. For older hosts that do not support live video settings, the menu explains the limitation and disables the options.
@@ -142,9 +152,11 @@ After connecting, open **Video settings** (the sliders icon) in the toolbar. Cho
For Windows, macOS, and Linux X11 hosts, **Video settings → Resolution** also lists supported desktop resolutions for the selected monitor. Changes take effect without reconnecting; when the last controller disconnects, the display mode from before the first change is restored. Linux requires X11 capture and a RandR-capable display server. Wayland, XWayland, and custom scaling or panning configurations are not supported. Choices come from the monitor or virtual display server; no additional modes are created for virtual screens that expose only one mode.
<p align="center">
<img src="images/desktop-stream-video-settings-en.png" width="800" alt="Current session video menu with quality, capture frame rate, and video preference; the background is a public page used for demonstration" />
<img src="images/desktop-stream-video-settings-en.png" width="800" alt="Current session video menu with resolution, quality, capture frame rate, and video preference; the background is a public page used for demonstration" />
</p>
Desktop and native mobile controllers remember confirmed resolutions per remote device and display. On reconnection, a saved mode is requested again if still supported. The host still restores the original mode when the last controller disconnects.
<a id="settings"></a>
## Client settings and updates
@@ -157,7 +169,7 @@ Open **☰ → Settings** in the top-right corner, choose **General / DeskHub**,
| Setting | Purpose |
| --- | --- |
| Language | 中文, English, Русский |
| Language | Follow the system by default, or select Simplified / Traditional Chinese, English, Russian, Japanese, Korean, German, French, Spanish, or Brazilian Portuguese; see [localization](../localization/README.md) (Chinese) |
| 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 |
@@ -165,7 +177,8 @@ Open **☰ → Settings** in the top-right corner, choose **General / DeskHub**,
| 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 | Click Edit to set the server address and signaling port, then enable the switch on the right |
| Auto Start / Enable Daemon | Configure startup and process supervision; restart as indicated by the UI |
| Auto Start | Installed Windows Release builds use the same ID and password before and after sign-in, with the GUI attaching to the background service after login. Unavailable in portable and Debug Windows builds. Other desktop platforms start at desktop login |
| Enable Daemon | On Windows / macOS / Linux desktops, saving immediately enables or disables restart after an abnormal exit. Normal exit or logoff does not relaunch the app; headless console mode does not use the built-in daemon |
| File Save Path | Choose where received files are saved |
The direct IP switch in the Network group is independent of the relay settings used for ID connections:
@@ -195,7 +208,17 @@ Devices supporting preview subscriptions can pause video while their views are h
The client checks for updates in the background after launch and automatically opens the update dialog when a new version is found, showing release notes and a link to the download page. After you dismiss the dialog, background checks will not reopen it during the current run, while the main window menu keeps its update indicator. Restarting the client shows the dialog again if an update is still available. Open **☰ → About** to view the version. When an update is available, click **Release notes** below the new version to reopen the update dialog, or click **Check for updates** to check manually.
<p align="center">
<img src="images/desktop-about-en.png" width="720" alt="About dialog with the Check for updates button; version and check result are demonstration data" />
<img src="images/desktop-about-en.png" width="720" alt="About dialog with the Check for updates button; development is a demonstration version and no online check was performed" />
</p>
<a id="feedback"></a>
### Feedback and diagnostic logs
Open **☰ → Feedback & suggestions** in the main window. **Give feedback on GitHub** opens the issue page; **Export diagnostic logs** saves CrossDesk and MiniRTC logs with basic version information as a ZIP archive. After export, the panel shows the saved path. Attach the archive to a report with both systems, client versions, connection mode, and reproduction steps.
<p align="center">
<img src="images/desktop-feedback-en.png" width="720" alt="Feedback and suggestions with GitHub feedback and diagnostic log export buttons" />
</p>
<a id="ios"></a>
@@ -204,7 +227,7 @@ The client checks for updates in the background after launch and automatically o
[`apps/ios`](../apps/ios/README.md) contains a native controller using the same MiniRTC protocol as the desktop client. It controls remote computers; it does not expose an iPhone or iPad as a remotely controlled desktop.
1. Follow the [iOS guide](../apps/ios/README.md) to build and sign the app with Xcode, then install it on an iOS 16+ physical device.
1. Install from the [App Store](https://apps.apple.com/app/id6828859211), checking the listing for OS requirements. Alternatively, follow the [iOS guide](../apps/ios/README.md) to build and sign with Xcode; current source targets iOS 16+.
2. Enter a remote ID on the home screen, connect, and enter its password. Successful connections become available in the recent devices list.
3. Choose a mouse mode in Settings: **Relative Position** works like a trackpad; **Absolute Position** maps touches directly to the remote screen.
4. Tap the floating icon to expand the menu, then switch displays, open the keyboard, toggle audio, or send files. Received files are stored in `Documents/Received` and can be exported using the share button beside the transfer status.
@@ -249,7 +272,7 @@ These are development builds. Follow the [HarmonyOS build guide](../apps/harmony
The installer registers an on-demand service by default. CrossDesk tries to start it on launch. Unless unattended mode is enabled, the service exits when no local CrossDesk client is running. Portable builds offer service installation in the prompt or **Settings → Lock Screen Service**, with administrator privileges.
On Windows, **Auto Start** launches the client after the current user signs in. Installed release builds use a logon scheduled task with highest privileges, so subsequent logons need no UAC confirmation; portable and Debug builds use a normal per-user startup entry. Upgrading the installed build or launching the new version manually migrates a legacy startup entry pointing to that executable. Turning Auto Start off removes its registration. Remote access before sign-in requires the separate unattended mode below.
In installed Windows Release builds, **Auto Start** enables unattended hosting: `CrossDeskService` starts with the system, and a scheduled task starts the GUI after the enabling user signs in. The background service owns the device identity and remote connections; the GUI attaches through an authenticated local pipe. Turning the option off removes automatic startup and returns the service to on-demand startup. Opening the GUI manually still uses the background host. **Enable Daemon** controls GUI crash recovery. Portable and Debug builds do not offer Auto Start.
<a id="windows-service-development-update"></a>
@@ -273,26 +296,28 @@ Remote control may briefly disconnect while the service restarts. Reconnect and
### Remote access before Windows sign-in
The installed release supports a separate unattended host. Open an **administrator PowerShell** in the complete installation directory and enable it once:
Enable **Settings → Auto Start** and save to use the main window's device ID and password before and after sign-in. The same feature can be enabled from an **administrator PowerShell** in the complete installation directory. Close the ordinary client before first enabling it through the CLI, or use the running client's settings switch:
```powershell
.\CrossDesk.exe --unattended-enable
# After network registration, show its separate device ID, password and online state
# Show the shared device ID, password, online state, and current hosting mode
.\CrossDesk.exe --unattended-status
```
Connect from another device using the returned `device_id` and `password`. First-time setup copies the current client's server and codec preferences and creates separate credentials. This ID differs from the GUI client's ID and persists across reboots, logoffs and re-enabling. Subsequent enable commands retain the machine configuration. Self-hosted server root certificates must be trusted in the Local Computer certificate store.
Connect using the existing `device_id` and `password`. Password changes, device identity keys, and trusted-device records are shared between hosting modes. Re-enabling reuses this identity instead of creating a new ID. Self-hosted server root certificates must be trusted in the Local Computer certificate store.
Once enabled, `CrossDeskService` starts automatically at system boot. Windows automatic login and saved Windows login passwords are unnecessary. The service launches a windowless SYSTEM host in the active console session and reuses secure-desktop capture, keyboard/mouse input and `Ctrl+Alt+Del`. Signing in, locking Windows or closing the ordinary client does not stop it. Logoff, user switching or a host crash causes the service to restart the host; the connection may drop, and you can reconnect using the same ID. Network connections retry if networking is unavailable during boot.
Once enabled, `CrossDeskService` starts at system boot without Windows automatic login or saved Windows login passwords. A windowless SYSTEM host owns network connections, capture, keyboard/mouse input, and `Ctrl+Alt+Del`. The GUI attaches after the user desktop unlocks without another signaling login or replacing the remote connection. Closing or restarting the GUI preserves viewing and input. Logoff, switching Windows sessions, service restarts, or network failures can still require reconnection; networking retries if unavailable during boot.
Unattended mode supports screen viewing, keyboard/mouse input, monitor switching and secure desktops. Audio, file transfer, clipboard and privacy screens are unavailable. Portable and Debug builds cannot enable it. Configuration and credentials reside in `%ProgramData%\CrossDeskUnattended`, accessible only to SYSTEM and administrators; logs are in its `logs` subdirectory.
Before sign-in, screen viewing, keyboard/mouse input, monitor switching, and secure-desktop control are available. Once the GUI attaches, audio, file transfers, clipboard, and privacy screens run in the signed-in user process over the existing background connection; file operations do not run as SYSTEM. Those user features pause when the GUI exits and resume when reopened. Portable and Debug builds cannot enable this mode. Shared identity resides in `%ProgramData%\CrossDeskUnattended`, accessible only to SYSTEM and administrators; logs are in its `logs` subdirectory.
Without a physical monitor, the unattended host attempts to prepare a virtual display before accepting connections, preferring a previously recorded resolution and using 1920 × 1080 when no valid record exists. These temporary modes do not overwrite persistent Windows display configuration. Once a physical display is stable, the temporary virtual display is released while preserving the remote stream index.
```powershell
# Stop the unattended host and restore on-demand service startup
.\CrossDesk.exe --unattended-disable
```
Turning off ordinary Auto Start does not disable unattended mode. Disabling or uninstalling the service disarms unattended startup but retains the protected machine profile. To erase its credentials, stop the service and delete that directory as an administrator.
Turning off **Auto Start** disables unattended mode; CLI enable/disable operations are also reflected in the switch. Disabling or uninstalling the service disarms unattended startup but retains the protected machine profile. To erase its credentials, stop the service and delete that directory as an administrator.
<details>
<summary>Manual deployment and service commands</summary>
+115 -17
View File
@@ -4,20 +4,15 @@
## 来源 / Sources
- **2026-10-26** 从 `e551e04e` 的实际 Slint 组件重新生成中英文 README 引用的 6 张截图:ID 连接主窗口、IP 直连主窗口与六设备桌面墙,展示更新后的柔和阴影、输入框与按钮配色。沿用原有演示数据、图片尺寸及 2× 软件渲染。
- **2026-10-25** 删除“启用中继服务”开关,并将自托管配置拆分为普通标签、“编辑”按钮和开关后,从当前工作区组件重新生成常规设置与网络设置共 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` 标记表示记录类型,不代表在线探测结果。
- 本机 ID `123 456 789`、密码 `Ab12Cd` / `Cd34Ef`、地址 `192.168.1.10` 与 `192.168.1.20–22`、设备名称和连接状态均为演示数据,不是真实设备凭据。IP 列表还包含 `192.168.2.10` 作为切换示例。截图中勾选的“记住密码”是演示选择,配置状态不代表全部运行时默认值。
- 桌面墙放大视图和会话画面设置共 4 张继续沿用 **2026-10-19** 从 `1ef372d2` 渲染的截图。桌面墙展示六台演示设备,主窗口展示三台。
- “关于”中的 `v1.5.2` 和“已是最新版本”是捕获工具的示例值,不代表当前发布版本或实际在线检查结果。会话图使用公开页面作为远端画面,展示真实工具栏与画面设置菜单;隐私屏按钮处于关闭状态。
- 缩略图沿用既有公开页面截图:`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 页面;桌面设备预览继续复用这张图片。
- **2026-11-11** 从 `6414f231` 的实际 Slint 组件刷新 **22 张**中英文桌面截图,并新增 **4 张**双栏文件传输与反馈面板截图。使用 Slint 1.17.1、macOS arm64 和 2× 软件渲染;主窗口展示独立的 ID / IP 模式与桌面墙入口,设置展示最小化时暂停视频,会话菜单展示远端显示器分辨率。
- 捕获程序在**工程外临时目录**复用现有 [`slint_ui_smoke_test`](../../apps/desktop/tests/slint_ui_smoke_test.cpp) 的截图辅助函数,注入演示状态并直接渲染产品组件。没有启动应用运行时、监听端口或远控会话,也没有读取真实设备记录、浏览文件系统或执行传输。工程内未新增或修改测试;捕获源码、可执行文件和 PPM 均位于工程外。
- 本机 ID `123 456 789`、密码 `Ab12Cd` / `Cd34Ef`、地址 `192.168.1.10` 与 `192.168.1.20–22`、设备名称和连接状态均为演示数据。IP 列表还包含 `192.168.2.10`。主窗口展示三台设备,桌面墙展示六台;IP 近期设备的 `LAN` 标记表示记录类型,不代表在线探测结果。
- 文件传输图中的 `/Users/demo/Documents`、`/home/demo/Documents`、文件名、大小、日期与已完成任务均为演示数据。会话菜单中的分辨率列表也是演示能力,不表示某台真实显示器提供这些模式。勾选状态不代表全部运行时默认值。
- “关于”中的 `development` 是捕获程序设置的演示版本;未执行在线更新检查。反馈截图仅展示入口,没有导出本机日志或提交反馈。
- 缩略图和会话背景沿用公开页面截图:`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 页面、CLI 或原生移动端。CLI 图片保留 **2026-10-31** 的实际输出,来源见下方 [CLI 图示](#cli-captures)。
On **2026-10-26**, the six images referenced by the Chinese and English READMEs (ID mode, Direct IP mode, and the six-device DeskHub grid) were refreshed from the actual Slint components at `e551e04e`, showing the updated soft shadows and input and button colors. The existing demonstration data, image dimensions, and 2× software rendering were retained.
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 and separating Self-Hosted Config into a label, Edit button, and 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 four DeskHub enlarged-view and session-video images 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-11-11**, **22 desktop images** were refreshed and **4 file-transfer and feedback images** were added using the actual Slint components at `6414f231`, Slint 1.17.1 on macOS arm64, and 2× software rendering. The external capture program supplies demonstration data only: it starts no application runtime, listeners, remote sessions, file browsing, transfers, log export, or online update checks. No repository tests were added or changed. IDs, passwords, paths, file metadata, device states, resolution choices, and the `development` version are illustrative. Public-page fixtures remain from 2026-09-07, the Web image from 2026-09-25, and CLI output captures from 2026-10-31; native mobile screenshots are not included. Temporary source, binaries, and PPM files stay outside the repository.
## 文件 / Files
@@ -34,6 +29,8 @@ On **2026-10-25**, 16 images were rendered from the actual Slint components at `
| `desktop-self-hosted-*.png` | 自托管设置 / Self-hosting | 1280 × 944 |
| `desktop-stream-video-settings-*.png` | 会话工具栏与画面设置 / Session video settings | 1920 × 1200 |
| `desktop-about-*.png` | 关于与检查更新 / About and update check | 1280 × 944 |
| `desktop-files-*.png` | 双栏文件传输 / Dual-pane file transfer | 1920 × 1240 |
| `desktop-feedback-*.png` | 反馈与诊断日志入口 / Feedback and diagnostic log export | 1280 × 944 |
| `web-client.png`(中文) | Web 连接首页 / Web connection page | 1280 × 720 |
| `cli-ansi-overview.png` | CLI ANSI 四象限全景 / ANSI quadrant overview | 1280 × 800 |
| `cli-kitty-overview.png` | CLI Kitty 协议像素全景 / Kitty protocol pixel overview | 1280 × 800 |
@@ -148,6 +145,105 @@ int main() {
return RunCaptureMode(options, window, stream, server);
}
'''
# Documentation-only additions for the current UI.
source = source.replace('window->set_current_version("v1.5.2");',
'window->set_current_version("development");\n'
' window->set_update_check_status(crossdesk::ui::UpdateCheckStatus::Idle);')
source = source.replace(' // Preview DeskHub with the same demo images, without opening any sessions.',
' if (options.page == "feedback") window->set_feedback_open(true);\n'
' // Preview DeskHub with the same demo images, without opening any sessions.')
source = source.replace(' stream->set_video_menu_open(true);', r''' stream->set_video_menu_open(true);
stream->set_remote_resolution_visible(true);
stream->set_remote_resolution_enabled(true);
stream->set_remote_resolutions(std::make_shared<slint::VectorModel<slint::SharedString>>(
std::vector<slint::SharedString>{"1280 × 720", "1920 × 1080", "2560 × 1440"}));
stream->set_remote_resolution_index(1);''')
source = source.replace(' // Let settings scroll animations settle as well as hover/focus feedback.', r''' if (options.page == "stream-video-settings") {
stream->set_video_menu_open(false);
const slint::LogicalPosition logo({19.0f, 19.0f});
stream->window().dispatch_pointer_move_event(logo);
stream->window().dispatch_pointer_press_event(logo, slint::PointerEventButton::Left);
stream->window().dispatch_pointer_release_event(logo, slint::PointerEventButton::Left);
stream->window().dispatch_pointer_move_event(slint::LogicalPosition({950.0f, 590.0f}));
stream->set_video_menu_open(true);
}
// Let settings scroll animations settle as well as hover/focus feedback.''')
source = source.replace('options.page.rfind("settings", 0) == 0 ? 350 : 150',
'options.page == "stream-video-settings" ? 650 : options.page.rfind("settings", 0) == 0 ? 350 : 150')
source = source.replace('int RunCaptureMode(', r'''int CaptureFileBrowser(const CaptureOptions &options) {
auto files = crossdesk::ui::FileBrowserWindow::create();
if (!RegisterFontAwesome(files->window())) return 2;
const bool zh = options.language == 0;
files->set_chinese(zh);
files->set_peer_name("Office PC");
files->set_local_role(zh ? "控制端" : "Controller");
files->set_remote_role(zh ? "被控端" : "Host");
files->set_local_path("/Users/demo/Documents");
files->set_local_current_path("/Users/demo/Documents");
files->set_remote_path("/home/demo/Documents");
files->set_remote_current_path("/home/demo/Documents");
files->set_local_up(true);
files->set_remote_up(true);
files->set_local_status(zh ? "4 个项目" : "4 items");
files->set_remote_status(zh ? "4 个项目" : "4 items");
std::vector<crossdesk::ui::BrowserEntry> local, remote;
for (int pane = 0; pane < 2; ++pane) {
const char *names[] = {"Design assets", "Release notes.md", "Roadmap.pdf", "Screenshots.zip"};
const char *sizes[] = {"—", "12 KB", "248 KB", "8.4 MB"};
auto &entries = pane == 0 ? local : remote;
for (int i = 0; i < 4; ++i) {
crossdesk::ui::BrowserEntry entry{};
entry.name = names[i];
entry.path = slint::SharedString((std::string(pane == 0 ? "/Users/demo/Documents/" : "/home/demo/Documents/") + names[i]).c_str());
entry.directory = i == 0;
entry.selected = pane == 0 && i == 3;
entry.size = sizes[i];
entry.modified = "2026-11-11 10:30";
entries.push_back(entry);
}
}
files->set_local_entries(std::make_shared<slint::VectorModel<crossdesk::ui::BrowserEntry>>(local));
files->set_remote_entries(std::make_shared<slint::VectorModel<crossdesk::ui::BrowserEntry>>(remote));
for (int pane = 0; pane < 2; ++pane) {
std::vector<crossdesk::ui::BrowserTreeEntry> tree;
const char *names[] = {"demo", "Desktop", "Documents", "Downloads"};
for (int i = 0; i < 4; ++i) {
crossdesk::ui::BrowserTreeEntry entry{};
entry.name = names[i]; entry.depth = i == 0 ? 0 : 1;
entry.path = slint::SharedString((std::string(pane == 0 ? "/Users/demo" : "/home/demo") + (i == 0 ? "" : std::string("/") + names[i])).c_str());
entry.expanded = i == 0; entry.selected = i == 2;
tree.push_back(entry);
}
auto model = std::make_shared<slint::VectorModel<crossdesk::ui::BrowserTreeEntry>>(tree);
if (pane == 0) files->set_local_tree(model); else files->set_remote_tree(model);
}
files->set_local_selected(1);
files->set_transfer_ready(true);
files->set_can_upload(true);
files->set_tasks_expanded(true);
crossdesk::ui::BrowserTask task{};
task.id = 1; task.name = "Roadmap.pdf"; task.size = "248 KB";
task.detail = zh ? "发送到远端" : "Send to remote";
task.status = zh ? "已完成" : "Completed";
task.progress = 1.0f;
files->set_tasks(std::make_shared<slint::VectorModel<crossdesk::ui::BrowserTask>>(std::vector{task}));
files->set_task_summary(zh ? "1 个任务 · 已完成 1" : "1 task · 1 completed");
files->window().set_size(slint::LogicalSize({960.0f, 620.0f}));
files->show();
bool saved = false;
slint::Timer timer;
timer.start(slint::TimerMode::SingleShot, std::chrono::milliseconds(600), [&] {
saved = WriteWindowSnapshot(files->window(), options.snapshot_path.c_str());
slint::quit_event_loop();
});
slint::run_event_loop();
return saved ? 0 : 7;
}
''' + 'int RunCaptureMode(')
source = source.replace(' auto window = crossdesk::ui::MainWindow::create();',
' if (options.page == "files") return CaptureFileBrowser(options);\n'
' auto window = crossdesk::ui::MainWindow::create();')
(out / 'readme_capture.cpp').write_text(source)
print(out / 'readme_capture.cpp')
PY
@@ -155,7 +251,7 @@ PY
### 编译与捕获
以下路径对应 `macosx / arm64 / debug` 配置;其他配置先用 `xmake show -t slint_ui_smoke_test` 查看生成头文件与库路径,再调整。捕获按顺序执行,避免窗口互相抢占焦点。
macOS 编译需链接 `CoreFoundation`,供当前语言检测辅助函数使用。以下路径对应 `macosx / arm64 / debug` 配置;其他配置先用 `xmake show -t slint_ui_smoke_test` 查看生成头文件与库路径,再调整。捕获按顺序执行,避免窗口互相抢占焦点。
```bash
slint_prefix=$(xmake lua -c 'import("core.project.config"); config.load(); import("core.project.project"); print(project.target("slint_ui_smoke_test"):pkg("slint"):installdir())')
@@ -168,14 +264,16 @@ xcrun clang++ -std=c++20 \
"$capture_dir/readme_capture.cpp" \
build/macosx/arm64/debug/libcrossdesk_ui.a \
-L"$slint_prefix/lib" -lslint_cpp -Wl,-rpath,"$slint_prefix/lib" \
-framework CoreFoundation \
-o "$capture_dir/readme_capture"
for locale in zh en; do
language=0
if [ "$locale" = en ]; then language=1; fi
for page in main lan gallery; do
for page in main lan gallery lan-password settings settings-network settings-deskhub self-hosted about gallery-focus stream-video-settings files feedback; do
image_page="$page"
if [ "$page" = gallery ]; then image_page=deskhub; fi
if [ "$page" = gallery-focus ]; then image_page=deskhub-focus; fi
snapshot="$capture_dir/desktop-$image_page-$locale.ppm"
SLINT_BACKEND=winit-software SLINT_SCALE_FACTOR=2 \
CROSSDESK_UI_CAPTURE=1 \
@@ -192,8 +290,8 @@ done
逐张检查语言、页面、文字裁切、尺寸和演示数据后,将这些 PNG 复制到 `docs/images`,并更新日期与源码版本。桌面墙设置的标签在窗口初始化后设置,网络页滚动到对应分组,避免捕获尚未稳定的页面。
### 其他页面
### 捕获范围
使用指南中的截图可用相同程序捕获,将循环中的页面列表换为 `lan-password settings settings-network settings-deskhub self-hosted about stream-video-settings`。桌面墙放大视图使用 `gallery-focus` 页面,输出文件命名为 `desktop-deskhub-focus-*`。生成器已为桌面墙保留六台演示设备、300px 磁贴宽度和 500px 网格窗口内容高度;放大视图保持 698px(macOS)。这些设置仅影响临时捕获程序的示例数据和窗口尺寸。
上面的循环生成本轮全部 26 张桌面图片。可缩短页面列表以仅刷新所需页面。生成器为桌面墙保留六台演示设备、300px 磁贴宽度和 500px 网格内容高度;放大视图保持 698px(macOS)。会话捕获先展开真实工具栏,再显示画面设置菜单;文件浏览窗口只填充内存中的示例行,不连接文件操作回调。这些设置仅影响临时捕获程序。
若更新 Web 图片,应打开 Web 客户端,等待表单与底部版本号加载完成,保持 ID 与密码为空,再截取页面视口;替换后也需重新生成桌面图以同步缩略图。
Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 467 KiB

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 593 KiB

After

Width:  |  Height:  |  Size: 594 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 KiB

After

Width:  |  Height:  |  Size: 602 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 KiB

After

Width:  |  Height:  |  Size: 469 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 154 KiB

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 199 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 198 KiB

After

Width:  |  Height:  |  Size: 187 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 KiB

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 135 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 147 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 364 KiB

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

After

Width:  |  Height:  |  Size: 341 KiB