1 🥱 WSL 的 GUI 为什么总是卡卡的?
在wsl2里用 WSLg 时打开带界面的软件时候,很容易产生一种奇怪的感觉:软件确实打开了,也能正常操作,但总觉得没有 Windows 原生应用那么顺。🤔
窗口拖动偶尔发黏,滚动不够跟手,最大化和还原时会停顿,部分软件的字体还有些模糊。更麻烦的是,同一个 WSL 环境里,不同软件的表现可能完全不同。
我也发现,例如我之前做过机器人相关的项目,打开Gazebo这样的应用时候 发现用起来比较自然,某些 Electron 软件却会出现缩放异常、点击位置不准,甚至最大化之后卡死(我这里因为不想要Windows下的vscode去开发wsl2下的东西,特意安装wsl2的linux版本的vscode去用发现的问题)。
然后怎么解决?
🎉🎉🎉 用这个 XDG_SESSION_TYPE=wayland 模式启动code(例如 XDG_SESSION_TYPE=wayland code .这类应用就会发现流畅太多了,日常开发完全够用了,甚至鼠标的跟手了, 但是没有办法解决这两个问题 => [跳转到 2.3 节](#跳转到 2.3 节 "###2.3")
- 和主机window的缩放保持一致,例如我电脑用125%做显示,但是它打开的应用不会是125的
- 最大最小化次数多之后 软件会卡死

然后就带着这样的问题找 ChatGPT 去问咯: 它给出的结论是: 不是"WSL 性能不好",而是图形显示链路比较长,而且不同应用走的链路并不一样。
2 背书的知识
2.1 🥹 WSLg 不是一个普通的 Linux 桌面
WSLg 的作用,是把运行在 WSL 里的 Linux GUI 程序显示到 Windows 桌面上。
它不是完整的 GNOME、KDE 或 XFCE 桌面,也不是简单地在 Windows 里嵌入一块 Linux 屏幕。更接近一种图形转发和窗口集成方案。
大致流程可以理解为:
text
Linux GUI 应用
↓
Wayland 或 X11
↓
WSLg 内部的 Weston
↓
RDP 图形通道
↓
Windows 桌面
这里最容易混淆的是 WSLg、Wayland、X11 和 XWayland。
- WSLg:整套图形集成系统;
- Wayland:较新的 Linux 图形协议;
- X11:较老的 Linux 图形协议;
- XWayland:兼容层,让 X11 程序跑在 Wayland 环境里。
所以一个软件可能直接走:
text
应用 → Wayland → Weston → Windows
也可能走:
text
应用 → X11 → XWayland → Weston → Windows
第二条链路多了一层转换。正常情况下未必有明显问题,但遇到 125% 这类分数缩放时,差异就容易暴露出来。
2.2 🙋♂️ 为什么有些软件舒服,有些软件卡
不同 GUI 框架对 Wayland、分数缩放和高 DPI 的支持程度并不相同。
Gazebo 的界面主要基于 Qt。Qt 对高 DPI、窗口尺寸和缩放比例的处理相对成熟,所以在 WSLg 中通常表现得比较自然:
- 字体清楚;
- 窗口尺寸正常;
- 点击位置准确;
- 调整窗口时相对稳定。
Electron 软件的情况更复杂。
Electron 内部包含 Chromium,显示链路大致是:
text
Electron 应用
↓
Chromium / Ozone
↓
Wayland 或 X11
↓
WSLg
↓
Windows
软件是否选择原生 Wayland,不只取决于系统里有没有 WAYLAND_DISPLAY,还可能取决于 Electron 版本、应用启动参数和环境变量。
WSLg 通常会同时提供:
bash
echo "$DISPLAY"
echo "$WAYLAND_DISPLAY"
可能得到:
text
:0
wayland-0
这表示 X11 和 Wayland 两条路线都存在。
但两条路都存在,不代表应用一定会选择更合适的那一条。
2.3 ✨ XDG_SESSION_TYPE=wayland 为什么会感觉更舒服
有些 Electron 软件直接启动时,可能默认选择 X11,然后通过 XWayland 运行。
链路类似:
text
Electron
↓
X11
↓
XWayland
↓
Weston
↓
Windows
如果在命令前加上:
bash
XDG_SESSION_TYPE=wayland 应用命令
相当于告诉应用:
text
当前环境应该被当作 Wayland 会话处理。
它不会创建一个新的 Wayland,也不会把 WSLg 从 X11 切换成 Wayland。
Wayland 本来就在运行。
这个变量只是影响应用自己的判断,让 Electron、Qt 或 GTK 更倾向于选择原生 Wayland 后端。
链路可能因此变成:
text
Electron
↓
Wayland
↓
Weston
↓
Windows
少了一层 XWayland 转换后,常见改善包括:
- 鼠标点击更准确;
- 滚动更跟手;
- 字体边缘更自然;
- 菜单和弹窗位置更稳定;
- 窗口拖动时的迟滞感减轻。
即使界面没有变大,仍然可能感觉"舒服很多"。
因为 Wayland 和 125% 缩放是两件不同的事。
text
Wayland:决定窗口走哪条显示链路
125% 缩放:决定逻辑像素如何映射到物理像素
所以:
bash
XDG_SESSION_TYPE=wayland
并不等于:
text
缩放比例 = 125%
出现"操作顺了,但大小没有变化"并不矛盾。
如果确认当前环境里已经有:
bash
echo "$WAYLAND_DISPLAY"
输出类似:
text
wayland-0
可以在 ~/.bashrc 里写得稍微稳一点:
bash
if [ -n "$WAYLAND_DISPLAY" ] && [ -z "$XDG_SESSION_TYPE" ]; then
export XDG_SESSION_TYPE=wayland
fi
如果只是想让 VS Code 这类 Electron 应用更倾向 Wayland,也可以单独写:
bash
alias code='code --ozone-platform=wayland'
不过是否更稳定,还是要看具体 Electron 版本。
2.4 🖥️ WSL GUI 卡顿不一定都是显示问题
图形链路只是其中一部分。
另一个常见问题,是 Windows 环境过多地进入了 WSL。
默认情况下,WSL 会把 Windows 的 PATH 追加到 Linux 的 PATH 中。
在 WSL 里执行:
bash
echo "$PATH"
可能看到很多类似路径:
text
/mnt/c/Windows/System32
/mnt/c/Program Files/...
/mnt/c/Users/用户名/AppData/Local/...
这很方便,因为可以直接调用:
bash
explorer.exe
notepad.exe
powershell.exe
但也会带来环境混用。
比如同时存在:
text
Linux 版 node
Windows 版 node.exe
Linux 版 code
Windows 版 code.cmd
Linux 版 git
Windows 版 git.exe
这不一定直接导致 GUI 掉帧,但会让整个 WSL 环境变得不干净,排查问题时也更麻烦。
3 🤖 关闭 Windows PATH 注入,让 WSL 更像 Linux
如果目标是让 WSL 尽量像一个独立 Linux 环境,可以关闭 Windows PATH 自动注入。
编辑:
bash
sudo nano /etc/wsl.conf
加入:
ini
[interop]
appendWindowsPath = false
保存后,在 Windows PowerShell 中执行:
powershell
wsl --shutdown
重新进入 WSL,再检查:
bash
echo "$PATH"
如果配置生效,/mnt/c/Windows/...、/mnt/c/Program Files/... 这类路径就不会自动出现在 PATH 里了。
这个设置不会完全关闭 Windows 互操作能力。你仍然可以用完整路径调用 Windows 程序,例如:
bash
/mnt/c/Windows/explorer.exe .
只是它们不会再自动混进 Linux 的命令搜索路径里。
之后可以用这些命令确认当前调用的是哪个版本:
bash
which git
which node
which python
which code
这一步和显示关系不大,但它能让环境更干净,减少很多莫名其妙的问题。
4 🤔 应该学着判断wslg的卡顿
WSL GUI "卡卡的",通常不是单一性能问题,而是这些因素叠加:
text
GUI 框架
+
Wayland / XWayland
+
Windows 分数缩放
+
Electron 兼容性
+
PATH 混用
+
项目是否在 /mnt/c
我的经验是:
- Qt 软件通常比较稳;
- Electron 软件要具体测试;
XDG_SESSION_TYPE=wayland可能让操作更顺;- 125% 分数缩放不一定适合所有程序;
- 不要期待一个全局参数解决所有 GUI 问题;
- 想让 WSL 干净一点,可以关闭 Windows PATH 注入;
- 大型项目尽量放在 Linux 文件系统里。
🆗🆗 最后都希望 希望大家愉快的使用wslg吧