使用rust编写dwm status-bar应用程序

dwm简单介绍

dwm是linux系统下的一款使用c语言编写的窗口管理器,dwm的特点就是小,核心代码只有几千行,编译后可执行文件也仅有几十KB,dwm不支持配置文件,每次对dwm进行修改,例如字体显示大小,只能通过修改源代码,重新编译。

dwm状态栏

dwm默认状态栏十分简单,如下所示,默认情况下status只显示dwm的版本号,用户一般通过shell脚本让状态栏显示更多的信息,例如时间、电量、网速等信息。接下来我们将使用rust编写dwm status-bar应用。

    +------+----------------------------------+--------+
    | tags | title                            | status +
    +------+---------------------+------------+--------+
    |                            |                     |
    |                            |                     |
    |                            |                     |
    |                            |                     |
    |          master            |        stack        |
    |                            |                     |
    |                            |                     |
    |                            |                     |
    |                            |                     |
    +----------------------------+---------------------+

创建status-bar应用

  • 通过以下命令可以设置dwm状态栏信息

    ❯ xsetroot -name "$(date)"
  • 创建一个rust项目

    ❯ cargo new status-bar
  • 编写一个可以执行linux命令的函数,如果你的linux系统没有dash shell,可以安装一个或者把下面代码中的dash改为bash

    pub fn exec_cmd(command: &str) -> Result<String, FromUtf8Error> {
      let output = Command::new("/bin/dash")
          .arg("-c")
          .arg(command)
          .output()
          .expect("error");
      let result = String::from_utf8(output.stdout);
      result
    }

接下来以电池信息获取举例

  • 创建电池结构体,电池图标可以去nerd font官网找以下

    pub struct Battery {
      // 电池图标
      icon: Vec<String>,
      // 电池电量等级
      level: usize,
      // 是否充电
      charge: bool,
      // 电池电量
      quantity: usize,
      // 更新时间
      timestamp: u64,
    }
  • 获取电池充电信息

      // 获取电池状态,通过读取系统文件内容获取充电状态
      fn get_battery_status() -> bool {
          let charge: bool;
          let result = fs::read_to_string("/sys/class/power_supply/BAT0/status");
          match result {
              Ok(content) => {
                  if content.contains("Charging") {
                      charge = true;
                  } else {
                      charge = false;
                  }
              },
              Err(err) => {
                  charge = true;
                  eprintln!("get battery status failed: {}", err);
              },
          }
          charge
      }
  • 获取电池电量

      // 获取电池电量,通过读取系统文件获取电量信息
      fn get_battery_quantity() -> usize {
          let quantity: usize;
          let result = fs::read_to_string("/sys/class/power_supply/BAT0/capacity");
          match result {
              Ok(content) => {
                  quantity = content.replace("\n", "").parse().unwrap();
              },
              Err(err) => {
                  quantity = 100;
                  eprintln!("get battery quantity failed: {}", err);
              },
          }
          quantity
      }
  • 电池的这两个状态,充电状态需要频繁更新,但是电量更新一般不需要过于频繁

      fn update(&mut self) {
          self.charge = Battery::get_battery_status();
          let current = util::timestamp();
          // 通过上次更新时间戳和当前时间对比判断是否更新电量信息
          if current - self.timestamp > UPDATE_RATE {
              self.quantity = Battery::get_battery_quantity();
              self.level = (self.quantity + 10) / 25;
              self.timestamp = current;
          }
      }
  • 将获取的信息展示到dwm状态栏,这里用到了之前写的执行linux命令方法

    // 设置状态栏
    pub fn set_bar(msg: &String) {
      let cmd = format!("xsetroot -name ' {} '", msg.replace("\n", ""));
      let res = exec_cmd(cmd.as_str());
      match res {
          Ok(_) => {}
          Err(err) => {
              eprintln!("xsetroot error, err is {}", err);
          }
      }
    }

    其他

    这个小项目是我学习rust的时候写的,我认为通过写项目是学习一本编程语言最快的方法。本文只是简单介绍了dwm状态栏这个小软件的设计思路,具体代码大家可以去我的gitee主页查看。
    status-bar: gitee.com/rcxid/status-bar.git

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!