跳转至内容

dwm

来自 ArchWiki

dwm 是一个为 Xorg 设计的动态窗口管理器。它支持平铺、堆叠和全屏等布局,还可以通过可选的补丁实现更多布局。布局可以动态应用,以优化当前应用程序和任务所需的环境。dwm 极其轻量且快速,用 C 语言编写,其设计目标是源代码行数保持在 2000 行以内。它支持 多头 显示,适用于 xrandr 和 Xinerama。

安装

可以使用 dwmAUR 包来 安装 dwm。在构建和安装 **之前** 进行任何必要的 配置更改,请参阅 makepkg

提示 也可以遵循 上游说明 进行安装,但这会将文件安装到 pacman 无法跟踪的地方。

配置

dwm 的配置是在编译时通过编辑其源代码文件(特别是 config.h)来完成的。有关这些设置的详细信息,请参阅其中包含的、注释良好的 config.def.h 以及 dwm 网站上的 自定义部分

官方网站上提供了许多 补丁,可以为 dwm 添加额外的功能。这些补丁主要修改 dwm.c 文件,但也会在适当的时候修改 config.h 文件。有关应用补丁的信息,请参阅 补丁包 文章。

启动

从您选择的 显示管理器 的菜单中选择 Dwm。或者,要使用 startx 启动 dwm,请将 exec dwm 添加到 ~/.xinitrc 文件末尾,并在其前面加上其他要执行的程序,例如:

redshift -O3500; xset r rate 300 50; exec dwm

用法

有关 dwm 基本用法的详细信息,请参阅 dwm 教程

技巧与提示

状态栏配置

有关更多状态栏的示例,请参阅 [1]

注意 以下操作需要安装 xorg-xsetroot 包。

dwm 读取根窗口的名称并将其重定向到状态栏。根窗口是所有其他窗口在其内部绘制和由窗口管理器排列的窗口。与任何其他窗口一样,根窗口也有一个标题/名称,但通常未定义,因为根窗口始终在后台运行。

您希望 dwm 在状态栏中显示的信息应在 ~/.xinitrc~/.xprofile(如果您正在使用 显示管理器)中使用 xsetroot -name "" 命令定义。例如:

xsetroot -name "Thanks for all the fish!"

动态更新的信息应放在一个循环中,该循环被 fork 到后台运行 - 请参阅下面的示例:

# Statusbar loop
while true; do
   xsetroot -name "$( date +"%F %R" )"
   sleep 1m    # Update time every minute
done &

# Autostart section
pcmanfm & 

exec dwm

在这种情况下,日期将以 RFC:3339 格式显示,并在启动时启动 PCManFM

注意 不建议将更新间隔设置为零或完全移除“sleep”行,因为这会导致 CPU 使用率大幅升高(您可以使用 toppowertop 来评估效果)。

Conky 状态栏

可以使用 xsetroot -nameConky 输出到状态栏。

(conky | while read LINE; do xsetroot -name "$LINE"; done) &
exec dwm

如果您不想通过 'xsetroot' 命令生成过多的 PID,可以编译这个 C 程序:

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <X11/Xlib.h>

int main(int argc, char * argv[])
{
        Display * dpy = NULL;
        Window win = 0;
        size_t length = 0;
        ssize_t bytes_read = 0;
        char * input = NULL;

        dpy = XOpenDisplay(getenv("DISPLAY"));
        if (dpy == NULL)
        {
                fprintf(stderr, "Can't open display, exiting.\n");
                exit(1);
        }
        win = DefaultRootWindow(dpy);

        while ((bytes_read = getline(&input, &length, stdin)) != EOF)
        {
                input[strlen(input) - 1] = '\0';
                XStoreName(dpy, win, input);
                XFlush(dpy);
                fprintf(stderr, "Input: %s", input);
                fprintf(stderr, "\nbytes read: %ld\n", bytes_read);
        }
        free(input);
        return 0;
}

将此代码保存到文件 dwm-setstatus.c,然后编译:

$ gcc dwm-setstatus.c -lX11 -o dwm-setstatus

将 'dwm-setstatus' 移动到您的 $PATH 中(例如 /usr/local/bin)。

# mv dwm-setstatus /usr/local/bin

并运行

$ conky | dwm-setstatus

为此,需要告诉 conky 只将文本输出到控制台。以下是一个双核 CPU 的示例 conkyrc,显示了几个使用统计信息:

conky.config = {
out_to_console = true,
out_to_x = false,
background = false,
update_interval = 2,
total_run_times = 0,
use_spacer = 'none',
};
conky.text = [[
$mpd_smart :: ${cpu cpu1}% / ${cpu cpu2}%  ${loadavg 1} ${loadavg 2 3} :: ${acpitemp}c :: $memperc% ($mem) :: ${downspeed eth0}K/s ${upspeed eth0}K/s :: ${time %a %b %d %I:%M%P}
]];

有关图标和颜色选项,请参阅 dzen

重启 dwm

要无需注销或关闭应用程序即可重启 dwm,请更改或添加一个启动脚本,使其在 while 循环中加载 dwm,例如:

while true; do
    # Log stderror to a file 
    dwm 2> ~/.dwm.log
    # No error logging
    #dwm >/dev/null 2>&1
done

现在可以通过按下通常的 Mod-Shift-Q 组合键来重启 dwm,而不会破坏其他 X 窗口。

最好将上述启动脚本放在一个单独的文件中,例如 ~/bin/startdwm,并通过 ~/.xinitrc 执行它。请考虑使用 exec 运行脚本,以避免在 X 服务器终止后仍然登录的安全隐患;有关更多信息,请参阅 Xinit#Autostart X at login。从现在开始,当您想结束 X 会话时,只需执行 pkill dwm,或将其绑定到一个方便的快捷键。或者,您可以设置您的 dwm 会话脚本,使其仅在二进制文件更改时才重新启动 dwm。当您更改设置或更新 dwm 代码库时,这可能会很有用。

# relaunch DWM if the binary changes, otherwise bail
csum=""
new_csum=$(sha1sum $(which dwm))
while true
do
    if [ "$csum" != "$new_csum" ]
    then
        csum=$new_csum
        dwm
    else
        exit 0
    fi
    new_csum=$(sha1sum $(which dwm))
    sleep 0.5
done

将右 Alt 键绑定到 Mod4

当使用 Mod4(Super/Windows 键)作为 MODKEY 时,将右侧的 Alt 键(Alt_R)设置为 Mod4 可能同样方便。这将允许您用单手执行那些原本笨拙的按键组合,例如使用 Alt_R+Enter 进行缩放。

首先,找出分配给 Alt_R 的键码:

$ xmodmap -pke | grep Alt_R

然后只需将以下内容添加到启动脚本(例如 ~/.xinitrc)中,如果需要,请将键码 113 更改为上一个 xmodmap 命令获得的结果:

重新分配 Alt_RSuper_L

xmodmap -e "keycode 113 = Super_L"

确保 X 将其排除在“mod1”组之外:

xmodmap -e "remove mod1 = Super_L"

完成此操作后,任何由 Super_L 键按下触发的功能也将由 Alt_R 键按下触发。

注意 config.h 中有一个 #define 选项,也可以让您切换 modkey。

在 DWM 中将两个 Alt 键都用作 Meta

使用 xmodmap 将 Alt_L 分配为 DWM 中的第二个 meta 键(前提是已在使用 Mod1Mask (Alt_R))。

~/.xinitrc
/usr/bin/xmodmap -e "clear mod5"
/usr/bin/xmodmap -e "keycode 108 = Alt_L"

dwm 状态栏字体周围留白

默认情况下,dwm 的状态栏会在字体大小周围添加 2px 的留白。要更改此设置,请修改以下行:

dwm.c
bh = dc.h = dc.font.height + 2;

禁用鼠标跟随焦点

要禁用鼠标跟随焦点行为,请在 struct handler 的定义中注释掉以下行:

dwm.c
[EnterNotify] = enternotify,

请注意,此更改可能会导致一些困难;第一次点击非活动窗口只会将焦点移至该窗口。要与窗口内容(按钮、字段等)进行交互,您需要再次点击。此外,如果您有多个显示器,您可能会注意到键盘焦点不会切换到通过点击激活的另一个显示器。

某些窗口的浮动布局

对于某些窗口(如偏好设置对话框),平铺这些窗口没有意义——它们应该浮动。例如,要使 Firefox 的偏好设置对话框浮动,请将以下内容添加到 config.h 的 rules 数组中:

{ "Firefox",     NULL,       "Firefox Preferences",        1 << 8,         True,     -1 },


要获取其他窗口的属性,可以使用 xprop 程序。


xprop | awk '
/^WM_CLASS/{sub(/.* =/, "instance:"); sub(/,/, "\nclass:"); print}
/^WM_NAME/{sub(/.* =/, "title:"); print}'

有关更多信息,请参阅 dwm 网站

将 Tilda 与 dwm 一起使用

Tilda 在添加到所有标签并配置为浮动时效果最佳。为此,请将以下内容添加到 config.h 的 rules 数组中:

{ "Tilda",        NULL,       NULL,                         0,              True,       -1 },

使用 -C 选项启动 tilda:

$ tilda -C

现在您可以配置 Tilda,以下选项作为建议提供:

Font: Clean 9
Appearance: Height: 50%, Width: 70%, Centered Horizontally
Extras: Enable Transparency Level 15
Animated Pulldown: 1500 usec, Orientation: Top
Colors: Built-in Scheme "Green on Black"
Scrolling: Scrollbar is on the left, 2000 lines scrollback
Key Binding: F9

启用下拉动画非常重要,否则每次隐藏 Tilda 时它都会向下跳动,这似乎是 dwm 的一个问题。

截屏

安装 scrot 包。然后创建两个脚本:

/path/to/scripts/screenshot.sh
#!/bin/sh
mkdir -p /path/to/pics && scrot /path/to/pics/%m-%d-%Y-%H%M%S.png

用于截屏,以及

/path/to/scripts/screenshotsel.sh
#!/bin/sh
mkdir -p /path/to/pics && scrot /path/to/pics/%m-%d-%Y-%H%M%S.png --select --line mode=edge

用于截屏并带有选择框。给予它们 可执行 权限。在 config.h 中添加以下内容:

static const Key keys[] = {
       ...
       
       { 0,         XK_Print, spawn, SHCMD("/path/to/scripts/screenshot.sh") },
       { ShiftMask, XK_Print, spawn, SHCMD("/path/to/scripts/screenshotsel.sh") },
       
       ...
};

这将把截屏映射到 Print 键,将带有选择框的截屏映射到 Shift + Print 键。

映射多媒体按键

添加到 config.h 的顶部:

#include <X11/XF86keysym.h>

以便 使用多媒体按键。现在我们可以将常用任务映射到这些按键。

调整音量

安装 pipewire 包。现在可以在 config.h 中添加静音和音量增加/减少的命令。

static const char *up_vol[]   = { "pactl", "set-sink-volume", "@DEFAULT_SINK@", "+10%",   NULL };
static const char *down_vol[] = { "pactl", "set-sink-volume", "@DEFAULT_SINK@", "-10%",   NULL };
static const char *mute_vol[] = { "pactl", "set-sink-mute",   "@DEFAULT_SINK@", "toggle", NULL };
...

static const Key keys[] = {
       ...
       
       { 0, XF86XK_AudioMute,        spawn, {.v = mute_vol } },
       { 0, XF86XK_AudioLowerVolume, spawn, {.v = down_vol } },
       { 0, XF86XK_AudioRaiseVolume, spawn, {.v = up_vol } },
       
       ... 
};

调整亮度

安装 brightnessctl 包。现在可以在 config.h 中添加屏幕调暗和调亮的命令。

static const char *brighter[] = { "brightnessctl", "set", "10%+", NULL };
static const char *dimmer[]   = { "brightnessctl", "set", "10%-", NULL };
...

static const Key keys[] = {
       ...
       
       { 0, XF86XK_MonBrightnessDown, spawn, {.v = dimmer } },
       { 0, XF86XK_MonBrightnessUp,   spawn, {.v = brighter } },
       
       ...
};

自启动

提供了一个 补丁。它会在进入处理循环之前运行 ~/.dwm/autostart_blocking.sh~/.dwm/autostart.sh &。可以省略其中一个或两个文件。

故障排除

修复行为异常的 Java 应用程序

请参阅 Java#Gray window, applications not resizing with WM, menus immediately closing

修复终端窗口周围的间隙

如果终端窗口周围有空白区域,这很可能是由终端的字体大小引起的。要么调整大小直到找到能消除间隙的理想比例,要么在 config.h 中将 resizehints 切换为 0

这将导致 dwm 忽略所有客户端窗口的 resize 请求,而不仅仅是终端。此解决方法缺点是某些终端可能会出现重绘异常,例如重影线条和过早的换行等。

或者,如果您使用 st 终端模拟器,您可以应用 anysize 补丁并重新编译 st。

阿拉伯字母连字

dwm 状态栏不支持字母连字。但是,您可以使用 类似工具,例如 fribidi,通过 Unicode 阿拉伯语表示形式-B 来应用字母连字。例如,而不是

xsetroot -name "لِخَـوْلَةَ أطْـلالٌ بِبُرْقَةِ ثَهْمَـدِ"

使用

xsetroot -name "$(echo "لِخَـوْلَةَ أطْـلالٌ بِبُرْقَةِ ثَهْمَـدِ" | fribidi --nopad)"

参见

© . This site is unofficial and not affiliated with Arch Linux.

Content is available under GNU Free Documentation License 1.3 or later unless otherwise noted.