Skip to content

全屏放映统一模型与实施规划 ​

状态:已实施(2026-10-18) 范围:Runtime 项目放映、演讲者模式、Editor 放映入口与相关文档 上位计划:翻页动画与自动放映实施总计划 相关模块:Runtime 计划、Editor 计划、联调与验收计划

本规划是 M3 完成后的交互收敛,不新增 Backend 字段、External API 或预览构建契约。目标是把已经存在的放映控制器、全屏布局和演讲者双窗口收敛为一条状态链;实施时更新现行文档和回归证据,不回溯改写已完成工作包的历史记录。

1. 背景与问题 ​

自动放映、全屏预览和演讲者模式此前分别演进,Runtime 中同时存在两套翻页入口和两套快捷键:

  • PlaybackHostBridge.vue 无条件挂在 ResponsiveLayout.vue 中。只要产物带 playback 配置,控制器就会创建,stopped 状态也会渲染底部控制条。
  • 全屏只是布局内的局部状态,和播放状态互不相干:可以“放映但未全屏”,也可以“全屏但未放映”;退出全屏不会停止自动推进。
  • 旧的右上角翻页、底部缩略图、画布两侧箭头与新的控制器自动翻页同时存在;手动翻页会隐式重置停留计时。
  • 空格键存在多种含义:预览层按旧逻辑翻页,播放层在捕获阶段切换开始/暂停,演讲者控制台又是下一页。
  • 演讲者控制台同时存在放映面板、演讲计时和旧的上一页/下一页;观众窗口还会自己响应键盘。
  • Editor 入口只有“放映”,但打开的是旧整项目预览壳;用户无法区分“预览”和“放映”。

这些问题不是缺少功能,而是缺少统一的归属:谁拥有页面推进、谁决定全屏、谁决定自动或手动。

2. 目标与非目标 ​

2.1 目标 ​

  • 明确 非全屏 = 预览,全屏 = 放映;退出全屏就是结束本次放映。
  • 复用现有 PlaybackController,不重写调度、媒体和转场就绪链路。
  • auto_start 只决定进入全屏时的初始模式;运行中可以在自动和手动之间切换。
  • 手动模式只停止页面自动推进,不暂停正在播放的媒体。
  • 全屏放映只保留一条控制条和一套键盘语义,预览态不再出现放映控制条。
  • 演讲者模式收敛为“观众窗口是放映本体,主窗口是控制台”,不产生第二个调度器。
  • 不新增 runtimeMode、不新增播放布局、不改变 Backend 存储结构。

2.2 非目标 ​

  • 不重新设计 none/fade/push 转场、媒体判定或截图/导出隔离。
  • 不新增远程控制、移动端适配、Firefox/WebKit 验收或无人值守代理。
  • 不保留“带侧栏/缩略图的全屏预览”;全屏即放映,需要目录时退出到预览。浏览器级 F11 全屏不在此模型内且无法被页面拦截,此时仍是预览。
  • 不新增 Backend 字段;auto_start 只调整运行语义和界面文案。
  • 不改变页面内容、组件、主题、资源或构建产物格式。

3. 核心模型 ​

3.1 三个场景 ​

场景触发播放控制器界面
预览非全屏项目壳不创建侧栏、缩略图、卡片、导出、旧的上一页/下一页
放映根元素进入全屏创建并启动纯画布 + 一条放映控制条
演讲放映中点击“演讲”观众窗口唯一持有主窗口控制台 + 观众窗口全屏放映

Editor 页面详情的“放大查看”仍是单页 iframe 弹窗,不属于本模型;它没有路由、整页转场和放映控制。

3.2 全屏即放映 ​

  • 进入全屏时创建本次放映的控制器并启动会话,不提供单独的“开始”按钮。
  • auto_start=true 表示进入后默认自动推进;auto_start=false 表示进入后默认手动,页面可翻但不会自动前进。
  • 退出全屏时停止计时、媒体并销毁控制器,回到预览;当前页保持不变。
  • 全屏请求被拒绝时留在预览并给出可见错误,不静默降级为窗口放映。
  • 只有 document.fullscreenElement === document.documentElement 才视为放映全屏。视频、图表等页面内元素全屏期间 fullscreenElement 不是根元素,放映状态保持不变:继续按当前模式推进,也不暂停媒体。
  • 退出页面内元素全屏后,Chromium 不会恢复根元素全屏,fullscreenElement 变为空,按退出全屏处理:本次放映结束并回到预览,需要重新点击“进入放映”。
  • 浏览器原生 F11/菜单全屏属于浏览器级全屏,不写入 document.fullscreenElement,因此不视为进入放映,也不会启动或推进本次放映;布局层不拦截 F11。
  • Editor 的“放映”入口仍打开 Runtime 预览;受浏览器用户手势限制,最后一步“进入放映”必须在 Runtime 窗口内点击。

3.3 自动与手动 ​

会话增加运行时开关 autoAdvanceEnabled,初始值来自 auto_start,只存在于本次放映,不写回 Backend。

当前页 advance.mode自动模式手动模式
manual等待用户上一页/下一页等待用户上一页/下一页
timer停留计时,到点自动下一页不计时,等待用户翻页
media_end播放媒体,结束后自动下一页媒体继续播放,结束后不自动翻页

规则:

  • 自动/手动只控制“页面是否自动前进”,不控制媒体播放。
  • 自动切手动:取消当前页停留计时和媒体等待计时;页面不动,正在播放的媒体继续。
  • 手动切自动:
    • timer 页从切换时刻重新开始一整轮停留时间;
    • media_end 页在媒体仍播放时等待结束,媒体已结束时按无媒体停留时间推进;
    • manual 页仍等待用户翻页,不因为会话切到自动就强行推进。
  • 会话切到手动时,manual 配置页和自动配置页都停止自动推进;会话切到自动时,只有配置为自动的页面恢复自动推进。
  • transition 在两种模式下都生效,手动翻页也播放整页转场。
  • loop 只在自动模式生效;手动模式末页“下一页”不绕回首页。
  • 后台标签页、冻结和 pageshow 恢复仍使用现有暂停逻辑;回到前台后显示“继续”,恢复后保持原自动/手动模式。

3.4 状态机 ​

text
非全屏(预览)
  │ 进入全屏
  ▼
preparing ──就绪──> playing
  │                  ├─ 自动:timer / media_end 推进
  │                  ├─ 手动:等待上一页/下一页
  │                  ├─ 系统中断 ──> paused ──继续──> playing
  │                  ├─ 自动末页且不循环 ──> ended
  │                  └─ 错误/受阻 ──> error / blocked
  │
  └─ 退出全屏 ──> 销毁控制器,回到预览
  • 全屏内不存在“未开始”的独立状态:auto_start=false 直接进入手动会话。
  • paused 只表示系统中断或媒体控制的临时暂停,不是主操作;主操作是自动/手动切换。
  • ended 只由自动序列产生;手动模式在末页等待用户退出或切到自动。
  • error/blocked 继续提供重试、下一页、退出。

3.5 翻页与就绪 ​

  • 手动上一页/下一页继续复用现有路由导航和 notifyPageChange:播放中翻页重置当前页计时,暂停中翻页保持暂停,旧 generation 的迟到结果被丢弃。
  • 自动推进继续等待“路由提交 + 整页转场 settled + 必要视觉资源就绪”后开始停留或媒体等待。
  • 媒体会话在自动和手动模式下都可以播放;手动模式不启用媒体超时,但实际播放错误/受阻仍然可见并可重试。
  • 不新增第二套翻页状态机,也不在控制器外单独维护自动/手动计时。

4. Backend 配置参数 ​

放映态直接使用项目路由产物中的 playback 和每页生效的 meta.transition/meta.advance,不额外请求 Backend。字段定义继续以 contract.md 为准。

参数放映态行为
auto_start进入全屏时的初始模式:自动或手动。字段不变,语义从“是否开始会话”改为“是否自动推进”。
transition.effect / duration_ms自动和手动翻页共用的整页转场。
advance.mode自动模式下当前页的推进方式;会话手动时强制等待。
advance.delay_mstimer 停留时间;media_end 无媒体时的回退时间。
media_timeout_ms自动模式下的媒体等待上限;手动模式不启用。
loop自动模式末页循环;手动模式不绕回。
逐页覆盖继续由 Backend 解析为生效值,Runtime 按当前页读取;同一页面多次引用可不同。
hidden / page_number决定放映序列;隐藏页不参与上一页/下一页和自动推进。
menu_mode / show_pdf_export只属于预览壳;全屏放映不显示菜单、导出、卡片和缩略图。
speaker_notes只进入演讲者控制台,不参与页面推进。
页面尺寸、主题、字体、样式预览和放映共用,属于渲染配置。
  • 不新增数据库迁移、DTO 或 External API 字段。
  • Editor 配置文案建议改为“进入放映后自动推进”,并说明关闭时进入全屏后先手动翻页,可随时切换自动。
  • CLI/MCP 文档同步说明 auto_start 的新运行语义;读写契约不变。

5. 界面与交互 ​

5.1 预览态 ​

  • 保留现有侧栏、缩略图、卡片模式、导出和上一页/下一页。
  • 不创建播放控制器,不显示放映控制条,不启动任何停留计时。
  • 右上角“全屏”入口改为“进入放映”,点击后请求全屏并进入放映态。
  • 预览工具栏保留“演讲”入口(Shift+P 同样可用);从预览进入时没有本窗口放映会话,观众窗口按项目 auto_start 起步。
  • 预览键盘:→/↓/PageDown/空格 下一页,←/↑/PageUp 上一页;Home/End 跳首末页;数字键跳页;O 打开卡片模式;F 进入放映;Shift+P 进入演讲。输入框和可编辑元素内不拦截。

5.2 放映态 ​

控制条只保留:

text
上一页 | 自动/手动 | 下一页 | 页码 | 自动剩余时间 / 手动 | 演讲 | 退出
  • 自动模式显示剩余时间;手动模式显示“手动”。
  • 控制条默认收起:指针进入窗口底部唤出区域时淡入,移开即淡出;暂停、错误、受阻、结束态以及无放映配置的旧产物保持显示。键盘 Tab 聚焦控制条时同样会唤出。
  • 当前页配置为 manual 时显示“本页手动”,即使会话处于自动模式。
  • 系统中断导致暂停时显示“继续”;不把暂停作为主操作。
  • 媒体错误/受阻时显示重试和下一页。
  • 结束态显示“重新开始”和“退出”。
  • “退出”退出全屏并结束放映,不保留后台计时。

5.3 键盘 ​

键位映射统一维护在 runtime/src/runtime-shell/keyboard/keyboard-map.ts(上下文 × 键位 × 动作),布局层只负责解析结果与执行动作。

场景空格 / → / ↓ / PageDown← / ↑ / PageUpHome / End数字键其他
预览下一页上一页首/末页跳页O 卡片模式;F 进入放映;Shift+P 演讲
放映下一页上一页首/末页跳页Shift+P 演讲
卡片模式下一页上一页不处理不处理Esc 关闭卡片
演讲者控制台切换自动/手动上一页/下一页不处理不处理命令发送给观众窗口
观众窗口不处理不处理不处理不处理Esc 退出全屏并暂停
  • 放映态不再由播放层独占空格:usePlaybackHost 不注册键盘监听,空格与方向键统一由布局层按下一页处理;布局层仍保留“焦点在按钮/链接上时空格不抢原生激活”的约束。
  • 数字键跳页:总页数不超过 9 时立即跳转;超过 9 时缓冲最多两位,约 600ms 后提交,页码越界给出行内提示。0 只用于两位数缓冲。
  • 不拦截 F11。F11/浏览器菜单全屏是浏览器级全屏,不触发 fullscreenchange,也不进入放映;进入放映由页面内“进入放映”按钮或 F 键调用 Fullscreen API。
  • fullscreenchange 是进入/退出放映的唯一入口,且只认“根元素全屏”(进入)与“无全屏元素”(退出)两种状态。
  • 预览与放映都可用 Shift+P 进入演讲。
  • 输入框、文本域、下拉框和可编辑区不拦截;带 Ctrl/Meta/Alt 的组合一律不映射。

5.4 演讲者模式 ​

text
主窗口:演讲者控制台(窗口化)
  当前页 / 下一页缩略图
  演讲备注
  演讲用时(独立计时)
  自动/手动、上一页/下一页、退出
        │ 命令
        ▼
观众窗口:全屏放映本体(唯一推进者)
  只显示当前页和页面转场
  按 Backend 配置自动/手动推进

流程:

  1. 在预览工具栏或放映控制条点击“演讲”,或在预览/全屏按 Shift+P。
  2. 主窗口暂停并结束本窗口放映、退出全屏,切换为控制台。
  3. 观众窗口打开并进入全屏,从当前页开始;从放映进入时继承运行时自动/手动模式,从预览进入时按项目 auto_start 起步。
  4. 控制台的自动/手动、上一页/下一页、退出通过同步协议发送给观众窗口;观众窗口是唯一计时和推进者。
  5. 观众窗口退出全屏、关闭或断开时,放映暂停,控制台显示状态;重新全屏并连接后才能继续。
  6. 退出演讲关闭观众窗口,主窗口回到预览。

约束:

  • 观众窗口必须全屏才能开始放映;未全屏时只显示进入全屏提示,控制台显示等待。
  • 观众窗口是只读视图,不注册本地播放/翻页快捷键;控制台是唯一输入入口。
  • 控制台合并原来的放映面板和页面按钮为一条传输栏;演讲计时仍独立,只表示演讲用时。
  • 从放映进入演讲时把当前页和运行时自动/手动模式交给观众窗口;从预览进入时按项目 auto_start 起步,不伪造运行时状态。
  • 同步协议增加 autoAdvance 状态和“设置自动推进”命令;双窗口同构建版本,必要时升级协议版本。
  • 不创建第二个 PlaybackController 或第二个计时器。

6. 实施阶段 ​

阶段范围退出条件
P0:控制器自动/手动能力PlaybackController 增加 autoAdvanceEnabled、切换语义、计时/媒体守卫;usePlaybackHost 暴露切换虚拟时钟覆盖自动/手动切换、计时重置、媒体继续、手动页不自动、循环边界
P1:全屏放映壳控制器只在全屏创建;预览去除控制条;放映工具栏、键盘、全屏失败提示、auto_start 初始模式单元/组件测试覆盖预览无控制器、全屏进入/退出、键盘归属、系统中断
P2:演讲者收敛演讲入口迁移;观众窗口全屏门禁与只读;控制台传输栏;协议状态与命令双窗口真实浏览器验证唯一调度、模式继承、观众只读、关闭重开、退出回预览
P3:入口、文档与证据Editor 入口提示;用户/开发文档;WP31/WP33 入口与证据更新;旧按钮/旧文案清理文档一致;构建产物/放映入口说明可复现;无残留重复控制

每个阶段单独可评审;P1 不依赖 P2,P2 以 P1 的放映壳为前置。

7. 文件级改动 ​

文件改动
runtime/src/runtime-shell/playback/playback-controller.ts增加会话自动/手动开关、有效推进模式、计时与媒体推进守卫
runtime/src/runtime-shell/playback/usePlaybackHost.ts暴露切换方法;手动切自动时重建/复核当前页媒体与计时;全屏挂载时初始化模式
runtime/src/runtime-shell/playback/PlaybackHostBridge.vue改为全屏放映控制条:上一页/自动手动/下一页/页码/状态/演讲/退出/重试
runtime/src/runtime-shell/layouts/ResponsiveLayout.vue全屏即放映;预览不挂控制器;隐藏预览控件;统一键盘与退出逻辑;移除 F11 劫持(F11 仅为浏览器级全屏,不进入放映)
runtime/src/core/router/runtime-session.ts按需同步放映状态;移除一次性 autoStartAttempted 假设
runtime/src/runtime-shell/presenter/PresenterDisplayView.vue全屏才启动控制器;继承页面与模式;观众只读
runtime/src/runtime-shell/presenter/PresenterConsoleView.vue合并传输栏;自动/手动命令;演讲计时独立
runtime/src/runtime-shell/presenter/usePresenterController.ts传递/回显 autoAdvance;观众全屏状态门禁
runtime/src/runtime-shell/presenter/presenter-sync-protocol.ts增加自动推进状态与命令;必要时升级协议版本
editor/src/views/PagesView.vue、editor/src/utils/project-presentation.ts入口文案/提示调整,说明 Runtime 窗口内进入全屏;不改变 artifact 流程
docs/developer/runtime-integration/slideshow/*、docs/user/workflows/*更新模型、控制、快捷键、入口和限制
docs/developer/runtime-integration/slideshow/work-packages/wp31-*.md、wp33-*.md更新构建产物/无人值守入口说明与证据
Backend无代码/迁移改动;仅更新 auto_start 文案和对外说明

8. 验收计划 ​

编号场景验收
A1预览态无控制器、无控制条、无自动计时;方向键翻页;空格不启动放映
A2进入/退出全屏进入即进入放映;退出即停止并回预览;全屏失败留在预览并提示
A3自动开始auto_start=true 进入后按 advance 自动推进;manual 页仍等待
A4手动开始auto_start=false 进入后手动翻页;无计时器;转场正常
A5自动切手动当前页计时取消、页面不动、媒体继续;切回自动按约定重新计一轮
A6媒体页手动模式媒体继续但不自动翻页;切回自动后按媒体结束或回退停留推进
A7循环与边界自动循环、手动末页不绕回、单页循环周期正确
A8键盘预览/放映/控制台/观众窗口按本规划映射,无双重触发
A9演讲者模式观众窗口唯一调度;继承页面和模式;控制台切换同步;观众只读
A10异常与恢复全屏失败、观众未全屏、观众关闭/退出全屏、错误/受阻均有明确状态
A11捕获/导出/缩略图不受放映态影响;不启动自动推进和媒体播放
A12文档与证据用户文档、Runtime README、WP31/WP33 入口与新行为一致

单元测试覆盖控制器与协议;组件测试覆盖布局、控制条和键盘;双窗口与全屏、媒体、转场必须在真实桌面 Chromium 中验证,不以 JSDOM 代替。

9. 风险与已知限制 ​

  • Editor 手势限制:Editor 新窗口无法可靠自动请求全屏,用户必须在 Runtime 窗口点击“进入放映”。Editor 入口文案需要说明这一点。
  • M3/无人值守入口:直接打开构建链接默认是预览,auto_start 不再在窗口内自动推进;无人值守需要全屏点击或 kiosk/自动化,WP31/WP33 的入口与证据必须更新。产品级无人值守仍不在本规划范围。
  • 全屏失败:按本规划不提供窗口放映 fallback;不支持全屏的环境无法进入放映。若后续需要,另设明确的窗口放映例外。
  • 内容元素全屏:视频、Mermaid、Drawio 等元素全屏期间放映继续,但不暂停页面推进;Chromium 退出元素全屏后不会恢复根全屏,因此本次放映结束并回到预览。“退出元素全屏后继续放映”需要重新请求根元素全屏,作为后续增强项。
  • F11 与浏览器级全屏:F11/浏览器菜单全屏不写 document.fullscreenElement,不进入放映,页面仍是带侧栏和缩略图的预览;浏览器级快捷键不能被页面可靠拦截。进入放映由页面内“进入放映”按钮或 F 键触发(两者都要求 Runtime 窗口内的用户手势)。
  • 演讲遥控器:观众窗口只读,演示遥控器需要把按键发送到控制台窗口;如果必须让观众窗口响应,另行设计转发,不恢复第二个调度器。
  • 协议版本:增加状态/命令可能要求升级演讲同步协议版本;双窗口同构建版本,需同步更新协议测试和双窗口证据。
  • 既有预期变化:全屏预览带侧栏/缩略图的行为被移除;空白键在放映态含义改变;用户文档和旧截图需要更新。
  • 旧产物兼容:不带 playback 配置的旧 artifact 仍可进入全屏,但控制条只显示“当前项目未启用放映配置”和退出,不渲染上一页/下一页与自动/手动按钮,翻页依赖方向键/PageUp/PageDown;预览态控件在全屏时已隐藏。需要重新构建产物才能获得完整控制条和自动/手动切换。
  • 浏览器范围:继续以桌面 Chromium 为验收目标;Firefox/WebKit 和移动端不作为本次支持承诺。

10. 已采纳决策与待确认项 ​

已采纳:

  • 非全屏 = 预览,全屏 = 放映;退出全屏结束放映。
  • 进入全屏即启动会话;auto_start 决定初始自动/手动,不再决定“是否开始”。
  • 自动/手动是本次放映的运行时状态,不写回 Backend。
  • 手动不是暂停:媒体继续,只停止页面自动推进。
  • 自动切手动取消计时;手动切自动时 timer 重新计一整轮,media_end 按媒体状态或回退停留处理。
  • manual 配置页在自动会话中仍手动;loop 只作用于自动推进。
  • 控制条以自动/手动为主操作,保留系统暂停后的“继续”。
  • 演讲者模式以观众窗口为唯一放映本体,控制台只发命令;观众窗口全屏且只读。
  • 预览工具栏保留“演讲”入口:从预览进入时观众窗口按 auto_start 起步;从放映控制条进入时继承当前自动/手动模式。
  • 不新增 runtimeMode、播放布局、Backend 字段或迁移。

实施时待确认(已决):

  • 无人值守/本地构建入口:直接打开构建链接仍是预览;需要用户点击全屏按钮,kiosk/自动化入口另行设计,WP31/WP33 已补充说明。
  • 演讲同步协议:升级到 v3,双窗口必须同构建版本;旧协议消息被拒绝。
  • 内容元素全屏:视频等页面内元素全屏期间放映继续,也不同步暂停推进;退出该元素全屏后 fullscreenElement 为空,按退出全屏结束放映并回到预览(Chromium 不恢复根全屏)。
  • 浏览器全屏:F11/菜单全屏不进入放映,也不被页面拦截;放映入口只有“进入放映”按钮。
  • Editor 引导:入口提示说明“在 Runtime 窗口点击进入放映”,不自动请求全屏。

11. 实施记录(2026-10-18) ​

  • P0:PlaybackController 增加会话级 autoAdvanceEnabled、setAutoAdvance、effectiveAdvanceMode;自动切手动取消计时但保留媒体,手动切自动按当前页重新计时/等待媒体,manual 配置页不因会话切换而自动推进;usePlaybackHost 暴露自动/手动切换与手动翻页。
  • P1:ResponsiveLayout 只在根元素全屏时挂载 PlaybackHostBridge;预览态隐藏控制条与全屏导航,全屏隐藏侧栏、缩略图、导出和旧翻页按钮;进入全屏即开始会话,auto_start 只决定初始自动/手动;空格由播放层独占,方向键由布局层处理,不拦截 F11(F11 仅为浏览器级全屏,不进入放映);控制条统一上一页、自动/手动、下一页、页码、状态、演讲与退出。
  • P2:演讲协议升级到 v3,播放快照增加 autoAdvanceEnabled,新增 set-auto-advance 命令;从放映进入时观众窗口继承当前页与自动/手动模式,必须根元素全屏后才开始放映,退出全屏立即暂停;观众页移除本地键盘,控制台传输栏合并翻页、自动/手动、状态与失败恢复,演讲计时保持独立;控制台传输栏按钮在观众全屏前禁用,键盘命令不受该门禁限制(由观众侧对 start/resume 做全屏门禁,其余命令在未启动时被吸收)。
  • P3:Editor 项目设置文案改为“进入放映后自动推进”,页面入口说明需在 Runtime 窗口点击进入放映;同步更新契约、Runtime、Editor、用户文档与 WP31/WP33 入口说明。
  • 自动化验证:Runtime 全量 143 个测试文件、1121 通过、3 跳过;vue-tsc -b 通过;改动文件 ESLint 通过。新增虚拟时钟用例覆盖自动/手动切换、媒体继续、手动页不自动、暂停切换与循环边界;组件测试覆盖预览无控制条、全屏进入/退出、控制条命令、工具栏按钮聚焦时方向键翻页、演讲协议 v3、观众全屏门禁与模式继承。
  • 真实浏览器验证(2026-10-18):有头 Chromium 148.0.7778.96(Playwright 1.60.0,Windows 10.0.26300 x64,1280×720),Runtime 开发服务 127.0.0.1:7373,路由拦截注入 3 页配置(timer 1500ms、手动页、autoStart: true)。node .tmp/fullscreen-playback/verify.mjs 共 38/38 项通过:预览无控制条且不推进;进入全屏即放映、自动剩余时间、自动↔手动切换、手动页不推进、空格与方向键归属、退出全屏回预览且无后台推进、重新进入从当前页开始;演讲者模式控制台/观众唯一调度、观众继承手动模式、控制台切换自动/手动、观众键盘无效、观众退出全屏暂停并需重新全屏后显式继续、退出演讲回预览。证据为 .tmp/fullscreen-playback/evidence.json 与截图 01–09。真实浏览器验证发现并修复了“工具栏按钮聚焦时方向键被吞掉”的回归,并补充组件用例。未验证:观众窗口的 getScreenDetails 多屏授权路径(脚本使用“当前窗口全屏”回退)、Firefox/WebKit、移动端;性能与长稳旧证据仍基于窗口化自动开始,全屏入口的无人值守时长未重新累计。
  • 2026-10-18 追加:全屏控制条默认收起,指针进入窗口底部 120px 唤出区域时淡入、移开即隐藏;暂停、错误、受阻、结束态与无放映配置的旧产物保持显示,键盘聚焦时同样唤出。组件测试新增 1 项覆盖(PlaybackHostBridge.test.ts 5 项通过);未重跑真实浏览器 38 项。
  • 2026-10-18 追加:预览右侧工具栏恢复“演讲”入口,Shift+P 在预览与全屏均可用;预览入口没有本地放映会话,观众窗口按项目 auto_start 起步。布局测试新增 1 项覆盖预览入口打开观众窗口并携带 auto 参数(ResponsiveLayout.test.ts 9 项通过)。

12. 复核勘误与设计约定(2026-10-18) ​

评审复核发现两处文档与实现不一致,已按实际实现更正;两项交互确认为设计意图,补充说明以便后续维护:

  • F11 不是放映入口:原 §3.2/§5.3 写“F11/菜单全屏同样视为进入放映”,实际浏览器级全屏不写 document.fullscreenElement,isFullscreen 保持 false,只得到带预览控件的窗口全屏。已更正为“不拦截、也不进入放映”。
  • 退出元素全屏会结束放映:原用户文档写“退出元素全屏后返回放映”,实际 Chromium 退出元素全屏后 fullscreenElement 为空,handleFullscreenChange 按退出全屏处理。已更正为“元素全屏期间继续放映,退出后结束并回预览”。
  • 重开的观众窗口不继承临时模式:openDisplayWindow() 只带当前页,不带 autoAdvance,因此重开的观众窗口按项目 auto_start 初始化;控制台随后按观众回执刷新自动/手动显示。这是设计意图:观众窗口始终以构建产物配置为基准,避免跨窗口残留状态。
  • 控制台键盘不受观众全屏门禁限制:传输栏按钮在观众窗口未全屏时禁用,但控制台方向键/空格仍向已连接的观众发送命令。这是设计意图:演讲者无需先聚焦按钮即可操作;观众侧对 start/resume 要求全屏,其余命令在放映未启动时被吸收。