dwm 美化

Posted aluluka

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dwm 美化相关的知识,希望对你有一定的参考价值。

在之前的博客中,我们将arch linux这个系统进行了一些美化,当然也是仅仅做到能看这个地步,要说跟网上其他那些惊艳的特效对比,肯定是不如的。但是我一直秉持一个观点,美化应该适可而止,只要不是丑的你不想打开,不想用,就已经足够了。所以我们不再对系统本身做其他美化,下面开始进行dwm本身的美化

dwm美化

相关插件安装

上一篇博文中,为了解决从登陆管理器进入dwm无法加载背景图片的问题,我们已经安装了dwmautostart插件,为了进一步的美化,这里再安装几个插件

wget https://dwm.suckless.org/patches/alpha/dwm-alpha-20201019-61bb8b2.diff # 半透明
wget https://dwm.suckless.org/patches/barpadding/dwm-barpadding-20211020-a786211.diff  #适当添加标题栏间距
wget https://dwm.suckless.org/patches/uselessgap/dwm-uselessgap-20211119-58414bee958f2.diff #dwm窗口间添加边距 

使用patch 命令之后,重新编译安装。重启之后发现dwm已经变样了

设置状态条

根据dwm官方的说法,使用xsetroot -name 来设置标题栏的内容,比如说我们使用如下命令来打印当前用户

xsetroot -name $(whoami)

运行之后发现dwm的右上角显示的内容变了

知道原理之后我们只需要在dwm启动的时候执行相关脚本,获取相关数据并刷新即可,例如可以使用如下命令实现每秒刷新时间

while true
do
    xsetroot -name "$(date)"
    sleep 1s
done

根据这个我们可以写一些脚本,获取各个状态,然后使用 xsetroot -name 来输出这些状态。但是这里我并不打算完全使用脚本来定义输出,而是使用dwmblocks来管理这个状态栏,输出各种状态。

git clone https://github.com/torrinfail/dwmblocks.git

进到对应目录中,编译并安装它

make
sudo make clean install

安装完成之后我们在autostart 脚本末尾添加一行代码中启动dwmblocks程序

dwmblocks &

重启dwm之后可以看到变化,原来输出的日期变为了内存使用情况加日期的显示了

进入到dwmblocks的目录中,会发现一个blocks.def.hblocks.h的文件,这里我们删掉前一个文件,后续想要修改显示内容可以修改blocks.h文件

//Modify this file to change what commands output to your statusbar, and recompile using the make command.
static const Block blocks[] = 
 /*Icon*/ /*Command*/  /*Update Interval*/ /*Update Signal*/
 "Mem:", "free -h | awk '/^Mem/  print $3\\"/\\"$2 ' | sed s/i//g", 30,  0,

 "", "date '+%b %d (%a) %I:%M%p'",     5,  0,
;

//sets delimeter between status commands. NULL character ('\\0') means no delimeter.
static char delim[] = " | ";
static unsigned int delimLen = 5;

其中blocks 数组是用来保存要获取的状态,每组状态用一个数组成员,其中每个成员又是一个字符串数组,每个部分分别代表了:状态前显示的图标,获取状态的命令,状态刷新的时间,更新的标志; 变量delim 表示各个状态之间的分割符

这样我们可以讲获取状态和显示状态分离开来,实现模块化,后续可以将不同状态组织成不同模块,便于管理脚本

这里我们计划输出网速、内存使用占比、cpu使用占比、音量、电量、亮度、时间

这里我在dwmblocks 源码目录中创建一个scripts的目录用来存储获取这些状态的脚本,分别命名为: wlan.sh、memory.sh、cpu.sh、volume.sh、power.sh、light.sh、clock.sh

然后修改blocks变量,通过调用这些脚本获取状态

//Modify this file to change what commands output to your statusbar, and recompile using the make command.
static const Block blocks[] = 
        /*Icon*/        /*Command*/             /*Update Interval*/     /*Update Signal*/
        " ", "~/scripts/wlan.sh",     1,              0, //网速
        " ", "~/scripts/cpu.sh",      5,              0, //cpu占用率
        " ", "~/scripts/memory.sh",   3,              0, //内存占用率
        "", "~/scripts/volume.sh",     0,              11, //音量
        "ﯦ ", "~/scripts/backlight.sh",        0,              11, //亮度
        "", "~/scripts/battery.sh",    2,              0, //电量
        "", "~/scripts/date.sh",      1,              0, //时间
;

//sets delimeter between status commands. NULL character ('\\0') means no delimeter.
static char delim[] = " | ";
static int delimLen = 5;

接着在用户目录下新建一个scripts 目录,并新建这些脚本文件

backlight.sh

xbacklight -get

要使用xbacklight 这个工具需要事先安装acpilight

sudo pacman -S acpilight
sudo gpasswd video -a 用户名 # 将当前用户添加到video实现免root控制亮度

# 获取当前亮度
xbacklight -get
# 设置亮度
xbacklight -set 70
# 增加亮度
xbacklight -inc 10
# 减少亮度
xbacklight -dec 10

battery.sh

#!/bin/bash
get_battery_combined_percent() 
    total_charge=$(expr $(acpi -b | awk 'print $4' | grep -Eo "[0-9]+" | paste -sd+ | bc))
    battery_number=$(acpi -b | wc -l)
    percent=$(expr $total_charge / $battery_number)

    if [ "$percent" -le 33 ]; then
        if $(acpi -b | grep --quit Discharging); then
           printf " %s%%" "$percent"
        else
           printf " %s%%" "$percent"
        fi
    elif [ "$percent" -ge 33 ] && [ "$percent" -le 66 ]; then
        if $(acpi -b | grep --quit Discharging); then
            print " %s%%" "$percent"
        else
            printf " %s%%" "$percent"
        fi
    else
        if $(acpi -b | grep --quit Discharging); then
            printf " %s%%" "$percent"
        else
            printf " %s%%" "$percent"
        fi
    fi


get_battery_combined_percent

cpu.sh

#!/bin/sh
#
#脚本功能描述:依据/proc/stat文件获取并计算CPU使用率
#
#CPU时间计算公式:CPU_TIME=user+system+nice+idle+iowait+irq+softirq
#CPU使用率计算公式:cpu_usage=(idle2-idle1)/(cpu2-cpu1)*100

#默认时间间隔
TIME_INTERVAL=5
time=$(date "+%Y-%m-%d %H:%M:%S")
LAST_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk 'print $2,$3,$4,$5,$6,$7,$8')
LAST_SYS_IDLE=$(echo $LAST_CPU_INFO | awk 'print $4')
LAST_TOTAL_CPU_T=$(echo $LAST_CPU_INFO | awk 'print $1+$2+$3+$4+$5+$6+$7')
sleep $TIME_INTERVAL
NEXT_CPU_INFO=$(cat /proc/stat | grep -w cpu | awk 'print $2,$3,$4,$5,$6,$7,$8')
NEXT_SYS_IDLE=$(echo $NEXT_CPU_INFO | awk 'print $4')
NEXT_TOTAL_CPU_T=$(echo $NEXT_CPU_INFO | awk 'print $1+$2+$3+$4+$5+$6+$7')

#系统空闲时间
SYSTEM_IDLE=`echo $NEXT_SYS_IDLE $LAST_SYS_IDLE | awk 'print $1-$2'`
#CPU总时间
TOTAL_TIME=`echo $NEXT_TOTAL_CPU_T $LAST_TOTAL_CPU_T | awk 'print $1-$2'`
CPU_USAGE=`echo $SYSTEM_IDLE $TOTAL_TIME | awk 'printf "%.2f", 100-$1/$2*100'`

echo "$CPU_USAGE%"

date.sh

date '+ %Y年%m月%d日 %H:%M:%S'

memory.sh

memfree=$(($(grep -m1 'MemAvailable:' /proc/meminfo | awk 'print $2')))
memtotal=$(($(grep -m1 'MemTotal:' /proc/meminfo | awk 'print $2')))

useage=$(echo "scale=2;100 * ($memfree/$memtotal)" | bc)
echo -e "$useage%"

volume.sh

#!/bin/bash
VOL=$(amixer get Master | tail -n1 | sed -r "s/.*\\[(.*)%\\].*/\\1/")

if [ "$VOL" -eq 0 ]; then
    printf "ﱝ  "
elif [ "$VOL" -gt 0 ] && [ "$VOL" -le 33 ]; then
    print " %s%%" "$VOL"
elif [ "$VOL" -gt 33 ] && [ "$VOL" -le 66 ]; then
    print "墳 %s%%" "$VOL"
else
    print " %s%%" "$VOL"
fi

wlan.sh

#!/bin/zsh
function get_bytes 
    interface=$(ip route get 8.8.8.8 2>/dev/null | awk 'print $5')
    line=$(grep $interface /proc/net/dev | cut -d ':' -f2 | awk 'print "received_bytes="$1, "transmitted_bytes="$9')
    eval $line
    now=$(date +%s%N)



function get_velocity 
    value=$1
    old_value=$2
    now=$3
    timediff=$(($now - $old_time))
    velKB=$(echo "1000000000*($value-$old_value)/1024/$timediff" | bc)
    if test "$velKB" -gt 1024
    then
        echo $(echo "scale=2; $velKB/1024" |bc)MB/s
    else
        echo $velKBKB/s
    fi


get_bytes
old_received_bytes=$received_bytes
old_transmitted_bytes=$transmitted_bytes
old_time=$now

get_bytes

vel_recv=$(get_velocity $received_bytes $old_received_bytes $now)
vel_trans=$(get_velocity $transmitted_bytes $old_transmitted_bytes $now)

echo "$vel_recv$vel_trans⬆"

这些脚本主要取材自B站的UP主 TheCW ,脚本的地址如下:
dwm status scripts

也有部分参考了这个地址 dt scripts

在上述脚本中有部分图标可能显示为乱码,这是因为读者本地没有安装对应的字体,这些图标都是我在nerd font 官网上找到的:Nerd Font Icons

做完这些修改后重新编译dwmblocks 然后重启dwm就可以看到效果了

dwm 其他部分修改

这部分的修改主要在dwm目录的config.f
1.修改左侧图标

static const char *tags[] =  "", "", "", "", "", "ﱘ", "";

2.修改dwm配色

static const char col_gray1[]       = "#222222";
static const char col_gray2[]       = "#444444";
static const char col_gray3[]       = "#bbbbbb";
static const char col_gray4[]       = "#ffffff";
static const char col_cyan[]        = "#37374f";

3.修改 窗口布局的图标

static const Layout layouts[] = 
        /* symbol     arrange function */
         "",      tile ,    /* first entry is default */
         "缾",      NULL ,    /* no layout function means floating behavior */
         "[M]",      monocle ,
;

修改完成之后的样子如下

针对终端和程序启动器的简单配置

suckless 全家桶本身也有终端st和程序启动器dmenu,也是一贯以极简著称,但是我已经不想在过多的投入精力到这些的配置中了,这里我找到了一些开箱即用的程序作为st dmenu的替代瓶,等有精力和时间了再来折腾他们

这里终端使用alacritty 程序启动器使用rofi

sudo pacman -S alacritty rofi

可以在这里找到关于alacritty 的配色
alacritty themes

/usr/share/doc/alacritty/example/alacritty.yml 拷贝一份到~/.config/alacritty/alacritty.yml 作为配置文件,然后找到自己喜欢的配色,修改里面关于color的部分

修改dwm中启动终端的快捷键

static const char *termcmd[] = "alacritty", NULL;

关于rofi的主题,可以在这个网站中找到 rofi theme

git clone --depth=1 https://github.com/adi1090x/rofi.git
cd rofi
./setup.sh # 安装

这里以misc里面的simple_kde 主题为例, 在~/.config/rofi/launcher/misc 中有launcher.sh ,找到最后一行

rofi -no-lazy-grab -show drun -modi drun -theme $dir/"$theme"

将这行写入dwm的配置文件中,修改最后的路径为对应的.rasi文件

static const char *dmenucmd[] =  "rofi", "-no-lazy-grab","-show", "drun", "-modi", "drun", "-theme", "~/.config/rofi/launchers/misc/kde_simplemenu.rasi", NULL ;

最终的效果如下图

当然还有一些其他的配置没有做,例如终端透明,标题栏也不算好看。比起一些网上大神的配置来,这些显得还是太朴素了,但是工具这种东西只要够用就行,实在不行还可以照抄其他觉得好的配置。我主要通过这段时间的折腾搞明白了如何从一个裸机一步步的搭建属于自己定制的初步可用的操作系统。以后使用别人的配置如果出现问题了也大概能知道如何处理。

当然,我自己如今自己的机器也不是完全是这样,我主要使用的是YouTube上一个老外自己搞的一个DTOS,也是一个基于archlinux加其他工具配置起来的一个,对于工具我一项的主张是先找到别人好用的配置,然后根据自己的日常使用习惯进行修改,最后形成一套完全贴合自己的版本。在还不了解这个工具的情况从0开始配置一个是耗费时间,二是出现暂时无法解决的问题时会产生退却心理,第三个就是自己独立摸索出来的配置可能并不如一些大神配置的好用,最终可能会降低效率。


以上是关于dwm 美化的主要内容,如果未能解决你的问题,请参考以下文章

archlinux + dwm系统美化

在 Windows Vista/7 中重定向应用程序的图形输出(使用 DWM)

DWM1000 帧过滤代码实现

UWB DWM1000 开源项目框架 之 温度采集

窗口管理器 dwm安装

窗口管理器 dwm安装