Fix/windows multi window run output leak - #413
Conversation
按窗口标签区分运行进程会话,并将 run-output/run-exit 事件定向投递到发起窗口,避免多开项目时输出混入其他窗口。 Fixes 1lck#408 Co-authored-by: Cursor <cursoragent@cursor.com>
|
@lithe review |
Lithe Review结论: ✅ 未发现明确问题 LGTM 验证
|
| if !chunk.is_empty() { | ||
| let _ = app.emit( | ||
| let _ = app.emit_to( | ||
| &window_label, |
There was a problem hiding this comment.
[P0] windows/tauri/src-tauri/src/run.rs:1474
这里改成 emit_to(&window_label, ...) 方向是对的,但单靠它可能还关不掉 #408 的串窗输出。
触发场景:两个项目窗口都挂了 listen("run-output") / listen("run-exit")(见 use-run-process-events.ts、use-maven-process-events.ts)。Tauri 2 里这种全局 listen 默认 target 是 EventTarget::Any;后端 emit_to 时,Any 监听仍会被命中,所以 B 窗口仍可能收到 A 窗口的输出。
影响:会话复合键能避免进程互踩,但用户看到的「输出串到其他窗口」很可能还在。
建议:前端改成窗口作用域监听,和 menu 事件同一套做法,例如:
const window = getCurrentWebviewWindow();
await window.listen("run-output", ...)
await window.listen("run-exit", ...)use-run-process-events.ts 和 use-maven-process-events.ts 都要改。后端 emit_to + 复合键建议保留。
| } | ||
| let _ = app.emit( | ||
| let _ = app.emit_to( | ||
| &window_label, |
There was a problem hiding this comment.
[P0] windows/tauri/src-tauri/src/run.rs:1538
run-exit 同样走 emit_to,会踩和上面 run-output 一样的问题:全局 listen("run-exit") 在 Any target 下仍会收到定向事件,非发起窗口可能错误地 finishProcess。
建议与 output 一并改成 getCurrentWebviewWindow().listen(...),两边保持对称。
| arguments: ["run", "."], | ||
| workingDirectory: "D:\\demo", | ||
| environment: {}, | ||
| windowLabel: "project-window", |
There was a problem hiding this comment.
[P1] windows/tauri/src/features/run/api/run-host-api.test.ts:33
这个测试能确认 invoke 带上了 windowLabel,对 API 契约有用,但盖不住 #408 的核心回归:多窗口下事件是否只进发起窗口。
现在 CI 全绿也说明不了串窗已修好(尤其是 listener 仍是全局 listen 时)。
建议补一条更贴场景的断言,例如 mock/验证 run、maven 的 listener 使用了当前 window label(或 WebviewWindow.listen)。手测两窗 run 也仍然值得做一次。
| pub struct RunProcessManager; | ||
|
|
||
| #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
| struct RunSessionKey { |
There was a problem hiding this comment.
[P3] windows/tauri/src-tauri/src/run.rs:43
RunSessionKey { window_label, session_id } 这个建模很干净,直接对准了多窗共用 "primary" 会互踩进程的根因,后续 debug 会话也可以按同一复合键扩展。这部分建议原样保留。
|
@Rangsh 看过这个 PR 了,整体方向是对的,不过 #408 的主症状我判断还没完全关上。 阻塞合并: 有。后端 做得好的地方: 验证缺口: 现有单测主要覆盖「参数带上了 windowLabel」和 key 相等性,钉不住多窗事件隔离。补完 listener 后,最好再手测一次:开两个项目窗,只在一个窗 run,确认另一个窗的 Run 面板保持安静。Windows CI 已经绿了,平台构建侧不用担心。 改完 listener 后我可以再帮看一轮。 |
将 use-run-process-events 与 use-maven-process-events 从全局 listen 改为 getCurrentWebviewWindow().listen,避免 Tauri EventTarget::Any 在多窗下仍接收 emit_to 事件。 补充 listener 窗口作用域单测,验证不会注册全局 listen。 Co-authored-by: Cursor <cursoragent@cursor.com>
|
@1lck 请你麻烦再审核一下最新的提交 |
1lck
left a comment
There was a problem hiding this comment.
@Rangsh 第二轮看过 bf842e07 了。
上次卡合并的点已经补上:use-run-process-events / use-maven-process-events 改成 getCurrentWebviewWindow().listen,和 emit_to(window_label)、会话复合键对上了;单测也断言了不会再走全局 listen。按 Tauri 2 的事件匹配规则,#408 那条串窗输出链路现在是闭环的。
未发现需要阻塞合并的问题。
值得保留的设计:RunSessionKey、host API 自动带 windowLabel、窗口级 listen,这三层是一套完整隔离,后续 debug 事件也可以直接复用。
剩余缺口主要是人工验证:Windows 上开两个项目窗,只在一个窗 run,确认另一个 Run 面板保持安静。Windows CI 这轮还在跑,合入前等它绿一下即可。PR 描述里的 Changes / Test plan 可以顺手补上 listener 相关文件(不阻塞)。
|
@Rangsh 未发现需要阻塞合并的问题。整体实现方向是合理的,建议保留现有的 |
|
已合入 |
Summary
修复 Windows 多开项目窗口时,运行/调试控制台输出串到其他窗口的问题(Fixes #408)。
根因有两处:
app.emit向所有 WebView 广播run-output/run-exit,每个窗口的监听器都会收到并写入本地 store。"primary"作为sessionId,后端进程会话以单一 ID 管理,后启动的窗口会覆盖或干扰先启动窗口的进程。本次改动:
(window_label, session_id)复合键隔离运行进程会话。run-output/run-exit改为emit_to(window_label, ...),仅投递到发起运行的窗口。windowLabel(Maven 任务复用同一 API,同步受益)。关联 Issue:#408
Changes
windows/tauri/src-tauri/src/run.rsemit_to定向事件投递windows/tauri/src/features/run/api/run-host-api.tswindowLabelwindows/tauri/src/features/run/utils/run-window-context.tswindows/tauri/src/features/run/api/run-host-api.test.tswindowLabelTest plan
cargo test --manifest-path windows/tauri/src-tauri/Cargo.toml run_session_keyscargo test --manifest-path windows/tauri/src-tauri/Cargo.toml run::tests::stdin_writebun test windows/tauri/src/features/run/api/run-host-api.test.tsNotes
debug_start_session)尚未在 Windows 端落地;本次修复覆盖 Issue 截图中的运行输出场景。调试器实现后建议采用相同的windowLabel+emit_to模式。Fixes #408