diff --git a/README.md b/README.md index 8ffff2d..7c3790b 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ npm run dist:win -- --config.win.signAndEditExecutable=false | `R` | 回到顶部 | | `↑` / `↓` | 快速滚动页面 | | `←` / `→` | 调节滚动速度 | -| `Esc` | 关闭第二屏输出窗口(仅桌面版) | +| `Esc` | 关闭第二屏输出(仅桌面版,主窗口或第二屏中均可);未开第二屏时停止播放 | ## 开发检查 diff --git "a/docs/\346\233\264\346\226\260\346\227\245\345\277\227-6.6.md" "b/docs/\346\233\264\346\226\260\346\227\245\345\277\227-6.6.md" index 36d8a8f..17e3951 100644 --- "a/docs/\346\233\264\346\226\260\346\227\245\345\277\227-6.6.md" +++ "b/docs/\346\233\264\346\226\260\346\227\245\345\277\227-6.6.md" @@ -2,6 +2,10 @@ 6.6 版本起 Tauri 版成为主力维护的全平台版本,支持 Windows、macOS 和 Linux;Electron 版保留为 Windows 备用版本。 +## 6.6.1 + +- 修复开启第二屏后按 `Esc` 退出不稳定的问题。之前只有键盘焦点在第二屏窗口时 `Esc` 才会关闭第二屏,而打开第二屏后焦点通常交回主窗口(macOS 上落在哪个窗口不确定)。现在开启第二屏时,在主窗口或第二屏中按 `Esc` 都能关闭第二屏,编辑稿件时同样生效,且不改变播放状态;未开第二屏时 `Esc` 仍为暂停播放。 + ## 6.6.0 ### 全平台支持 diff --git a/tauri/web/index.html b/tauri/web/index.html index 15d3cc8..293268e 100644 --- a/tauri/web/index.html +++ b/tauri/web/index.html @@ -2168,6 +2168,19 @@

准备一段稿件

} } + async function closeOutputWindowFromMain() { + if (!window.teleprompterBridge?.closeOutputWindow || outputTogglePending) { + return; + } + outputTogglePending = true; + try { + applyOutputStatus(await window.teleprompterBridge.closeOutputWindow()); + elements.stage.focus({ preventScroll: true }); + } finally { + outputTogglePending = false; + } + } + function startResize(event) { event.preventDefault(); resizing = true; @@ -2551,6 +2564,13 @@

准备一段稿件

} return; } + // 打开第二屏后键盘焦点通常留在主窗口(macOS 上焦点落在哪个窗口还不确定), + // 所以主窗口里按 Esc 也要能关闭第二屏;编辑稿件时同样生效 + if (event.key === "Escape" && outputActive) { + event.preventDefault(); + closeOutputWindowFromMain(); + return; + } // 只有正在输入文字的控件(文本框、下拉框)才把按键留给控件本身; // 按钮和滑块获得焦点时不拦截,让空格/R/F/方向键等全局快捷键始终可用 const shortcutTarget = event.target; diff --git "a/tauri/\345\212\237\350\203\275\344\273\213\347\273\215.md" "b/tauri/\345\212\237\350\203\275\344\273\213\347\273\215.md" index 612fdf3..c5ce22b 100644 --- "a/tauri/\345\212\237\350\203\275\344\273\213\347\273\215.md" +++ "b/tauri/\345\212\237\350\203\275\344\273\213\347\273\215.md" @@ -21,7 +21,7 @@ - `R`:回到顶部 - `↑ / ↓`:快速滚动页面 - `← / →`:调节滚动速度 - - `Esc`:在第二屏窗口中退出第二屏输出 + - `Esc`:关闭第二屏输出(主窗口或第二屏窗口中均可);未开第二屏时停止播放 ## 显示调节 @@ -46,7 +46,7 @@ - 第二屏只显示提词内容,不显示底部控制栏。 - 第二屏顶部显示更醒目的剩余字数。 - 中间指示线包含进度点,便于判断当前阅读位置。 -- 按钮再次点击可以关闭第二屏输出,第二屏窗口按 `Esc` 也可以退出。 +- 按钮再次点击可以关闭第二屏输出,在主窗口或第二屏窗口按 `Esc` 也可以退出。 - 关闭程序时会同步结束相关窗口和进程。 ## 主屏预览 diff --git a/tests/teleprompter.spec.js b/tests/teleprompter.spec.js index 16812bc..0462d79 100644 --- a/tests/teleprompter.spec.js +++ b/tests/teleprompter.spec.js @@ -537,3 +537,45 @@ test("output mode ignores playback keys and only handles Escape", async ({ page await page.keyboard.press("Escape"); await expect.poll(() => page.evaluate(() => window.__closeCalls)).toBe(1); }); + +test("Escape in the main window closes an open output window", async ({ page }) => { + await page.addInitScript(() => { + window.__closeCalls = 0; + window.teleprompterBridge = { + toggleOutputWindow: async () => ({ opened: true, displayCount: 2, outputWidth: 1280, outputHeight: 720 }), + closeOutputWindow: async () => { + window.__closeCalls += 1; + return { opened: false, displayCount: 2 }; + }, + sendState: () => {}, + onState: () => {}, + onOutputStatus: () => {}, + }; + }); + + await page.goto(appUrl); + await page.locator("#outputButton").click(); + await expect(page.locator("#outputButton")).toHaveAttribute("aria-pressed", "true"); + + // 播放中按 Esc 只关第二屏,不改变播放状态 + await page.keyboard.press("Space"); + await expect(page.locator("#playButton")).not.toHaveClass(/primary/); + await page.keyboard.press("Escape"); + await expect(page.locator("#outputButton")).toHaveAttribute("aria-pressed", "false"); + await expect.poll(() => page.evaluate(() => window.__closeCalls)).toBe(1); + await expect(page.locator("#playButton")).not.toHaveClass(/primary/); + + // 第二屏关闭后,Esc 恢复为暂停播放,不再调用关闭 + await page.keyboard.press("Escape"); + await expect(page.locator("#playButton")).toHaveClass(/primary/); + expect(await page.evaluate(() => window.__closeCalls)).toBe(1); + + // 编辑稿件时按 Esc 也能关闭第二屏 + await page.locator("#outputButton").click(); + await expect(page.locator("#outputButton")).toHaveAttribute("aria-pressed", "true"); + await page.locator("#toggleEditorButton").click(); + await page.locator("#scriptInput").focus(); + await page.keyboard.press("Escape"); + await expect(page.locator("#outputButton")).toHaveAttribute("aria-pressed", "false"); + await expect.poll(() => page.evaluate(() => window.__closeCalls)).toBe(2); +}); diff --git a/windows-electron/index.html b/windows-electron/index.html index 15d3cc8..293268e 100644 --- a/windows-electron/index.html +++ b/windows-electron/index.html @@ -2168,6 +2168,19 @@

准备一段稿件

} } + async function closeOutputWindowFromMain() { + if (!window.teleprompterBridge?.closeOutputWindow || outputTogglePending) { + return; + } + outputTogglePending = true; + try { + applyOutputStatus(await window.teleprompterBridge.closeOutputWindow()); + elements.stage.focus({ preventScroll: true }); + } finally { + outputTogglePending = false; + } + } + function startResize(event) { event.preventDefault(); resizing = true; @@ -2551,6 +2564,13 @@

准备一段稿件

} return; } + // 打开第二屏后键盘焦点通常留在主窗口(macOS 上焦点落在哪个窗口还不确定), + // 所以主窗口里按 Esc 也要能关闭第二屏;编辑稿件时同样生效 + if (event.key === "Escape" && outputActive) { + event.preventDefault(); + closeOutputWindowFromMain(); + return; + } // 只有正在输入文字的控件(文本框、下拉框)才把按键留给控件本身; // 按钮和滑块获得焦点时不拦截,让空格/R/F/方向键等全局快捷键始终可用 const shortcutTarget = event.target; diff --git "a/windows-electron/\345\212\237\350\203\275\344\273\213\347\273\215.md" "b/windows-electron/\345\212\237\350\203\275\344\273\213\347\273\215.md" index 99af31d..9aba707 100644 --- "a/windows-electron/\345\212\237\350\203\275\344\273\213\347\273\215.md" +++ "b/windows-electron/\345\212\237\350\203\275\344\273\213\347\273\215.md" @@ -23,7 +23,7 @@ - `R`:回到顶部 - `↑ / ↓`:快速滚动页面 - `← / →`:调节滚动速度 - - `Esc`:在第二屏窗口中退出第二屏输出 + - `Esc`:关闭第二屏输出(主窗口或第二屏窗口中均可);未开第二屏时停止播放 ## 显示调节 @@ -48,7 +48,7 @@ - 第二屏只显示提词内容,不显示底部控制栏。 - 第二屏顶部显示更醒目的剩余字数。 - 中间指示线包含进度点,便于判断当前阅读位置。 -- 按钮再次点击可以关闭第二屏输出,第二屏窗口按 `Esc` 也可以退出。 +- 按钮再次点击可以关闭第二屏输出,在主窗口或第二屏窗口按 `Esc` 也可以退出。 - 关闭程序时会同步结束相关窗口和进程。 ## 主屏预览 diff --git "a/\344\275\277\347\224\250\346\214\207\345\215\227.md" "b/\344\275\277\347\224\250\346\214\207\345\215\227.md" index a3ffa7d..c81a795 100644 --- "a/\344\275\277\347\224\250\346\214\207\345\215\227.md" +++ "b/\344\275\277\347\224\250\346\214\207\345\215\227.md" @@ -45,7 +45,7 @@ - 支持水平镜像和垂直镜像 - 顶部显示剩余字数 - 指示线上显示进度圆点 -- 按 `Esc` 可以退出第二屏 +- 在主窗口或第二屏中按 `Esc` 都可以退出第二屏 6.1 版本中,主窗口采用固定比例预览画布,主屏看到的换行、字号、指示线位置会尽量和第二屏一致。 @@ -106,7 +106,7 @@ - `←`:降低滚动速度 - `→`:提高滚动速度 - `Shift + ← / →`:更大幅度调节速度 -- `Esc`:第二屏窗口中退出第二屏;播放时停止播放 +- `Esc`:开启第二屏时关闭第二屏(在主窗口或第二屏中按都可以,不影响播放状态);未开第二屏时停止播放 编辑稿件时,方向键会优先用于文本编辑,不会触发提词器快捷操作。