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

设置状态条

根据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

进入到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 ${velKB}KB/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 },
};

修改完成之后的样子如下


dwm-bar

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

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开始配置一个是耗费时间,二是出现暂时无法解决的问题时会产生退却心理,第三个就是自己独立摸索出来的配置可能并不如一些大神配置的好用,最终可能会降低效率。

<hr />

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容