【Linux】关于 X11 GUI 转发和 WSLg 的坑

2021-09-11

image.png

我的电脑是 Win11 企业版,版本号是 21H2。虽然 WSL2 已经很强大了,但是我还是系统有一天能够打通 Win 与 Linux 的壁垒,实现真正的自由切换,这样对于我们无论是开发还是测试都会变得非常简单。但打通两个系统可能不是轻而易举的,需要多方的努力才能做到。

Linux 与 Windows 共存

MacOS 就算了,我不喜欢 MacOS。

虚拟机与双系统

Linux 虚拟机或者双系统高中的时候有搞过,虽说搞出来了,但是那时候什么都不懂,也只是用 Ubuntu 的图形界面罢了,命令行不会用,体会不到 Win 与 Linux 的差异。

大学开始接触编程之后,就知道最好的环境就是 Unix 环境或者类 Unix 环境了,当时装了 Win10 + Ubuntu18.04 双系统,虽然说写代码体验非常爽,但是交作业体验就非常差了。更别说听歌、看视频和使用其他软件了,使用纯 Linux 环境就意味着你要放弃高标准的办公软件、通用的娱乐软件和游戏这些,甚至还有开发需要用的桌面类软件,这在我眼里是不值得的。但是苦于 Win 与 Linux 隔阂太深,所以当时只能使用双系统了,双系统的体验是非常糟糕的。

WSL 与 WSL2

以前我一直骂 Windows 的闭源,在 Windows 上开发很痛苦的,尤其是你要做编译的工作的时候,简直噩梦。后面微软竟然出了 WSL,虽然很捞,但是理念震惊到我了。我应该算是第一批 WSL 用户了,当时立刻把双系统给删了,迁回 Windows,使用 WSL 代替 Linux 环境,不过那时候 WSL 很垃圾,内核问题一堆,这不行那不行的。我就想了,那先用虚拟机吧,结果 WSL 其实就是个 Hyper-V 虚拟机,和 VMware、VirtualBox 无法兼容,简直就是简直了。所以 WSL 被人骂惨了,我也骂,不过骂也是因为真真正正有这个需求啊。

后面 WSL2 出世了,由于我是内测用户,还丧心病狂地订阅了 Dev Channel,所以是第一批更新到 WSL2 的玩家,简直不要太爽。因为 WSL2 支持 docker 神器,加上微软自己布局的 WindowsTerminal 和 VSCode 对 WSL 的助攻,使得 WSL 的体验越来越好了。因此 WSL2 出来之后,骂声变少了,微软也变成了大家口中的“巨硬”。

后面其他大软件平台也专门对 WSL2 做支持了,毕竟这是趋势,没人能够拒绝 Windows 这个最大的 Linux 发行版,哈哈。包括 VMware、Docker Desktop 都对 WSL2 做了支持,简直不要太爽。

但是还是有遗憾的,就是 JetBrain 家的 IDE 对 WSL2 的支持都不够好,而且更新慢,尤其是 maven 根本用不了,这无疑是 Java 工程师最大的痛点。那我就想着,如果能够使用 Linux 中的桌面程序就好了。当时我还不知道 X11 Forwarding 这东西。

WSL2 桌面支持

后面 WSL2 更新 WSLg,支持使用 Linux 桌面程序!我马上就去试了一下,So Bad。因为无法调整分辨率,而 Scaling 也只能调整为整数倍。Linux 程序在我这 2K 屏幕上,那些字就跟蚂蚁一样小,根本用不了。所以期待落空了。

而实际上 WSL2 的图形支持是通过 RDP 实现的,原理类似于 X11 Forwarding。显示效果自然要好于 X11 Forwarding,但是高分屏现在还是用不了。。。

X11 图形转发

Linux 与 Windows 互通是不可能的,毕竟内核不一样,但是虚拟机是可以共存的。所以要让他们互通,我们可以把 Linux 当作是远程服务器去看待。

X-Windows

Linux 和 Windows 不一样,并没有将图形功能放到内核里面,早期 Linux 就是终端操作的,没想过支持窗口应用。所以 Linux 的图形应用支持是通过程序实现的,就算我们用 Ubuntu Desktop 看到的整个图形窗口,也只是 Linux 的一个程序而已,和 Windows 那种与生俱来的图形界面完全不同。

Linux 就是通过 X Window System 来实现图形界面的。之所以称为 X11,是因为 X-Windows 发展到 11 版之后,所有新版本都是在 X11 之上拓展,没有本质上的改动。(X11 是 1987 年整出来的)

X-Windows 由 X Server 和 X Client 组成,X Server 用于接收 IO 设备的各种事件,例如鼠标点击事件、屏幕点击时间、键盘输入事件,然后向用户进行输出显示,是面向用户交互的。X Client 就是各个图形程序,X Server 将接收到的各种事件发送给 X Client,X Client 处理完成之后将结果响应给 X Server,X Server 再进行输出。

image.png

X-Windows 只是定义了这个框架,但并没有限定具体输入输出的各种细节,这也是如今 Linux 图形化界面百花齐放的原因。

图形转发

我们发现,X Server 的主要作用是输入、渲染和通信,并不参与应用程序的运算,因此 X Server 这一层是可以单独拿出来的。显示终端在哪,X Server 这一层就放在哪,X Client 可以作为远程主机通过网络与 X Server 交互,这样我们就可以远程使用 Linux 图形应用了。

这也是很多使用 WSL 的同伴们最初使用图形界面的方式。也是我们远程开发的常用方式。不过这种方式的问题是:

  1. 数据传输效率低,X11 转发的消耗非常大这一点一直让人所诟病。
  2. X Server 无法与显示设备很好的兼容。

X Server 所有的更新都是小打小闹的,以至于现在大多数人用的 Windows 中的 X Server 都是十年前的版本,(没错就是 Xming)。因为 X Server 我们会放在 Windows 这边,来实现在 Windows 中使用 Linux 程序这一功能。

分辨率的坑

但是有一个很难受的问题就是,X Server 通常都太老而无法支持高分辨率,Windows 的 X Server 基本上都无法修改分辨率。这就是我遇到的坑。我被坑惨了,我试了 Xming、MobaXterm 和 VcxSrv,都没办法修改。

就算你使用的是新版的 Linux 发行版,支持 GNOME 或者 KDE 这些桌面,分辨率调到你爽,也没办法解决这个问题。因为 Linux 自己的桌面是 Linux 主机自己的 X Server 渲染的,而我们远程图形转发的 X Server 是我们 SSH 客户端的 X Server,根本无法用到 Linux 自身的 X Server 上的功能,他们是分开的两个东西。

而网上非常多修改分辨率的教程,但都是没用的,因为 Linux 自己的 X Server 支持修改,你的客户端里的 X Server 不支持修改,你也没辙。

image.png

image.png

所以。。。还是得滚回去用虚拟机。

所以现在是 Windows + WSL2 + Linux VM 的环境,Linux VM 用得比较少,但是我就是喜欢往坑里钻,脑壳疼。

WSLg

WSL2 推出的 WSLg 在高分屏下字体太小的问题,可以通过 export GDK_DPI_SCALE=N 进行设置,这里的 N 就是字体缩放倍数,可惜只能是整数倍。同时标题框无法缩放,这简直要了我这个强迫症的命。

盯紧这个 Issue,等官方早日解决吧:WSLg does not seem to support fractional scaling · Issue #23 · microsoft/wslg (github.com)

不过官方之所以禁止这个功能,是因为非整数倍缩放实在是太模糊了,如果能够忍受,可以通过这种方式启用:

创建文件 C:\ProgramData\Microsoft\WSL\.wslgconfig,内容为:

[system-distro-env]
WESTON_RDP_DISABLE_FRACTIONAL_HI_DPI_SCALING=false
复制代码
分类:
开发工具
标签: