dwm是linux系統下的一款使用c語言編寫的視窗管理器,dwm的特點就是小,核心程式碼只有幾千行,編譯後可執行檔案也僅有幾十KB,dwm不支援配置檔案,每次對dwm進行修改,例如字型顯示大小,只能通過修改原始碼,重新編譯。
dwm預設狀態列十分簡單,如下所示,預設情況下status只顯示dwm的版本號,使用者一般通過shell指令碼讓狀態列顯示更多的資訊,例如時間、電量、網速等資訊。接下來我們將使用rust編寫dwm status-bar應用。
+------+----------------------------------+--------+
| tags | title | status +
+------+---------------------+------------+--------+
| | |
| | |
| | |
| | |
| master | stack |
| | |
| | |
| | |
| | |
+----------------------------+---------------------+
通過以下命令可以設定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 協議》,轉載必須註明作者和本文連結