From 36593527ca327f3474e21586c5750b1ac1cb681e Mon Sep 17 00:00:00 2001 From: Victor Timofei Date: Wed, 14 Jun 2023 15:25:23 +0300 Subject: [PATCH] Rewrite it in Rust --- .config/eww/scripts/launch.rs | 146 ++++++++++++++++++ .config/eww/templates/bar/eww.scss | 14 +- .config/eww/templates/bar/eww.yuck | 8 +- .../bar/modules/activeworkspaceid.yuck | 2 +- .config/eww/templates/bar/modules/bar.yuck | 8 +- .config/eww/templates/bar/modules/clock.scss | 2 +- .../eww/templates/bar/modules/management.scss | 2 +- .../eww/templates/bar/modules/management.yuck | 2 +- .config/eww/templates/bar/modules/sound.scss | 2 +- .config/eww/templates/bar/modules/sound.yuck | 2 +- .../eww/templates/bar/modules/weather.scss | 2 +- .config/eww/templates/bar/modules/widget.scss | 2 +- .../templates/bar/modules/widgets-panel.yuck | 6 +- .../eww/templates/bar/modules/workspaces.scss | 2 +- .../eww/templates/bar/modules/workspaces.yuck | 2 +- 15 files changed, 174 insertions(+), 28 deletions(-) create mode 100755 .config/eww/scripts/launch.rs diff --git a/.config/eww/scripts/launch.rs b/.config/eww/scripts/launch.rs new file mode 100755 index 0000000..d9b9fdd --- /dev/null +++ b/.config/eww/scripts/launch.rs @@ -0,0 +1,146 @@ +#!/usr/bin/env rust-script +//! +//! ```cargo +//! [dependencies] +//! serde = { version = "1.0", features = ["derive"] } +//! serde_json = "1.0" +//! anyhow = "1.0" +//! handlebars = "3" +//! ``` + +use serde::Deserialize; +use anyhow::Result; +use std::process::Command; +use std::{fs, io}; +use handlebars::Handlebars; +use std::collections::HashMap; + +#[derive(Deserialize, Debug)] +struct Monitor { + id: u32, + name: String, + width: u32, + height: u32, +} + +impl Monitor { + fn list() -> Result> { + let output = Command::new("hyprctl") + .arg("monitors") + .arg("-j") + .output()?; + + assert!(output.status.success()); + + let monitors_json = std::str::from_utf8(&output.stdout)?; + + Ok(serde_json::from_str(monitors_json)?) + } + + fn launch_bar(&self, wl_display: &str, home: &str) -> Result<()> { + let bar_name = format!("bar-{wl_display}-{}", self.id); + let dir = format!("/tmp/vbar/{wl_display}/{}", self.id); + + match fs::create_dir_all(&dir) { + Ok(()) => {}, + Err(e) if e.kind() == io::ErrorKind::AlreadyExists => { + let output = Command::new("rm") + .arg("-rf") + .arg(&dir) + .output()?; + assert!(output.status.success()); + + fs::create_dir_all(&dir)?; + }, + Err(e) => return Err(e.into()), + } + + self.generate_bar_config( + &bar_name, + &home, + &dir, + &format!("{home}/.config/eww/templates/bar"), + &dir, + )?; + + let output = Command::new("eww") + .arg("-c") + .arg(&dir) + .arg("reload") + .output()?; + assert!(output.status.success()); + + let output = Command::new("eww") + .arg("-c") + .arg(&dir) + .arg("open") + .arg(bar_name) + .output()?; + assert!(output.status.success()); + + Ok(()) + } + + fn generate_bar_config(&self, bar_name: &str, home: &str, base_dir: &str, source_dir: &str, dest_dir: &str) -> Result<()> { + for entry in fs::read_dir(source_dir)? { + let entry = entry?; + let path = entry.path(); + let relpath = path.strip_prefix(&source_dir)? + .to_str().unwrap(); + + if path.is_dir() { + fs::create_dir_all(&format!("{dest_dir}/{relpath}"))?; + + self.generate_bar_config( + &bar_name, + &home, + &base_dir, + &path.to_str().unwrap(), + &format!("{source_dir}/{relpath}"), + )?; + } else if path.is_file() { + let data = fs::read_to_string(&path)?; + let output = self.template(&data, &bar_name, &home, &base_dir)?; + + fs::write(format!("{dest_dir}/{relpath}"), output)?; + } + } + + Ok(()) + } + + fn template(&self, source: &str, bar_name: &str, home: &str, base_dir: &str) -> Result { + let height: u32 = (self.height as f32 * 0.02) as u32; + let id_str = self.id.to_string(); + let height_str = height.to_string(); + + let values: HashMap<&str, &str> = HashMap::from([ + ("monitor", id_str.as_str()), + ("monitor_name", self.name.as_str()), + ("bar_name", bar_name), + ("home", home), + ("base_dir", base_dir), + ("height", height_str.as_str()), + ]); + + let mut handlebars = Handlebars::new(); + handlebars.register_template_string("tpl", source)?; + Ok(handlebars.render("tpl", &values)?) + } +} + +fn main() -> Result<()> { + let wl_display = std::env::var_os("WAYLAND_DISPLAY").unwrap() + .into_string().unwrap(); + + let home = std::env::var_os("HOME").unwrap() + .into_string().unwrap(); + + let monitors = Monitor::list()?; + println!("{:?}", monitors); + for monitor in monitors { + monitor.launch_bar(&wl_display, &home)?; + } + + Ok(()) +} diff --git a/.config/eww/templates/bar/eww.scss b/.config/eww/templates/bar/eww.scss index d9b4bd2..3bce73d 100644 --- a/.config/eww/templates/bar/eww.scss +++ b/.config/eww/templates/bar/eww.scss @@ -1,10 +1,10 @@ -@import "$base_dir/modules/workspaces.scss"; -@import "$base_dir/modules/sound.scss"; -@import "$base_dir/modules/clock.scss"; -@import "$base_dir/modules/weather.scss"; -@import "$base_dir/modules/widget.scss"; -@import "$base_dir/modules/management.scss"; -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/modules/workspaces.scss"; +@import "{{ base_dir }}/modules/sound.scss"; +@import "{{ base_dir }}/modules/clock.scss"; +@import "{{ base_dir }}/modules/weather.scss"; +@import "{{ base_dir }}/modules/widget.scss"; +@import "{{ base_dir }}/modules/management.scss"; +@import "{{ base_dir }}/variables.scss"; *{ all: unset; diff --git a/.config/eww/templates/bar/eww.yuck b/.config/eww/templates/bar/eww.yuck index 4dca6c8..aae8c79 100644 --- a/.config/eww/templates/bar/eww.yuck +++ b/.config/eww/templates/bar/eww.yuck @@ -4,12 +4,12 @@ ; bar_name: The bar name (should be unique) ; monitor: The Hyprland monitor id ; monitor_name: The Hyprland monitor name -(include "$base_dir/modules/bar.yuck") +(include "{{ base_dir }}/modules/bar.yuck") -(defwindow $bar_name +(defwindow {{ bar_name }} :geometry (geometry :x "0" :y "15" :anchor "bottom center" - :height "$height" :width "60%") + :height "{{ height }}" :width "60%") :exclusive true - :monitor $monitor + :monitor {{ monitor }} (bar )) diff --git a/.config/eww/templates/bar/modules/activeworkspaceid.yuck b/.config/eww/templates/bar/modules/activeworkspaceid.yuck index 258c130..2452041 100644 --- a/.config/eww/templates/bar/modules/activeworkspaceid.yuck +++ b/.config/eww/templates/bar/modules/activeworkspaceid.yuck @@ -1,3 +1,3 @@ (deflisten activeworkspaceid :initial "2" - "$home/.config/eww/scripts/get-activeworkspace-id") + "{{ home }}/.config/eww/scripts/get-activeworkspace-id") diff --git a/.config/eww/templates/bar/modules/bar.yuck b/.config/eww/templates/bar/modules/bar.yuck index f7a59d9..116d7bd 100644 --- a/.config/eww/templates/bar/modules/bar.yuck +++ b/.config/eww/templates/bar/modules/bar.yuck @@ -1,7 +1,7 @@ -(include "$base_dir/modules/workspaces.yuck") -(include "$base_dir/modules/activeworkspaceid.yuck") -(include "$base_dir/modules/widgets-panel.yuck") -(include "$base_dir/modules/management.yuck") +(include "{{ base_dir }}/modules/workspaces.yuck") +(include "{{ base_dir }}/modules/activeworkspaceid.yuck") +(include "{{ base_dir }}/modules/widgets-panel.yuck") +(include "{{ base_dir }}/modules/management.yuck") (defwidget bar[] (box diff --git a/.config/eww/templates/bar/modules/clock.scss b/.config/eww/templates/bar/modules/clock.scss index 5d208b6..de47e69 100644 --- a/.config/eww/templates/bar/modules/clock.scss +++ b/.config/eww/templates/bar/modules/clock.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .clock { padding: .3rem; diff --git a/.config/eww/templates/bar/modules/management.scss b/.config/eww/templates/bar/modules/management.scss index 049a868..d64c76d 100644 --- a/.config/eww/templates/bar/modules/management.scss +++ b/.config/eww/templates/bar/modules/management.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .management { padding: .3rem; diff --git a/.config/eww/templates/bar/modules/management.yuck b/.config/eww/templates/bar/modules/management.yuck index f184911..94c210c 100644 --- a/.config/eww/templates/bar/modules/management.yuck +++ b/.config/eww/templates/bar/modules/management.yuck @@ -10,7 +10,7 @@ (defwidget lock[] (button :class "lock-btn btn" - :onclick "$home/.config/eww/scripts/lock" + :onclick "{{ home }}/.config/eww/scripts/lock" "󰌾")) (defwidget reboot[] diff --git a/.config/eww/templates/bar/modules/sound.scss b/.config/eww/templates/bar/modules/sound.scss index 5e6a1f0..6faf92b 100644 --- a/.config/eww/templates/bar/modules/sound.scss +++ b/.config/eww/templates/bar/modules/sound.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .volume-widget { padding: .3rem; diff --git a/.config/eww/templates/bar/modules/sound.yuck b/.config/eww/templates/bar/modules/sound.yuck index da5e724..8972d68 100644 --- a/.config/eww/templates/bar/modules/sound.yuck +++ b/.config/eww/templates/bar/modules/sound.yuck @@ -1,6 +1,6 @@ (deflisten volume :initial `{"value": 100, "is_muted": false}` - "$home/.config/eww/scripts/get-volume") + "{{ home }}/.config/eww/scripts/get-volume") (defwidget volume-widget[] (box diff --git a/.config/eww/templates/bar/modules/weather.scss b/.config/eww/templates/bar/modules/weather.scss index fc3a964..ad95e40 100644 --- a/.config/eww/templates/bar/modules/weather.scss +++ b/.config/eww/templates/bar/modules/weather.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .weather { padding: .3rem; diff --git a/.config/eww/templates/bar/modules/widget.scss b/.config/eww/templates/bar/modules/widget.scss index 133b8e7..460c8e7 100644 --- a/.config/eww/templates/bar/modules/widget.scss +++ b/.config/eww/templates/bar/modules/widget.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .widget { font-size: 1rem; diff --git a/.config/eww/templates/bar/modules/widgets-panel.yuck b/.config/eww/templates/bar/modules/widgets-panel.yuck index 1c7cd32..0b3f893 100644 --- a/.config/eww/templates/bar/modules/widgets-panel.yuck +++ b/.config/eww/templates/bar/modules/widgets-panel.yuck @@ -1,6 +1,6 @@ -(include "$base_dir/modules/sound.yuck") -(include "$base_dir/modules/clock.yuck") -(include "$base_dir/modules/weather.yuck") +(include "{{ base_dir }}/modules/sound.yuck") +(include "{{ base_dir }}/modules/clock.yuck") +(include "{{ base_dir }}/modules/weather.yuck") (defwidget widgets-panel[] (box diff --git a/.config/eww/templates/bar/modules/workspaces.scss b/.config/eww/templates/bar/modules/workspaces.scss index 3842913..0dc7b0e 100644 --- a/.config/eww/templates/bar/modules/workspaces.scss +++ b/.config/eww/templates/bar/modules/workspaces.scss @@ -1,4 +1,4 @@ -@import "$base_dir/variables.scss"; +@import "{{ base_dir }}/variables.scss"; .workspaces-widget { margin-left: .4rem; diff --git a/.config/eww/templates/bar/modules/workspaces.yuck b/.config/eww/templates/bar/modules/workspaces.yuck index 7246d56..d7a1ae1 100644 --- a/.config/eww/templates/bar/modules/workspaces.yuck +++ b/.config/eww/templates/bar/modules/workspaces.yuck @@ -1,6 +1,6 @@ (deflisten workspaces :initial "[]" - "$home/.config/eww/scripts/get-workspaces $monitor_name") + "{{ home }}/.config/eww/scripts/get-workspaces {{ monitor_name }}") (defwidget workspaces-widget[] (box