在Gentoo Linux上使用dwm
dwm全名为dynamic window manager,是suckless出品的主打简洁的窗口管理器。这里不多谈窗口管理器这个话题,我们主要说一下dwm都有哪些特点。
这里我将dwm和i3wm做一个简单的对比,这两者都是平铺窗口管理器,但是dwm和核心概念是标签(tag),而i3wm的核心概念则是容器(container),简单来说,dwm会给每个图形窗口打上tag,你可以选择显示某个tag或者某几个tag,与这些tag绑定的所有窗口都会被显示。在显示时,这些窗口会按照一定的布局排布,最基本的布局是一个主窗口占大部分空间,其他窗口平分剩下的空间。i3wm则是有若干个工作区,每个工作区内是一个容器构成的树,每个容器内可以包含子容器和程序窗口,你可以定义每个容器内的布局,比如分割方向,分割比例等。同一时刻,i3wm只能显示一个工作区。因此,i3wm可以手动实现更精细的布局控制,但是其他方面来说,不如dwm灵活,而布局这件事,我个人认为只需要几种自己常用的即可。因此我个人也是比较偏爱dwm。当然还有其他一些优秀的窗口管理器也有类似的特性,这里就不多介绍了。
dwm是使用c语言实现的,与一般的这类软件不同,dwm只包含大概两千多行代码,没有实现运行时的配置解析,而是将配置放到了一个c语言的头文件内,这样修改该头文件之后,编译即可得到一个配置过的dwm。这算是suckless软件的一种理念,我个人了解不多,这里就不多谈了。总之dwm不具备运行时解析配置的能力,更改配置之后,需要重新编译才能生效。这种配置方式并不是这种理念最有意思的地方,而是这种方式强迫用户自己对dwm进行修改,从而产生了补丁(patch)。
dwm的代码相当简洁,本身只具备非常基本的功能,即使是你进行了详细的配置,dwm也只能说是勉强可用的程度,因此很多用户为dwm编写了各种补丁,为dwm添加各种功能,也就是说,作为用户,你可以选择给dwm打上你想要的补丁,来让你自己的dwm更符合自己的需求,无论这些功能是否被官方认可。如果你自己熟悉c语言,只要花上一些时间读懂dwm的源代码,你也可以自己编写自己的补丁,来实现自己想要的但是别人没做的功能。这就让dwm具备了无限可能,一般的窗口管理器,你只能接受官方的设计,即使开放源代码,也一般因为过于复杂,造成大部分用户无力修改,从而没有多少补丁可用。而dwm则因为简洁的代码,而拥有其他窗口管理器不具备的定制能力。通过补丁,用户可以给dwm添加新功能、新布局、修改外观等等。
当然这样做的缺点也是显然的,要定制就必须有一定的定制能力,虽然说现在简单的定制已经可以说是毫无难度了,但如果要定制dwm,最好还是具备一些基本的c语言功底、编译常识、常用工具的使用、代码冲突解决的能力。如果补丁数量很多的话,要管理这些补丁、解决补丁之间的冲突,这些成本也是很高的。
Gentoo由于本身是一个源码编译的发行版,在包管理器设计上就给源码编译的软件留足了空间,对于dwm来说,Gentoo可以说是一个非常合适的发行版了。具体来说,Gentoo具备用户自定义补丁、保留配置等功能。同时,Gentoo官方源内的dwm包还提供了一个session文件用于登陆时自动启动程序。
因此以下就主要介绍一下,我是怎么在Gentoo下使用dwm的。
首先Gentoo上的dwm包提供了一个session文件,当你通过display manager启动dwm的时候,会自动运行 ~/.dwm/dwmrc 这个启动脚本,在这个脚本里,你可以自己启动一些自己常用的程序,比如我就是抄了一位大佬的脚本,做了启动fcitx5,picom,定时换壁纸之类的事情,这样,就不再需要给dwm打autostart之类的补丁了。当然如果你想用startx这种方式启动dwm,这个脚本是不会执行的。我之前在用这种方式启动的时候,就碰到了一些D-bus相关的问题,最后没有很好的解决,还是换成了简单易用的dm。
Gentoo提供了比较方便的补丁机制,当用户安装某个软件,需要打补丁的时候,只需要将补丁放入一个特定的文件夹,portage在构建时,便会自动打上这些补丁,再进行编译。具体来说,补丁目录是 /etc/portage/patches/<category>/<package> ,这里的category和package分别是包类别和包名,package还可以指定版本。像我目前只选择了少数不冲突的补丁,我只需要把这些补丁一股脑的放到 /etc/portage/patches/x11-wm/dwm-6.2/ 文件夹内,就能正常的用包管理安装dwm,同时又打上我需要的补丁。
此外部分包还提供了savedconfig这个use,当启用这个use的时候,portage会将构建时需要的配置文件存在一个地方,在构建包时,就能自动应用这些配置,对于dwm来说,这个配置文件就是dwm的头文件 config.h ,当你修改好这个文件后,将它存成 /etc/portage/savedconfig/x11-wm/dwm-6.2 这个文件(因为这个文件后缀名不是.c,所以文件编辑器一般不会高亮显示,如果是vim,可以手动执行 set ft=c 指令),在编译前,portage就会自动将这个文件替换成 config.h。这样当你修改了配置之后,你只需要重新emerge一次dwm,就能更新好dwm了,当然这些改动还需要重启dwm才能真正生效。
总的来说,上面说的这些,都是为了能让dwm能完全由包管理管理。对于软件包来说,我个人是比较倾向于能交给包管理器的,都一律交给包管理处理。因为这样相对来说比较简单而且比较“干净”,用户只需要维护一份配置,就能够简单的重新构建出一套相同的环境。总的来说,要做到这点,还是不那么容易的,比如Arch这样的发行版,你要做到这点,要么是自己维护一个AUR脚本,要么是修改通用的AUR脚本。对我这种懒到极致的人来说,还是有点不友好的。而类似debian的发行版,则可能只能直接 make install 了。