环境:Windows 11 + WSL2 + WSLg 1.0.79,发行版为 Fedora 44,桌面为 XFCE,显示管理器为 LightDM。 目标:在 WSLg 里跑起一个「有登录界面、有窗口管理器、能用 GPU」的完整桌面,而不是只有一个孤零零的 X11 小程序。

本文以 X11(Xwayland + LightDM + XFCE) 为主线,把原理、配置、以及一路上踩过的坑都讲清楚;文章最后再附带聊聊 niri(Wayland) 的玩法,以及我为此给 Mesa 打的一个补丁。


0. TL;DR#

如果你只想快速复现,核心就四件事:

  1. 让 WSL 用 systemd 启动,并装好桌面环境 + 显示管理器;
  2. 用 wslg-fix.service 修 /tmp/.X11-unix,把 X0 软链到 /mnt/wslg/.X11-unix/X0;
  3. 把 /usr/bin/Xorg 换成一个调用 Xwayland 的包装脚本,让 LightDM 以为自己在启动 Xorg,实际起的是 Xwayland;
  4. 强制 GTK/Qt 走 X11 后端(GDK_BACKEND=x11),并设 GALLIUM_DRIVER=d3d12 让 X11 也能吃到 GPU。

剩下的都是排错。


1. 背景:WSLg 到底给了我们什么#

WSLg 的本质是:在 Windows 上跑一个 Weston(Wayland 合成器),再通过 RDP RAIL/VAIL 把每个窗口“远程”到 Windows 桌面里。它默认只提供:

  • 一个 Wayland socket(/mnt/wslg/runtime-dir/wayland-0);
  • 一个 X11 socket(/mnt/wslg/.X11-unix/X0,DISPLAY=:0);
  • 音频、剪贴板等集成。

它不是一个完整的桌面环境:没有登录管理器、没有窗口管理器(对 X11 而言)、没有一台“真的显卡设备”。

我们的目标,是在这套基础上“骗”一个完整的会话出来:

Windows 桌面
│ (RDP RAIL/VAIL,本地传输)
▼
WSLg: Weston (合成器)
│ Wayland socket
▼
Xwayland (我们让 LightDM 启动的“Xorg”)
│ X11
▼
LightDM → slick-greeter / XFCE(xfwm4, panel, apps)

关键点:LightDM 原本要启动真正的 Xorg,但 WSL 没有真实的 DRM/VT,真 Xorg 起不来。 于是我们用包装脚本把 Xorg 换成 Xwayland,让 X11 程序跑在一个嵌套的 Xwayland 里,再由 Weston 显示到 Windows。


2. 前置条件#

2.1 打开 systemd#

编辑 /etc/wsl.conf:

[boot]
systemd=true
[interop]
appendWindowsPath=false

改完在 Windows 侧执行 wsl.exe --shutdown,重新打开终端。

2.2 安装桌面与显示管理器(Fedora 为例)#

Terminal window
sudo dnf install -y \
xfce4-session xfwm4 xfce4-panel xfdesktop thunar \
lightdm slick-greeter \
xorg-x11-server-Xwayland

说明:lightdm-gtk-greeter 也能装,但它在 WSL 下更容易踩坑(见 §4.3)。这里我们直接用 slick-greeter。


3. 核心改造#

3.1 修复 /tmp/.X11-unix 并准备 X0#

WSLg 默认把 /tmp/.X11-unix 挂成只读,且里面没有 X0。我们创建一个 oneshot 服务,把它换成可写目录,并把 X0 软链到 WSLg 的共享目录:

Terminal window
sudo tee /etc/systemd/system/wslg-fix.service >/dev/null <<'EOF'
[Service]
Type=oneshot
ExecStart=-/usr/bin/umount /tmp/.X11-unix
ExecStart=/usr/bin/rm -rf /tmp/.X11-unix
ExecStart=/usr/bin/mkdir /tmp/.X11-unix
ExecStart=/usr/bin/chmod 1777 /tmp/.X11-unix
ExecStart=/usr/bin/ln -s /mnt/wslg/.X11-unix/X0 /tmp/.X11-unix/X0
ExecStart=/usr/bin/chmod 0777 /mnt/wslg/runtime-dir
ExecStart=/usr/bin/chmod 0666 /mnt/wslg/runtime-dir/wayland-0.lock
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl enable wslg-fix.service

⚠️ 坑:在 WSLg 1.0.79 上,umount /tmp/.X11-unix 有时会因“多层 tmpfs / Device or resource busy”失败,导致 rm 失败、服务起不来,Fedora 44是有一个tmpfs配置文件存在冲突的。可以:

  • 重启 WSL(wsl --shutdown)后再让它跑;
  • 或先手动 sudo umount -R -l /tmp/.X11-unix,再 sudo systemctl start wslg-fix.service;
  • 检查:journalctl -u wslg-fix.service -b 和 ls -l /tmp/.X11-unix/X0。

3.2 把 /usr/bin/Xorg 换成 Xwayland 包装脚本#

先备份真 Xorg,再写包装脚本:

sudo mv /usr/bin/Xorg /usr/bin/Xorg.original
sudo tee /usr/bin/Xorg.Xwayland >/dev/null <<'EOF'
#!/bin/bash
# 把 Xorg 的参数做一点适配,再转交给 Xwayland
for arg do
shift
case $arg in
# Xwayland 不支持 vtxx,转成 ttyxx
vt*) set -- "$@" "${arg//vt/tty}" ;;
# Xwayland 不支持 -keeptty / -novtswitch,丢掉
-keeptty) ;;
-novtswitch) ;;
*) set -- "$@" "$arg" ;;
esac
done
# Xwayland 需要一个指向 WSLg Weston 的 XDG_RUNTIME_DIR
if [ ! -d "$HOME/runtime-dir" ]; then
mkdir "$HOME/runtime-dir"
ln -s /mnt/wslg/runtime-dir/wayland-0 \
/mnt/wslg/runtime-dir/wayland-0.lock "$HOME/runtime-dir/"
fi
export XDG_RUNTIME_DIR="$HOME/runtime-dir"
# 选一个空闲显示号(注意:Xwayland 实际取最后一个 :N,见下方说明)
for displayNumber in $(seq 1 100); do
[ ! -e /tmp/.X11-unix/X$displayNumber ] && break
done
# 窗口模式:去掉 -fullscreen,给固定分辨率
command=("/usr/bin/Xwayland" ":${displayNumber}" "-geometry" "1600x900" "$@")
systemd-cat -t /usr/bin/Xorg echo "Starting Xwayland:" "${command[@]}"
exec "${command[@]}"
EOF
sudo chmod 0755 /usr/bin/Xorg.Xwayland
sudo ln -sf Xorg.Xwayland /usr/bin/Xorg

📌 实测结论:当命令行里出现多个 :N(包装脚本加的 :1 和 LightDM 传的 :0)时,Xwayland 绑定的是最后一个 :N。所以包装脚本前面的“空闲显示号”其实会被 LightDM 传进来的 :0 覆盖。

真正让整套方案跑通的是 §3.1 的 X0 软链:Xwayland 启动 :0 时会创建 /tmp/.X11-unix/X0,因为它是软链,socket 实际落在了 /mnt/wslg/.X11-unix/X0,从而被 WSLg 暴露给 Windows。

3.3 强制 GTK/Qt 走 X11#

这是整个方案里最容易踩、也最隐蔽的坑。

WSLg 会为每个用户会话创建 /run/user/<uid>/wayland-0 软链。即使你没有设置 WAYLAND_DISPLAY,GTK 的 Wayland 后端在默认情况下也会去找 wayland-0,一旦找到就直接用 Wayland 后端。于是:

  • 登录界面(lightdm-gtk-greeter / slick-greeter)是 X11-only 的程序 → 调 gdk_x11_* 时断言失败 → SIGSEGV 闪退;
  • XFCE 里的 GTK 程序也会跑到 Wayland 上,绕过 xfwm4,窗口没有边框、不被管理。

文章里常见的做法是改 user-runtime-dir@.service:

Terminal window
sudo mkdir -p /etc/systemd/system/user-runtime-dir@.service.d
sudo tee /etc/systemd/system/user-runtime-dir@.service.d/override.conf >/dev/null <<'EOF'
[Service]
ExecStartPost=-/usr/bin/rm -f /run/user/%i/wayland-0 /run/user/%i/wayland-0.lock
EOF
sudo systemctl daemon-reload

⚠️ 但在 WSLg 1.0.79 上,WSLg 会把 wayland-0 软链重新造回来,这条 rm 挡不住。所以我们改用更稳的方式:直接强制后端。

给 greeter 强制 X11#

sudo tee /usr/local/bin/slick-greeter-x11 >/dev/null <<'EOF'
#!/bin/bash
export GDK_BACKEND=x11
unset WAYLAND_DISPLAY
exec /usr/bin/slick-greeter "$@"
EOF
sudo chmod 0755 /usr/local/bin/slick-greeter-x11
sudo tee /usr/share/xgreeters/slick-greeter-x11.desktop >/dev/null <<'EOF'
[Desktop Entry]
Name=Slick Greeter (X11)
Comment=LightDM greeter forced to GDK X11 backend
Exec=slick-greeter-x11
Type=Application
EOF
sudo mkdir -p /etc/lightdm/lightdm.conf.d
sudo tee /etc/lightdm/lightdm.conf.d/50-greeter.conf >/dev/null <<'EOF'
[Seat:*]
greeter-session=slick-greeter-x11
EOF

给用户会话强制 X11 + 开 GPU#

X 会话会读取 /etc/X11/xinit/xinitrc.d/*,在这里注入环境最干净:

Terminal window
sudo tee /etc/X11/xinit/xinitrc.d/99-force-x11.sh >/dev/null <<'EOF'
# 强制 GTK/Qt 走 X11,绕过 WSLg 的 wayland-0
export GDK_BACKEND=x11
export QT_QPA_PLATFORM=xcb
# 让 Mesa 走 WSL 的 D3D12 后端(GPU: NVIDIA ...),而不是 llvmpipe
export GALLIUM_DRIVER=d3d12
# WSL 的 GPU 工具在 /usr/lib/wsl/lib
export PATH="$PATH:/usr/lib/wsl/lib"
EOF
sudo chmod 0755 /etc/X11/xinit/xinitrc.d/99-force-x11.sh

再给登录 shell 也补上(方便在终端里直接跑 GL 程序):

Terminal window
sudo tee /etc/profile.d/99-wsl-gpu.sh >/dev/null <<'EOF'
case ":$PATH:" in
*:/usr/lib/wsl/lib:*) ;;
*) export PATH="$PATH:/usr/lib/wsl/lib" ;;
esac
export GALLIUM_DRIVER=d3d12
EOF
sudo chmod 0644 /etc/profile.d/99-wsl-gpu.sh

3.4 让 LightDM 成为默认显示管理器#

Terminal window
sudo systemctl disable gdm 2>/dev/null
sudo systemctl enable lightdm
sudo systemctl set-default multi-user.target # 或 graphical.target,见下
sudo systemctl start lightdm

如果你希望开机自动进图形,用 graphical.target;如果想像文章那样“手动起”,就保持 multi-user.target,需要时:

Terminal window
sudo systemctl start graphical.target

4. 验证与排错#

4.1 确认 Xwayland 在跑、分辨率正确#

Terminal window
pgrep -a Xwayland
# 用 greeter/会话的 XAUTHORITY 查 :0
sudo xrandr --display :0 # 或在会话里 xrandr
# 期望看到 1600x900
# 包装脚本日志
journalctl -b -t /usr/bin/Xorg | tail

4.2 确认 GPU 真的用上了#

Terminal window
glxinfo -B | grep -E "renderer|Accelerated"
# 期望:D3D12 (NVIDIA GeForce RTX 4060) / Accelerated: yes
glmark2 -s 800x600 -b desktop
nvidia-smi

我们实测的数据(RTX 4060):

路径分辨率驱动Score
X11800×600llvmpipe(默认)156
X11800×600d3d12529
X111920×1080d3d12153
原生 Wayland800×600d3d12540
原生 Wayland1920×1080d3d12171

📌 别用 glxgears 判断 GPU:它默认开 vsync(锁 60Hz),而且负载太轻,CPU 都能 800+ FPS。要比性能用 glmark2,并且比较时一定用同一个 -s 分辨率——800×600 和 1080p 的像素量差 4 倍多,帧率会差 3~4 倍。

4.3 坑:greeter 一启动就闪退#

现象:/var/log/lightdm/lightdm.log 里反复出现

Greeter closed communication channel
Seat seat0: Stopping; failed to start a greeter
Display manager stopped ... Exiting with return value 1

seat0-greeter.log 末尾:

Gdk-CRITICAL: gdk_x11_window_get_xid: assertion 'GDK_IS_X11_WINDOW (window)' failed

dmesg:

lightdm-gtk-gre[xxxx]: segfault at ... in libX11.so.6

根因:不是 lightdm 崩,而是 greeter 崩。而且根因是 GDK 选了 Wayland 后端(见 §3.3):greeter 是 X11-only 程序,拿到的 window/display 不是 X11 对象,随后把野指针传给 XInternAtom → SIGSEGV。

解决:按 §3.3 用 GDK_BACKEND=x11 包装 greeter。lightdm-gtk-greeter 和 slick-greeter 都会中招,任选其一 + 包装脚本即可。

4.4 坑:登录后窗口没有边框、没有最小化/最大化/关闭#

根因:XFCE 的窗口管理器 xfwm4 没启动。检查:

Terminal window
pgrep -a xfwm4 # 没有输出就是没起

~/.xsession-errors 开头会有:

Failed to fetch _NET_NUMBER_OF_DESKTOPS; assuming 1
Failed to get _NET_WORKAREA; using full screen dimensions

这些 _NET_* 都是窗口管理器设置的——没有它,自然没有标题栏。

原因:~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml 里 SessionName=Default,但 Failsafe 的 Client*_Command 被写空,导致 xfce4-session 没有拉起 xfwm4。

解决(重置会话配置 + 兜底自启动):

Terminal window
# 备份并移走有问题的会话配置,改用系统默认 Failsafe(第一个客户端就是 xfwm4)
mv ~/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml \
/tmp/xfce4-session.xml.orig
# 清空会话缓存
rm -rf ~/.cache/sessions/*
# 兜底:在 autostart 里显式启动 xfwm4
mkdir -p ~/.config/autostart
cat > ~/.config/autostart/xfwm4.desktop <<'EOF'
[Desktop Entry]
Type=Application
Name=Xfwm4
Comment=Xfce Window Manager
Exec=xfwm4 --replace
Terminal=false
NoDisplay=true
EOF

注销重登后 pgrep xfwm4 应该有输出,窗口也就有边框和按钮了。

4.5 坑:会话里 nvidia-smi: command not found#

WSL 的 GPU 工具在 /usr/lib/wsl/lib/,但 LightDM 给会话的 PATH 很精简(可能只有 /usr/local/bin:/usr/bin),所以找不到。两条一起做:

Terminal window
# 立刻可用
sudo ln -sf /usr/lib/wsl/lib/nvidia-smi /usr/local/bin/nvidia-smi
# 登录 shell 也补上 PATH(见 §3.3 的 /etc/profile.d/99-wsl-gpu.sh)

4.6 坑:整个桌面是全屏,想窗口化#

改包装脚本里的 -geometry 和 -fullscreen:

Terminal window
# 原来: Xwayland ... "-geometry" "1920x1080" "-fullscreen" ...
# 改成: Xwayland ... "-geometry" "1600x900" ...

然后 sudo systemctl restart lightdm。想改回全屏就把 -fullscreen 加回去。

注意:这是嵌套式 Xwayland,整个桌面是一个 X 窗口。缩放外层 Windows 窗口时,X 根分辨率不一定跟着变;要换分辨率就改 -geometry 重启。

4.7 坑:GDM/GNOME 方案在 Fedora 44 上是死路#

之前参考的网上一篇文章(“在 wsl2 中使用 wslg 实现完整桌面环境”)是用 GDM + GNOME(Ubuntu 24.04) 演示的。它能把 /usr/bin/Xorg 换成 Xwayland,是因为 GDM 当时会用 Xorg 起 greeter。

但在 Fedora 44 / GNOME 50 上:

  • gnome-shell --help 里已经没有 --x11,GNOME 50 是 Wayland-only;
  • /usr/share/xsessions/ 里不再有 GNOME 的 X11 会话;
  • GDM 的 greeter 就是 gnome-shell --mode=gdm,只能跑 Wayland;
  • 而 Wayland greeter 需要 DRM/KMS,WSL 的 /dev/dri 是假的 vgem(/devices/faux/vgem/...)→ 直接失败:
Running GNOME Shell ... as a Wayland display server
MESA-EGL: warning: egl: failed to create dri2 screen
MESA-EGL: warning: NEEDS EXTENSION: falling back to kms_swrast
org.gnome.Shell@gdm.service: Failed with result 'protocol'
GdmDisplay: Session never registered

WaylandEnable=false 也救不了(因为 greeter 本身没有 X11 模式了)。所以 Fedora 44 上请走 LightDM + X11 桌面(XFCE 等)。


5. 原理补充:为什么 WSL 下 X11/Wayland 都“没有真 GPU”#

这是理解后面所有现象的关键。

  • WSL 里的 /dev/dri/card0 / renderD128 来自 faux vgem:

    Terminal window
    cat /sys/class/drm/card0/device/uevent
    # DRIVER=faux_driver
    udevadm info -q property /sys/class/drm/renderD128 | grep DEVPATH
    # DEVPATH=/devices/faux/vgem/drm/renderD128

    它们不是真正的 GPU 设备,所以依赖 DRM/KMS/GBM 的东西(真 Xorg、GNOME Wayland greeter、glamor、dmabuf)都会失败或回退。

  • 真正的 GPU 通过 /dev/dxg(dxgkrnl) 暴露,Mesa 用 d3d12 gallium 驱动访问它(配合 /usr/lib/wsl/lib 里的 libd3d12core.so / libdxcore.so)。

  • 因此:

    能力状态
    真 DRM render node❌(faux vgem)
    EGL_EXT_device_drm❌
    dmabuf 零拷贝❌(Wayland 走 wl_shm;Xwayland glamor 退软件)
    d3d12(GPU 渲染)✅ 需 GALLIUM_DRIVER=d3d12
    CUDA(nvidia-smi)✅ 通过 /dev/dxg
  • 所以你会看到这类“警告”,它们都是能力降级,不是错误:

    Xwayland glamor: GBM Wayland interfaces not available
    Failed to initialize glamor, falling back to sw

    以及 Wayland 侧 niri 的:

    failed building default dmabuf feedback, falling back to v3:
    error getting EGL device render node
    EGL_EXT_device_drm ... at least one is required

    影响:普通 2D 桌面无感;3D/高帧率会有“显存→内存”的额外拷贝开销;依赖 DRM 枚举/零拷贝的功能(多 GPU 选择、DRM leasing、部分录屏)受限。这些都不是配置错误,换到有真 /dev/dri/renderD128 的裸机/虚拟机就消失了。


6. 附带:niri 方案(Wayland)#

如果你想要更现代、更流畅的平铺式体验,也可以直接在 WSLg 里跑 niri(一个用 Rust 写的滚动平铺 Wayland 合成器)。

6.1 基本玩法#

niri 以 winit 嵌套后端 运行在 WSLg 的 Weston 里:

Terminal window
# 你的 shell 里需要有指向 WSLg Weston 的 Wayland 环境
# (WSLg 登录会话通常已经设好 WAYLAND_DISPLAY=wayland-0 / XDG_RUNTIME_DIR=/run/user/1000)
niri --session

niri 自己会监听 wayland-1(给它启动的客户端)和 X11 socket(通过 xwayland-satellite)。它的外层窗口由 winit 创建,因为 WSLg 不提供服务端装饰(没有 zxdg_decoration_manager_v1),所以窗口边框是 CSD(客户端自绘)——这也是为什么 niri 的窗口看起来有边框,而 sway 没有。

6.2 坑:点“最大化”时 niri 闪退#

现象:niri 外层窗口点标题栏最大化,niri 偶尔/经常 SIGSEGV:

niri[xxxx]: segfault at 40 ... in libEGL_mesa.so.0.0.0[...]
niri.service: Main process exited, code=killed, status=11/SEGV

根因:WSLg 没有 dmabuf,Mesa 只能走 Wayland 软件呈现路径。resize 的瞬间,dri2_surf->back 还没就绪,而 Mesa 里只有一句被 release 构建编译掉的 assert:

static void *
dri2_wl_swrast_get_backbuffer_data(struct dri2_egl_surface *dri2_surf)
{
assert(dri2_surf->back); // release 下无效
return dri2_surf->back->data; // back == NULL → [NULL+0x40] → SIGSEGV
}

(libEGL_mesa 里 dri2_wl_swrast_put_image2 调它,对应 platform_wayland.c 的 dst += y * dst_stride;。)

我们查了 Mesa 26.2.6 和 main,上游都还没修。于是我给它打了个补丁并重编 libEGL_mesa:

/* 1) 判空而不是 assert */
static void *
dri2_wl_swrast_get_backbuffer_data(struct dri2_egl_surface *dri2_surf)
{
if (!dri2_surf->back)
return NULL;
return dri2_surf->back->data;
}
/* 2) put_image2 里 back 没就绪就跳过这一帧 */
dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
if (!dst)
return;

效果:resize 时极端情况下丢一帧而不是崩溃(可能表现为轻微闪烁),最大化就稳定了。

6.3 编译与替换(简述)#

Terminal window
# 1. 装构建依赖(Fedora:用 mesa 的 spec 最省事)
sudo dnf builddep -y ./mesa.spec
# 2. 打补丁后,用 meson 只编 libEGL_mesa
meson setup build -Dprefix=/usr -Dbuildtype=release \
-Dplatforms=x11,wayland -Dgallium-drivers=softpipe \
-Dvulkan-drivers= -Dvulkan-layers= \
-Dgallium-rusticl=false -Dmicrosoft-clc=disabled \
-Dglx=dri -Degl=enabled -Dgles1=enabled -Dgles2=enabled -Dopengl=true \
-Dgbm=enabled -Dglvnd=enabled -Dllvm=disabled \
-Dbuild-tests=false -Dtools= -Dvideo-codecs=
ninja -C build src/egl/libEGL_mesa.so.0.0.0
# 3. 去掉 build 目录 RPATH(让它用系统的 libgallium),备份后替换
patchelf --remove-rpath build/src/egl/libEGL_mesa.so.0.0.0
sudo cp -a /lib64/libEGL_mesa.so.0.0.0 /lib64/libEGL_mesa.so.0.0.0.orig
sudo cp build/src/egl/libEGL_mesa.so.0.0.0 /lib64/libEGL_mesa.so.0.0.0

验证:

Terminal window
objdump -d /lib64/libEGL_mesa.so.0.0.0 | grep -A3 '450' # 应能看到 test %rax,%rax; je
glxinfo -B | grep -E "renderer|Accelerated" # D3D12 / yes

⚠️ 以后 dnf update mesa-* 会覆盖这个补丁,需要重新打。回滚: sudo cp -a /lib64/libEGL_mesa.so.0.0.0.orig /lib64/libEGL_mesa.so.0.0.0

6.4 niri 的日志里那些 warning 要不要管?#

MESA-EGL: failed to get driver name for fd -1
MESA-LOADER: failed to retrieve device information
failed building default dmabuf feedback ... error getting EGL device render node
EGL_EXT_device_drm ... at least one is required

不用管,也不影响其他软件。它们只是说明「WSL 没有真 DRM、没有 EGL_EXT_device_drm、dmabuf 零拷贝不可用,自动回退到 shm」。GPU 渲染(d3d12)、CUDA 都正常。真的受影响的是多 GPU 选择、DRM leasing、VR、部分录屏工具这些边缘功能。

另外两条:

error inhibiting power key: AccessDenied
XDG_SESSION_ID is unset or invalid; logind LockedHint won't be set

是 logind 集成的小问题(电源键抑制、锁屏状态),与图形无关。


7. X11 vs niri 对比与选择#

维度X11(Xwayland + LightDM + XFCE)niri(Wayland)
登录界面✅ LightDM + slick-greeter一般直接 niri --session,无独立登录界面
窗口管理xfwm4(标题栏/最小化/最大化)niri 平铺/滚动,自绘边框
外层窗口装饰无(WSLg 不画;内部窗口有 xfwm4 装饰)winit CSD,有边框
GPU✅ GALLIUM_DRIVER=d3d12✅ 默认/可设
dmabuf 零拷贝❌ → shm❌ → shm
稳定性成熟,踩坑主要在 greeter 后端需注意 resize 的 Mesa NULL bug(已给补丁)
适合想要“传统桌面 + 登录界面”想要现代平铺、滚动布局

8. 一页排查清单#

  1. systemctl is-active lightdm、pgrep -a Xwayland、pgrep -a slick-greeter。
  2. 看 /var/log/lightdm/lightdm.log 是 greeter 崩还是 X 起不来。
  3. journalctl -u wslg-fix.service -b、ls -l /tmp/.X11-unix/X0。
  4. journalctl -b -t /usr/bin/Xorg 看包装脚本实际参数。
  5. greeter 崩 → 十有八九是 GDK 走了 Wayland,确认 GDK_BACKEND=x11 包装脚本生效。
  6. 没边框 → pgrep xfwm4,检查 ~/.xsession-errors 的 _NET_* 报错。
  7. nvidia-smi 找不到 → PATH 没 /usr/lib/wsl/lib,软链到 /usr/local/bin。
  8. 帧率低 → glxinfo -B 看是不是 llvmpipe;设 GALLIUM_DRIVER=d3d12。
  9. 比较性能 → 用 glmark2,固定 -s。
  10. GDM/GNOME 在 Fedora 44 起不来 → 正常,换 LightDM + X11 桌面。

9. 参考#

  • WSLg 官方仓库与 README(RAIL/VAIL、vGPU 经系统内存的限制):https://github.com/microsoft/wslg
  • 社区文章《在 wsl2 中使用 wslg 实现完整桌面环境》(GDM/GNOME 版思路来源)
  • Mesa src/egl/drivers/dri2/platform_wayland.c(dri2_wl_swrast_put_image2 / dri2_wl_swrast_get_backbuffer_data)

免责声明:本文基于 WSLg 1.0.79 + Fedora 44 实测,不同 WSL/发行版/桌面版本细节可能不同;升级 Mesa 会覆盖第 6 节的补丁。