如果你也在 Windows 上用 Codex 写代码、改 bug、跑自动化任务,大概率遇到过这个场景:Codex 正在终端里干活,你想用鼠标去旁边窗口复制一段报错,结果鼠标刚甩过去,终端窗口就自动弹到最前,焦点直接被抢走。更离谱的是在一些终端界面里,鼠标指针会被“锁”在终端区域,你明明在桌面上移动,它却按终端里的坐标响应,拖都拖不出来。
我前两个月把 Windows 上的 Codex 环境彻底重装了一遍,换掉了几个默认配置,又补上几个必装组件,这个“抢鼠标”的问题终于消失了。这篇文章就把完整方案写出来,包括环境怎么搭、窗口焦点怎么控制、任务怎么丢到后台跑、报错怎么查,给同样在 Windows + Codex + 鼠标这个组合里踩过坑的朋友一份能直接抄的作业。
1. 先拆解:Codex 在 Windows 上为什么“抢鼠标”
1.1 最常见的三种“抢鼠标”现场
你要先判断自己遇到的是哪一种,不然会走弯路。
第一种是窗口焦点被抢。Codex 在跑任务时,只要终端有新输出,Windows Terminal 就会被系统拉到前台。你前一秒还在浏览器里查文档,后一秒焦点就跳回终端,鼠标单击直接落在终端窗口里,相当于白点一下。
第二种是鼠标事件被截获。很多终端交互程序开启鼠标协议后,终端会进入“鼠标报告”模式,所有鼠标移动、点击、滚轮事件都被它吃掉。这时候你按下的滚轮不是在滚动页面,而是在操作终端的虚拟菜单,光标上下乱窜,非常像“鼠标被抢”。
第三种是桌面版的日志自动滚动。Codex 的 Windows 桌面版在输出内容时会实时刷新页面,如果你的鼠标恰好停在日志列表区,页面会跟着你的滚轮方向乱滚。你本来想选中一段内容,结果它自己跳走了。
这三种情况我都遇到过,最终解决方案不靠“抢回来”,而是让 Codex 尽量不要出现在会跟你抢鼠标的交互场景里。
1.2 根因不在鼠标,而在终端焦点模型
Windows 的窗口焦点模型和 macOS 不太一样,它更偏向“谁被激活谁就接管一切”。Codex 跑在终端里,终端窗口一旦出现在前台,就会把键盘和鼠标事件全部接管。
如果你还开了远程桌面,问题会更明显:鼠标在本地和远程窗口之间切换时,一旦远程窗口激活,本地鼠标要重新定位,那一刻你会觉得指针“卡”在远程屏幕上。
所以核心思路不是写一段脚本去反制抢焦点,而是从源头隔离:
- 把 Codex 放到独立的终端标签页里运行;
- 批量任务优先用非交互模式,不走交互界面;
- 把当前你要用鼠标操作的工作窗口“钉”在最上层;
- 在真正需要同时操作多台机器时,用无界鼠标这类工具物理隔离。
这套组合拳做完,鼠标就几乎不会再被 Codex 抢走了。
2. Windows Codex 环境搭建:这些组件一个都不能少
2.1 必装清单速览
先说结论。我在 Windows 上给 Codex 准备的组件如下,不是信仰,都是踩坑踩出来的。
| 组件 | 版本建议 | 作用 |
|---|---|---|
| WSL 2 + Ubuntu 22.04/24.04 | 22.04 稳 | 给 Codex 一个接近 Linux 的运行环境,避免 Windows 路径和权限的怪问题 |
| Windows Terminal | 商店最新版 | 多标签管理,配合焦点控制 |
| Node.js LTS | 20 或 22 | Codex CLI 依赖 Node 运行 |
| Codex CLI | npm 最新版 | OpenAI 官方终端版编码 agent |
| Git + Git Credential Manager | WSL 内 apt 安装 | Codex 提交代码、读仓库时必需 |
| PowerToys | 微软官方最新版 | Always on Top 等窗口管理能力 |
| AutoHotkey v2 | 2.0 以上 | 自定义焦点守卫脚本,可选但推荐 |
少装任何一个,后面都会在某个地方绕路。尤其是 WSL 和 Windows Terminal,很多“鼠标被抢”其实是因为 Codex 直接在 Windows 原生终端里跑,缺少了 Linux 那套稳定的进程隔离和终端行为。
2.2 WSL 和 Node 环境安装
先打开 PowerShell,以普通用户身份执行:
wsl --install -d Ubuntu-22.04 wsl --set-default Ubuntu-22.04 wsl -d Ubuntu-22.04重启电脑后进入 WSL,先更新系统包:
sudo apt update && sudo apt upgrade -y sudo apt install -y git curl build-essentialNode 环境我建议用 nvm 装,不要直接去 Windows 官网下载 Node 安装包。在 WSL 里用 nvm 的好处是版本可以随时切换,也不会跟 Windows 的 PATH 变量打架。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash source ~/.bashrc nvm install 22 nvm alias default 22 node -v npm -vCodex CLI 官方说 Node 18 以上就行,但我实测 20 和 22 的兼容性更稳,在 WSL 里跑不会出现莫名其妙的进程退出。如果你已经在 Windows 侧装了 Node,也建议在 WSL 里再装一份,两边互不影响,因为 Codex 最终运行在 WSL 内部。
2.3 Codex CLI 安装、登录与 config 初始化
在 WSL 终端里执行:
npm install -g @openai/codex codex --version首次运行时会自动生成~/.codex/config.toml,然后执行登录:
codex login登录流程会打开浏览器,回传授权码。如果你卡在登录后提示“codex windows设置未完成”,多半不是网络问题,而是你的终端环境变量没有正确继承。先在 WSL 里确认:
which codex然后把全局 npm bin 目录加到~/.bashrc:
echo 'export PATH="$PATH:$(npm prefix -g)/bin"' >> ~/.bashrc source ~/.bashrccodex windows设置未完成这个提示还有个常见来源:你是用管理员权限开的终端,导致 Codex 把配置写到了另一个用户目录。解决办法很简单:不要用管理员终端跑登录,关掉重开一个普通终端窗口再执行codex login。
登录成功后,编辑~/.codex/config.toml,我习惯把审批策略改成手动确认,避免 Codex 自作主张执行高风险命令:
model = "codex-latest" approval_policy = "on-request" sandbox_mode = "read-only"model这一项以你账号里实际可用的模型为准,别自己发明名字,否则后面会看到model is not supported之类的报错。sandbox_mode = "read-only"的意思是最开始只让它读代码,不直接改文件,等你确认没问题再放开。
如果你是桌面版用户,我建议桌面版只用来人工 review 结果,不要让桌面版作为主力跑批量任务。桌面版每次输出日志都会刷新界面,鼠标停在日志区就会被滚轮抢走体验很差,批量任务还是交给 CLI +codex exec更稳。
3. 让 Codex 彻底不碰鼠标的三套打法
3.1 首选方案:用 codex exec 跑后台任务
codex exec是 Codex CLI 的非交互模式。它不会进入那个会截获鼠标事件的终端界面,而是接收一段自然语言指令,跑完后把结果打印出来或写进日志文件。
以前我习惯直接敲codex进入交互 TUI,结果它一跑起来我就什么都干不了。现在我的做法是:
cd /mnt/c/Work/demo codex exec "给 README.md 补充安装说明,并检查 docker-compose.yml 里 redis 服务的内存限制有没有写错"如果你所在的目录不是 Git 仓库,加一个跳过检查的参数:
codex exec --skip-git-repo-check "把 scripts/report.py 改成鼠标点哪儿,哪儿就显示柱状图"任务比较长、不想一直盯终端时,直接丢到后台:
nohup codex exec \ --skip-git-repo-check \ "把 scripts/report.py 改成鼠标点哪儿,哪儿就显示柱状图" \ > /tmp/codex-task.log 2>&1 &命令最后的&会让 Codex 在 WSL 后台运行,终端马上回到可输入状态。想观察进度就看日志:
tail -f /tmp/codex-task.log这一步做对了,你的鼠标和操作系统就能在 Codex 干活的同时干你的事。Codex 既不占用交互窗口,也不截获鼠标事件,你甚至可以把 WSL 窗口最小化,它照样慢慢跑。
3.2 窗口和焦点层面:把 Codex 关进“专属标签页”
如果你确实需要用交互 TUI,那就给 Codex 单独开一个永久标签页,不要跟你正在编辑代码的窗口混在同一个页面里。
我在 Windows Terminal 里新建了一个 WSL 专用 profile,启动参数直接进/mnt/c/Work,这样每次打开都是固定的工作目录。重点是:这个 Codex 标签页平时放在后台,Codex 只在里面跑,不新建窗口,不从任务栏弹出来。
如果你用的是单个 Windows Terminal 窗口,又开了两个标签页,Codex 在标签 A 里运行时切到标签 B 去用鼠标,理论上不会抢焦点。但 Windows Terminal 默认会有一些“输出时滚动”“输入时切到前台”的行为,建议在设置里把这类自动焦点切换关掉。
实际操作上,最省事的办法是在 PowerToys 里开启 Always on Top,把你正在编辑的窗口钉在最上层。即使 Codex 终端偶尔跳到前台,它也只会在底下闪,你的编辑窗口依然可见,鼠标点击不会点错位置。
PowerToys 的 Always on Top 默认快捷键是Win+Ctrl+T,选中窗口后按一下就能钉住,再按一下取消。连续嵌套几个窗口时,钉住最常用的那个能明显降低“被 Codex 拉走注意力”的概率。
3.3 补充方案:AutoHotkey 焦点守卫和无界鼠标
如果前面的方案还不够,我用 AutoHotkey v2 写了一个简单的“焦点守卫”脚本。思路是:当 Codex 所在窗口自动获得焦点而鼠标并没有点击它时,把焦点还给上一个窗口。
示意代码如下:
#Requires AutoHotkey v2.0 #Persistent ; 我把 Codex 固定在 WindowsTerminal.exe 里 targetClass := "ahk_exe WindowsTerminal.exe" global prevHwnd := 0 ; 鼠标点击事件记录时间,用来判断当前焦点是不是用户主动点的 ~LButton:: { global lastClickTick := A_TickCount } SetTimer WatchFocus, 200 WatchFocus() { global lastClickTick, prevHwnd activeHwnd := WinGetID("A") activeExe := WinGetProcessName(activeHwnd) if (activeExe = "WindowsTerminal.exe") { ; 如果 300ms 内没有过鼠标点击,认为焦点是自动抢过来的 if (A_TickCount - lastClickTick > 300) { if (prevHwnd && WinExist("ahk_id " . prevHwnd)) WinActivate("ahk_id " . prevHwnd) } return } ; 当前不是 Codex 窗口时,记录成“上一个窗口” if (activeHwnd != prevHwnd) prevHwnd := activeHwnd }这段脚本并不是万能药,它需要在真实场景里调参。我的完整版里还加了一个白名单:如果鼠标真的在点击 Codex 窗口里某个按钮,300ms 内就能识别出来,不会强制把焦点抢走。核心思想不是“禁止 Codex 获得焦点”,而是“禁止它偷偷获得焦点”。
如果你的使用场景横跨两台 Windows 电脑,比如一台专门跑 Codex,一台专门做日常操作,那么可以试试微软 Garage 出品的无界鼠标(Mouse Without Borders)。它能用一套鼠标键盘控制最多四台电脑,Codex 跑在开发机上,你在这台办公机上用鼠标,从根本上就抢不到。
4. 常见问题、报错排查与配置速查
4.1 高频报错与解决办法
| 报错/现象 | 原因 | 解法 |
|---|---|---|
codex: command not found | WSL 里 PATH 没包含 npm 全局 bin | 把$(npm prefix -g)/bin加入~/.bashrc |
| 登录后提示“codex windows设置未完成” | 用了管理员终端或环境变量没继承 | 普通终端重新执行codex login,检查which codex |
the 'gpt-5.6-sol' model is not supported when using codex with a... | config.toml里的模型名写错 | 用codex --help或账号可用模型列表里的准确名字,不要自创模型名 |
| Codex 跑一会儿就退出 | 权限过高或终端冲突 | 别用管理员方式运行 WSL/Windows Terminal |
| 鼠标滚轮在 Codex 页面里乱跳 | 终端鼠标协议开启 | 改用codex exec,别进交互 TUI |
| 远程桌面里鼠标漂移 | 窗口焦点在本地/远程反复切换 | 在 WSL 里跑后台执行,不要用桌面版实时刷日志 |
4.2 把 Codex 接到 DeepSeek 的省钱配置(可选)
如果你不想只用 OpenAI 官方模型,Codex CLI 支持自定义模型 provider。我试过把 Codex 接到 DeepSeek,跑一些改脚本、补注释的轻量任务,成本确实低不少。
在~/.codex/config.toml里追加:
model = "deepseek-chat" model_provider = "deepseek" [model_providers.deepseek] name = "DeepSeek" base_url = "https://api.deepseek.com/v1" env_key = "DEEPSEEK_API_KEY"然后设置环境变量:
export DEEPSEEK_API_KEY="你的密钥"用之前要知道一个前提:DeepSeek 不是 OpenAI 官方模型,Codex 对工具调用和部分系统指令的适配不一定完整,适合写脚本、处理文本、改配置,不建议在重度全自动 agent 流程里硬上。换回来也很简单,把model改回官方模型名就行。
4.3 我的最终配置速查
每次重装系统后,我基本照着这个顺序走一遍:
1. wsl --install -d Ubuntu-22.04 2. 在 WSL 里安装 git、curl、build-essential 3. 用 nvm 安装 Node 22 4. npm install -g @openai/codex 5. codex login,普通终端运行 6. 编辑 ~/.codex/config.toml,设置 model / approval_policy / sandbox_mode 7. Windows Terminal 新建 WSL profile,固定工作目录 8. 安装 PowerToys,开启 Always on Top 9. 批量任务一律 codex exec + nohup 后台跑这一套跑下来,Codex 在旁边干活,我用鼠标继续写代码、查文档、刷网页,互不干扰。
我个人最后留了一个习惯:每次给 Codex 派任务前,先敲codex exec而不是codex,把交互 TUI 留给需要人工 review 的场景。这一个习惯改掉之后,鼠标被抢的次数基本归零。你如果也被这个问题烦了很久,不妨从这一步开始试。