vscode的onwindowchange在整窗失焦时保存,onfocuschange在编辑器控件失焦(如切终端、标签页)时保存;前者触发条件更窄、稳定性差,后者覆盖更广、推荐优先使用。

VSCode 没有“窗口失去焦点时自动保存”的独立开关,files.autoSave 的 onWindowChange 模式才是对应行为——但它实际触发条件比直觉更窄,且在多数场景下不如 onFocusChange 可靠。
onWindowChange 和 onFocusChange 到底差在哪
两者都依赖系统焦点事件,但监听粒度不同:
- onWindowChange 只在**整个 VSCode 窗口**(不是编辑器标签页)失去或获得系统焦点时触发,比如你 Alt+Tab 切出 VSCode、或点击桌面其他应用窗口
- onFocusChange 监听的是**当前编辑器控件**的焦点状态,比如你在同一个 VSCode 里点到终端面板、切换到另一个 .ts 文件标签、甚至用鼠标点进搜索框,都会触发保存
- 实测中,onWindowChange 在 macOS 上最小化窗口不触发,在 Windows 上被某些全屏应用(如游戏、Zoom)抢占焦点时也可能漏掉
为什么 onWindowChange 经常“看起来没生效”
常见失效原因不是配置错,而是触发条件未满足:
- 当前 VSCode 是多窗口模式(比如开了两个独立窗口),onWindowChange 只对“当前窗口”有效,切到另一个 VSCode 窗口不算“失去焦点”,只是窗口间切换
- 远程开发(SSH/WSL)下,宿主系统对“窗口焦点”的上报不稳定,onWindowChange 触发概率明显下降
- 文件本身是只读、未命名(Untitled-1)、或路径匹配了 files.exclude,VSCode 会直接跳过保存逻辑,不报错也不提示
- 同时启用了 editor.formatOnSave 但格式化插件失败(如 Prettier 缺少配置或依赖),VSCode 会回滚本次保存,表现为“编辑后切走,再回来发现没保存”
如何正确配置 onWindowChange 模式
如果你确实需要该模式(例如仅在彻底离开 VSCode 时才保存),按以下步骤操作:
- 打开设置(Ctrl+, 或 Cmd+,),搜索 files.autoSave
- 从下拉菜单中选择 onWindowChange(注意拼写,不是 onWindowLostFocus 或其他变体)
- 检查右下角是否显示「工作区」,如果是,切换到「用户」设置标签页,确认没有被工作区配置覆盖为 off
- 不需要额外配延迟值——onWindowChange 是即时触发,files.autoSaveDelay 对它无效
- 若需排除特定文件类型(如临时生成的 .log),在 settings.json 中加 language-specific 配置:
{ "files.autoSave": "off" } 放在对应语言块内更推荐用 onFocusChange 替代 onWindowChange
除非你明确要求“只在完全离开 VSCode 时保存”,否则 onFocusChange 更贴近真实工作流:
- 它覆盖了绝大多数“想保存”的瞬间:切终端、查文档、回微信、甚至只是点一下侧边栏图标
- 在远程环境和多显示器场景下稳定性更高
- 不受文件是否已命名限制(onWindowChange 对 Untitled 文件完全不生效)
- 如果担心太频繁,可搭配 files.autoSaveDelay 使用——但注意:这个 delay 只对 afterDelay 生效,onFocusChange 始终是立即保存,无法加延迟
真正容易被忽略的一点:VSCode 的焦点判断基于原生 GUI 事件,不是键盘/鼠标坐标。当你用快捷键(如 Ctrl+` 呼出终端)切换面板时,onFocusChange 能捕获,但 onWindowChange 完全无反应。











