mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-15 00:09:39 +08:00
82 lines
18 KiB
Markdown
82 lines
18 KiB
Markdown
# 桌面墙(DeskHub)
|
||
|
||
主窗口标题栏下方可以切换“连接”和“桌面墙”,菜单位于同一行右侧。每次启动软件默认进入“连接”页,不恢复上次退出时的页面;保存的位置会在窗口显示前恢复。连接页保留原有布局和紧凑尺寸;桌面墙可以调整尺寸及全屏。普通窗口切换模式时保持左上角位置,仅分别记忆尺寸。切回连接页会退出全屏并恢复普通窗口位置与紧凑尺寸,再进入桌面墙会恢复它的尺寸及全屏状态。已断开的显示器所对应的位置会修正到可用屏幕内。
|
||
|
||
全屏按钮通过短暂淡出、等待窗口尺寸稳定、淡入完成切换,常规总时长约 0.2 秒;过渡期间屏蔽设备操作与重复全屏点击。窗口尺寸变化会立即更新网格,避免在新窗口中先显示旧的行列布局。过渡复用现有 UI 更新循环,不启动嵌套事件循环;失败或超时会恢复内容与交互。
|
||
|
||
可见的普通窗口若低于连接页最小尺寸,桌面墙恢复上次有效大小,连接页恢复固定大小;最小化、隐藏和全屏窗口不会触发这一恢复。窗口恢复以实际尺寸确认完成,期间不记录过渡尺寸;macOS 的最大化恢复使用无动画原生窗口调整,避免系统缩放动画嵌套事件循环。
|
||
|
||
## 使用
|
||
|
||
- 在桌面墙中点“添加设备”,填写设备 ID、密码和可选的分组名称,再点“添加并连接”。密码仅用于本次连接,勾选“记住密码”才会通过原有凭据机制保存;不会写入桌面墙配置。
|
||
- “从最近连接添加”支持多选、全选和统一指定分组。导入后只加入桌面墙,使用“批量选择 → 连接”再发起连接。同一分组内重复设备会跳过;不指定分组时,已在桌面墙中的设备不会重复加入。
|
||
- 连接成功后立即记录在连接页的“最近连接”中,无需等到断开,也不要求记住密码。失败的连接不会新增最近记录。
|
||
- “全部设备”显示保存的成员及当前活动会话。分组成员与连接相互独立:断开后成员仍在,重启后不会自动连接。
|
||
- 卡片名称栏以文字标签显示“在线/离线”,与画面中的连接状态分开,不遮挡预览。在线状态订阅包含全部分组中的设备;尚未收到结果、结果过期或服务器断连时显示“未知”,已有活动连接的设备仍显示在线。
|
||
- 鼠标悬停时,名称栏右侧显示与近期连接一致的改名、修改分组、移除、连接/断开操作条,并显示按钮提示。两处的连接按钮均随实际会话状态切换:未连接时显示连接箭头,已连接时显示叉号,点击断开该设备;点卡片仍可查看设备。名称与近期连接共用别名;移除会先确认,只移除当前分组或桌面墙中的成员,不删除近期记录或断开会话。批量选择时隐藏操作条。
|
||
- 两处的“修改分组”共用操作条组件、分组弹窗和保存逻辑。可以选择多个已有分组、填写新分组,或选“未分组”清除分组归属。分组与桌面墙成员独立保存:近期连接修改分组不会自动加入桌面墙,也不会自动连接;通过“从最近连接添加”或“添加设备”才保存为桌面墙成员,未指定新分组时保留已有分组。从“全部设备”移除成员后仍保留其分组信息;在特定分组中移除则取消对应分组归属,移除最后一个分组后仍保留在“全部设备”中。修改分组保留墙内设备的顺序,保存失败时保留弹窗和输入。
|
||
- 近期连接的设备提示浮窗显示所属分组;多个分组并列显示并自动换行,没有分组时显示“未分组”。分组变更后自动刷新。
|
||
- “近期连接”标题行右侧可按“全部设备”、未分组或已有分组筛选;一个设备可出现在它所属的多个分组中。筛选与桌面墙当前分组独立,不改变历史记录、在线状态订阅或桌面墙成员。分组修改后自动更新结果;当前分组被清空删除时回到全部设备。
|
||
- 网格随窗口大小增加行列,紧凑窗口为 3 × 2;翻页不关闭连接。分组内顺序不会按在线状态自动重排。
|
||
- 顶部“精简模式”切换为仅画面的设备卡片,隐藏名称、在线状态、状态文字和悬停操作条,同时收起设备管理工具栏、连接计数与底部服务器状态栏;画面完整等比显示,不裁切。顶部保留“退出精简”、网络状态、全屏及菜单入口,多页时保留分页。点击图片仍可展开查看和接管操控,返回后保持精简模式;模式切换会释放操控、退出批量选择并返回网格,不改变连接、分组和设备顺序。
|
||
- 菜单中的全局“设置”顶部并排提供“常规”和“桌面墙”两个选项卡;“桌面墙”可统一配置桌面墙设备的传输分辨率上限和帧率,在连接页面以及桌面墙普通、精简、展开和全屏视图中均可打开。切换选项卡保留未保存修改,底部统一保存或取消。分辨率支持自动、320 × 180、640 × 360、1280 × 720、1920 × 1080、2560 × 1440、3840 × 2160和原始分辨率;固定上限适用于缩略图和展开画面,保持比例且不放大源画面。帧率支持跟随设备设置、15、30、60 FPS。保存后立即更新当前桌面墙会话,也用于后续桌面墙连接,不影响普通连接,跨分组和分页生效;取消不应用修改,恢复默认需保存后生效。配置保存在本地,重启后保留;保存失败时保留面板和输入。打开设置会释放远程操控。
|
||
- 顶部“网络状态”按钮打开当前已建立连接的设备列表,不受桌面墙分组和分页限制;离线、未连接和连接中的设备不列入,断开后自动移除。列表显示设备名称、ID、直连/中继、实际协商的 SRTP 加密状态、往返延迟(RTT)、控制端接收与发送速率、视频丢包率、实际接收分辨率与帧率,打开期间每秒刷新。加密状态紧随连接方式显示为“已加密/未加密”,尚无统计或报告超过 3 秒未更新时显示“待确认”。分辨率与帧率在解码交付时统计,墙内预览和后台会话均可用;尚未收到画面时显示“—”,画面停止更新超过 1 秒时帧率显示 0 FPS。网络数值尚无统计或报告超过 3 秒未更新时显示“—”。可通过关闭按钮、Esc 或点击列表外关闭;打开列表会释放远程操控。
|
||
- 点卡片进入只读放大视图,点“接管操控”才开始发送键鼠。点“释放操控”或按 Ctrl/⌘ + Shift + Esc 可以释放。切换设备、翻页、打开本地操作面板、切换模式及窗口失焦也会释放。
|
||
- 桌面墙连接默认静音,包含新建连接、重连、复用已有连接、添加或导入已有会话,以及切入桌面墙时已有的连接。展开、全屏或接管操控不会自动开启声音;需要声音时,可通过批量“取消静音”或在独立串流窗口主动开启。两个入口共用同一静音状态,主动开启的声音在桌面墙可见时播放,翻页、展开及释放操控保留声音设置;每台设备使用独立音频流同时播放,静音一台不会清空其他设备的声音。新版本对端按会话关闭音频订阅;旧版本发送的音频由控制端丢弃,不通过停止对端的全局声音采集影响其他控制端。
|
||
- 放大视图使用一行设备操作栏,只保留返回、设备名称、状态和接管/释放操控按钮;紧凑窗口的设备缩略图位于下方,宽窗口移到右侧。缩略图显示设备名、在线状态和当前设备标记,缺少画面或画面停滞时有状态占位;滚动条单独留出空间。调整尺寸后当前设备仍在列表中,选中时自动滚入可见区域。主预览和缩略图均完整等比显示,鼠标坐标按实际预览区域映射。
|
||
- 在“近期连接”中点击已连接设备的卡片画面,可打开原有独立串流窗口,使用声音、显示器切换、隐私屏、文件传输等完整单会话工具。关闭墙内设备的独立窗口不会断开墙中的会话。
|
||
- 批量选择复用固定底栏,设备卡片的位置和尺寸不变。底栏提供“全选”:选中当前筛选下的所有设备,跨页生效;全部选中后显示“取消全选”。翻页保留选择,切换分组清空选择;已选数量与跨页数量、连接/断开/静音/分发文件及分页控件在同一底栏显示。声音按钮根据已选且已连接设备的状态切换:全部静音时显示“取消静音”,有设备开启声音时显示“静音”,无已连接设备时禁用。点击后统一设置所有已选的已连接设备,包含跨页选择,跳过未连接设备,保留当前选择。断开和文件分发会先列出完整目标;提交后的操作目标不会跟随之后的选择变化。
|
||
|
||
## 预览与兼容性
|
||
|
||
自动分辨率模式下,桌面墙发起或接管的会话在能力协商后默认请求最长边不超过 320 像素的画面。点卡片展开后,根据视频显示区域的实际物理像素(包含 HiDPI 缩放)请求分辨率;全屏、退出全屏和调整窗口大小后会重新计算,尺寸稳定 200 毫秒后更新订阅。返回网格或切换到其他设备后恢复缩略图尺寸。不可见设备暂停视频;如果同一设备仍在可见的独立串流窗口显示,则继续传输。同一会话同时在独立串流窗口显示时,按两个可见视频区域中较大的尺寸请求,避免小预览降低大窗口的清晰度。选择固定或原始分辨率后使用对应上限;恢复自动后重新跟随视图。普通连接页发起且未加入桌面墙管理的会话保留原有分辨率行为。
|
||
|
||
被控端按连接分别在编码前缩放,完整保留桌面比例,不放大超过源画面的尺寸,也不修改被控端屏幕的系统分辨率。请求的宽高是上限,画质和网络自适应仍可降低实际发送尺寸。默认跟随每个会话原有的 30/60 帧设置;指定帧率仅覆盖桌面墙订阅,不修改会话的画质或原有帧率偏好。声音仍需明确开启。
|
||
|
||
15 帧订阅使用编码前发送节流和稳定的逐显示流时间预算,并采用保持分辨率策略,避免低帧率触发交互视频的画质降级。30/60 帧选项使用编码器自身的交互帧率控制。仅向声明 `supports_deskhub_fps15` 的对端发送 `fps=15`;缺少该能力的 v1/v2 对端使用原有 `fps=60, frame_rate=30` 格式回退到 30 FPS,未声明预览能力的更旧版本保持原行为。协议仍接受旧控制端的 1/8 帧请求,但设置界面不再提供这两个档位。
|
||
|
||
预览在解码回调中随收到的画面生成有界缩略图,可见桌面墙随 UI 刷新显示最新帧。UI 不处理全分辨率转换,只保留当前可见设备的最新预览,超过 5 秒未更新会标记停帧。画面保持比例,以完整矩形显示;外层圆角卡片与画面之间保留内边距,不裁切桌面内容或画面边角。实际显示帧率受设备性能与网络状况影响。
|
||
|
||
连接旧版被控端时,若仅声明 `supports_deskhub_preview`,控制端发送原有 v1 订阅;若未声明预览能力,则不发送该订阅,沿用其视频策略。旧控制端连接新版被控端时继续使用原分辨率;v1 订阅也会清除此前的尺寸限制。只有同时声明 `supports_deskhub_preview` 与 `supports_deskhub_resolution` 的被控端才会收到 v2 尺寸请求,旧版本不承诺发送端节省资源。
|
||
|
||
### 视频带宽分配
|
||
|
||
“设置 → 桌面墙 → 视频总带宽”配置所有支持带宽协商的桌面墙会话共享的视频预算,默认 20 Mbps,可选 2、5、10、20、50、100 Mbps。保存立即应用,取消不生效,重启后保留;恢复默认后需要保存。它是视频的持续目标预算,包含发送端为视频纠错、重传及 RTP 开销预留的份额;音频、文件传输、普通连接及不支持带宽协商的旧版设备不计入,关键帧和切换期间的瞬时速率可能超过预算。
|
||
|
||
控制端根据请求的分辨率和帧率估算每台设备的需求上限。先为每台可见设备保留至多 100 Kbps 的基础份额(总预算不足时等分),再按权重分配剩余预算:展开画面或可见的独立串流窗口权重为缩略图的 4 倍。相同规格、相同优先级的设备基本均分;达到需求上限的设备让出剩余额度,不强制用满总预算。默认缩略图 320 × 320 上限、30 FPS 的需求预算为 500 Kbps。分配随连接、分页、分组、窗口可见性以及分辨率/帧率变化更新,独立串流窗口和墙内画面使用同一份设备预算。需求和总预算未变化时复用分配结果,不随 UI 刷新重复计算。
|
||
|
||
翻页、切换分组、隐藏或最小化桌面墙后,没有可见画面的墙内会话发送 `fps=0` 暂停视频,保留连接和主动开启的音频。重新可见后恢复当前需求并请求关键帧。单纯重新分配带宽不会触发所有设备同时发送关键帧,也不会重置 15 FPS 的发送节奏。
|
||
|
||
预算不代表测速结果。每条连接原有的拥塞控制继续工作,发送端使用网络可用带宽与设备预算中的较小值,并在设备的多个活动显示流之间再分配。视频探测速率受同一设备额度约束,以便网络恢复或画面展开后继续升速;额度下降会取消旧探测,暂停视频时关闭探测和填充包。只有声明 `supports_deskhub_bandwidth` 的对端会收到带宽字段;支持预览但不支持带宽协商的旧版仍能暂停不可见视频,更旧版本保持原行为。
|
||
|
||
### 协议与接口
|
||
|
||
可靠控制通道的 `deskhub_preview` v2 保留 v1 的 `request_id`、`fps`、`quality`、`frame_rate`、`preference`、`audio` 字段,新增必填 `width`、`height` 整数,单位为物理像素。两个值均为 0 表示恢复源尺寸上限,否则两个值均须在 2~16384 之间;非法或缺失的值不应用。`deskhub_preview_status` 回传请求的协议版本、请求 ID 与 `accepted`。请求 ID 跳过 0,支持 32 位回绕,重复或过期请求不会覆盖新设置。断开会话清除订阅和 15 FPS 协商能力,再连接会重新发送当前需求。15 FPS 扩展通过可选能力 `supports_deskhub_fps15` 协商,沿用 v1/v2 的字段结构,使用 `fps=15, frame_rate=30`,在编码前将实际输入限制为 15 FPS。
|
||
|
||
带宽扩展沿用 v1/v2,增加可选整数 `max_bitrate_bps`(0~100000000,单位 bps),仅向声明 `supports_deskhub_bandwidth` 的对端发送。0 或缺省表示解除额外的视频预算限制;暂停视频仍使用 `fps=0`。非法字段拒绝整个订阅,断开后清除能力,重连重新协商。MiniRTC 的 `UpdateVideoBitrateLimit(peer, remote_id, remote_id_size, max_bitrate_bps)` 为指定连接的所有视频流设置合计预算,不改变音频与数据发送;返回 0 表示已进入拥塞控制队列,-1 表示参数、连接或传输不支持。
|
||
|
||
MiniRTC 新增 `UpdateVideoResolution(peer, remote_id, remote_id_size, width, height)` 接口,返回 0 表示已接受,-1 表示参数、连接或传输类型不支持。它为指定控制端的所有显示流设置独立尺寸上限,切换时丢弃旧设置尚未发出的编码结果,并请求新关键帧;底层自适应也以这个上限作为有效源尺寸。
|
||
|
||
`SetVideoSendPaused(peer, remote_id, remote_id_size, paused)` 与 `SetAudioSendPaused(peer, remote_id, remote_id_size, paused)` 分别控制指定连接的所有视频/音频发送通道,`true` 暂停、`false` 恢复。重复设置不产生额外操作;返回 0 表示接受,-1 表示参数、连接或传输类型不支持。视频暂停阻止新帧进入编码,废弃旧编码结果,并在发送队列上清除待发视频/重传/纠错包,停止探测和填充;恢复请求新关键帧。音频暂停阻止 PCM 编码并清理待发音频,恢复时仅发送新音频。已交给网络的包无法撤回。API 保留连接、采集源、码率与画质设置以及其他媒体/数据通道,也不改变其他控制端的发送状态。
|
||
|
||
桌面墙将 `fps=0` 和 `audio=false` 分别映射到上述 API;应用层仅保留低帧率节流,不再使用 `1 bps` 代替视频暂停或在采集回调中过滤静音音频。接收端仍保留静音门控及播放队列清理,以立即停止播放网络中已在途的音频。旧版 `audio_capture` 命令在支持新 API 的传输中也按连接静音,已有订阅的音频状态优先;不支持 API 的旧/Web 传输沿用采集开关回退。
|
||
|
||
## 批量操作
|
||
|
||
连接和文件分发最多并行启动 4 个操作。尚未开始连接的设备卡片显示“排队中”,轮到后自动切换为实际连接状态。断开立即执行,同时取消该设备排队中的操作及重连请求,不等待文件传输完成。单台等待密码不会阻塞其他设备,可以从对应设备的放大视图填写密码。连接状态显示在设备卡片上,文件传输详情可在该设备的独立串流窗口中查看。
|
||
|
||
批量操作仅在本次运行中执行,不提供任务列表、操作历史或重启后的恢复。成员资料与窗口状态保存在应用缓存目录的 `deskhub.json` 和 `deskhub.json.window` 中,不含设备密码和文件内容。
|
||
|
||
`deskhub.json` 第 2 版分别保存分组记录和桌面墙设备 ID,并通过可选的 `stream_settings` 保存分辨率预设及帧率。缺少或无效的设置使用自动分辨率和跟随设备帧率,不影响设备成员。已保存的 1/8 FPS 自动迁移为 15 FPS,保留原分辨率预设;原有 30/60 FPS 设置保持不变。第 1 版配置仍可读取,原有桌面墙成员、分组和顺序会保留;旧版数据未记录加入来源,因此不会自动移除已有成员。
|
||
|
||
批量远程命令、重启尚未提供。实际大规模并发容量需要用真实设备测量。
|
||
|
||
## 验证
|
||
|
||
```sh
|
||
xmake build crossdesk
|
||
xmake run slint_ui_smoke_test
|
||
xmake run crossdesk_wire_test
|
||
xmake run keyboard_state_wire_test
|
||
```
|