walrs
pywal but if its Fast-Minimal-Simple
git clone https://git.pi66.xyz/walrs
About | Files | Commits | Refs | License
debloat main.rs
Author: pixel2175
Date: 2025-06-04 23:01
commit: ba6c2540
Stat
| M | Cargo.lock | 2 | +1 | -1 |
| M | Cargo.toml | 2 | +1 | -1 |
| M | src/create_templates.rs | 36 | +18 | -18 |
| M | src/get_colors.rs | 31 | +22 | -9 |
| M | src/main.rs | 171 | +42 | -129 |
| M | src/reload.rs | 68 | +44 | -24 |
| M | src/theme.rs | 53 | +37 | -16 |
| M | src/utils.rs | 48 | +41 | -7 |
| M | src/wallpaper.rs | 72 | +29 | -43 |
Diff
diff --git a/Cargo.lock b/Cargo.lock
index 18acd8d..62b8a3b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1226,7 +1226,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walrs"
-version = "1.1.1"
+version = "1.1.2"
dependencies = [
"argh",
"color-thief",
diff --git a/Cargo.toml b/Cargo.toml
index 48b633e..3bec2b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "walrs"
...
Show all
Show less
diff --git a/Cargo.lock b/Cargo.lock
index 18acd8d..62b8a3b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1226,7 +1226,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walrs"
-version = "1.1.1"
+version = "1.1.2"
dependencies = [
"argh",
"color-thief",
diff --git a/Cargo.toml b/Cargo.toml
index 48b633e..3bec2b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "walrs"
...
diff --git a/Cargo.lock b/Cargo.lock
index 18acd8d..62b8a3b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1226,7 +1226,7 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walrs"
-version = "1.1.1"
+version = "1.1.2"
dependencies = [
"argh",
"color-thief",
diff --git a/Cargo.toml b/Cargo.toml
index 48b633e..3bec2b8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "walrs"
-version = "1.1.1"
+version = "1.1.2"
edition = "2024"
description = "walrs - Generate colorscheme from image."
license = "GPL-3.0"
diff --git a/src/create_templates.rs b/src/create_templates.rs
index 876bbd7..2357cd1 100644
--- a/src/create_templates.rs
+++ b/src/create_templates.rs
@@ -8,19 +8,19 @@ fn change(template: &str, colors: (u8, u8, u8), alpha: u8) -> String {
let (r, g, b) = colors;
if template.contains(".strip") {
- format!("{:02x}{:02x}{:02x}", r, g, b)
+ format!("{r:02x}{g:02x}{b:02x}")
} else if template.contains(".xrgba") {
- format!("{:02x}/{:02x}/{:02x}/{:02x}", r, g, b, alpha)
+ format!("{r:02x}/{g:02x}/{b:02x}/{alpha:02x}")
} else if template.contains(".rgba") {
- format!("{},{},{},{}", r, g, b, alpha)
+ format!("{r},{g},{b},{alpha}")
} else if template.contains(".rgb") {
- format!("{},{},{}", r, g, b)
+ format!("{r},{g},{b}")
} else if template.contains(".alpha_per") {
format!("{:.1}", (alpha / 255) * 100)
} else if template.contains(".alpha") {
- format!("#{:02x}{:02x}{:02x}{:02x}", r, g, b, alpha)
+ format!("#{r:02x}{g:02x}{b:02x}{alpha:02x}")
} else {
- format!("#{:02x}{:02x}{:02x}", r, g, b)
+ format!("#{r:02x}{g:02x}{b:02x}")
}
}
@@ -33,7 +33,7 @@ fn fill_template(
) {
let output_path = format!(
"{}/wal/{}",
- get_cache(send).to_string_lossy().to_string(),
+ get_cache(send).to_string_lossy(),
template_name
);
let alpha = colors.1;
@@ -92,13 +92,13 @@ fn fill_template(
let color = colors.0[i];
let patterns = [
- format!("{{color{}.strip}}", i),
- format!("{{color{}.xrgba}}", i),
- format!("{{color{}.rgba}}", i),
- format!("{{color{}.rgb}}", i),
- format!("{{color{}.alpha_dec}}", i),
- format!("{{color{}.alpha}}", i),
- format!("{{color{}}}", i),
+ format!("{{color{i}.strip}}"),
+ format!("{{color{i}.xrgba}}"),
+ format!("{{color{i}.rgba}}"),
+ format!("{{color{i}.rgb}}"),
+ format!("{{color{i}.alpha_dec}}"),
+ format!("{{color{i}.alpha}}"),
+ format!("{{color{i}}}"),
];
for pattern in patterns {
@@ -111,7 +111,7 @@ fn fill_template(
let checksum = colors
.0
.iter()
- .map(|(r, g, b)| format!("{:02X}{:02X}{:02X}", r, g, b))
+ .map(|(r, g, b)| format!("{r:02X}{g:02X}{b:02X}"))
.collect::<Vec<String>>()
.join("");
result = result.replace("{checksum}", &checksum);
@@ -124,9 +124,9 @@ pub fn create_template(colors: (Vec<(u8, u8, u8)>, u8), wallpaper: &str, send: b
let system_template_path = "/etc/walrs/templates/";
let user_template_path = format!(
"{}/walrs/templates/",
- get_config(send).to_string_lossy().to_string()
+ get_config(send).to_string_lossy()
);
- let cache_path = format!("{}/wal/", get_cache(send).to_string_lossy().to_string());
+ let cache_path = format!("{}/wal/", get_cache(send).to_string_lossy());
create_dir_all(&cache_path).unwrap_or_else(|_| {
warning("Create", "can't create the cache folder", send);
exit(1)
@@ -167,7 +167,7 @@ pub fn create_template(colors: (Vec<(u8, u8, u8)>, u8), wallpaper: &str, send: b
};
// Copy template to user directory
- let user_file_path = format!("{}{}", user_template_path, name);
+ let user_file_path = format!("{user_template_path}{name}");
let _ = write(&user_file_path, &content);
fill_template(&name, &content, &colors, wallpaper, send);
diff --git a/src/get_colors.rs b/src/get_colors.rs
index 801987f..c54b2b9 100644
--- a/src/get_colors.rs
+++ b/src/get_colors.rs
@@ -55,7 +55,7 @@ fn kmeans_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> {
.map(|&lab| Srgb::from_color(lab))
.collect();
- return palette_kmeans
+ palette_kmeans
.iter()
.map(|color| {
let (r, g, b) = (
@@ -65,7 +65,7 @@ fn kmeans_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> {
);
(r, g, b)
})
- .collect::<Vec<(u8, u8, u8)>>();
+ .collect::<Vec<(u8, u8, u8)>>()
}
fn color_thief_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> {
@@ -77,10 +77,10 @@ fn color_thief_colors(len: u8, native_rgba: RgbaImage) -> Vec<(u8, u8, u8)> {
palette_extract::PixelFilter::White,
);
- return palette_extract
+ palette_extract
.iter()
.map(|color| (color.r, color.g, color.b))
- .collect::<Vec<(u8, u8, u8)>>();
+ .collect::<Vec<(u8, u8, u8)>>()
}
fn palette_extract_colors(len: u8, native_rgba: RgbaImage, send: bool) -> Vec<(u8, u8, u8)> {
@@ -90,14 +90,27 @@ fn palette_extract_colors(len: u8, native_rgba: RgbaImage, send: bool) -> Vec<(u
exit(1)
});
- return palette_thief
+ palette_thief
.iter()
.map(|color| (color.r, color.g, color.b))
- .collect::<Vec<(u8, u8, u8)>>();
+ .collect::<Vec<(u8, u8, u8)>>()
}
fn extract_colors(len: u8, backend: &str, native_rgba: RgbaImage, send: bool) -> Vec<(u8, u8, u8)> {
match backend {
+ "backends" => {
+ println!(
+ "┌──────────────────────┬───────────────────────┐
+│ Method │ Description │
+├──────────────────────┼───────────────────────┤
+│ kmeans │ best colors, slow │
+│ color_thief │ balanced │
+│ palette_extract │ fast, weak colors │
+│ all │ use all methods │
+└──────────────────────┴───────────────────────┘"
+ );
+ exit(0)
+ }
"kmeans" => kmeans_colors(10, native_rgba),
"color_thief" => color_thief_colors(10, native_rgba),
"palette_extract" => palette_extract_colors(10, native_rgba, send),
@@ -108,12 +121,12 @@ fn extract_colors(len: u8, backend: &str, native_rgba: RgbaImage, send: bool) ->
.for_each(|c| {
collected.push(*c);
});
- color_thief_colors(len / 3 as u8, native_rgba.clone())
+ color_thief_colors(len / 3_u8, native_rgba.clone())
.iter()
.for_each(|c| {
collected.push(*c);
});
- palette_extract_colors(len / 3 as u8, native_rgba, send)
+ palette_extract_colors(len / 3_u8, native_rgba, send)
.iter()
.for_each(|c| {
collected.push(*c);
@@ -150,7 +163,7 @@ pub fn get_colors(
let image = core_image.resize(
400,
- (core_image.height() as f32 * (400 as f32 / core_image.width() as f32)) as u32,
+ (core_image.height() as f32 * (400_f32 / core_image.width() as f32)) as u32,
image::imageops::FilterType::Lanczos3,
);
diff --git a/src/main.rs b/src/main.rs
index 0ee2e25..313ac99 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,7 +12,7 @@ use reload::reload;
use std::fs::{copy, create_dir_all};
use std::path::Path;
use std::process::exit;
-use theme::{collect_themes, set_theme};
+use theme::{print_themes, set_theme, theme_exists};
use utils::*;
#[derive(FromArgs)]
@@ -92,176 +92,89 @@ struct Arg {
version: bool,
}
-fn image_path(image: Option<String>, send: bool) -> String {
- match image {
- Some(ref v) if Path::new(v).exists() => match get_absolute_path(v) {
- Some(p) => {
- if Path::new(&p).is_file() {
- p
- } else {
- std::str::from_utf8(
- &std::process::Command::new("sh")
- .arg("-c")
- .arg(format!("find "{}" -type f | sort -R | head -n1", p))
- .output()
- .unwrap()
- .stdout,
- )
- .unwrap()
- .trim()
- .to_string()
- }
- }
- None => {
- warning("Wallpaper", "Can't find wallpaper absolute path!", send);
- exit(1);
- }
- },
- Some(_) => {
- warning("Image", "Image does not exist", send);
- exit(1);
- }
- None => {
- warning("Image", "Can't find Image", send);
- exit(1);
- }
- }
-}
-
-fn print_themes(send: bool) {
- let (dark, light) = (collect_themes("dark", send), collect_themes("light", send));
-
- println!("[\x1b[33mDark\x1b[0m]");
- for theme in dark {
- println!(" -{theme}")
- }
-
- println!("[\x1b[33mLight\x1b[0m]");
- for theme in light {
- println!(" -{theme}")
- }
-}
-
fn main() {
+ // get and load args from user
let arg: Arg = argh::from_env();
+ // save the quit status
+ let send = !arg.quit;
+ // save the backend
let backend = match arg.backend {
- Some(v) => {
- if v == "backends" {
- println!(
- "┌──────────────────────┬───────────────────────┐
-│ Method │ Description │
-├──────────────────────┼───────────────────────┤
-│ kmeans │ best colors, slow │
-│ color_thief │ balanced │
-│ palette_extract │ fast, weak colors │
-│ all │ use all methods │
-└──────────────────────┴───────────────────────┘"
- );
- exit(0)
- } else {
- v
- }
- }
+ Some(v) => v,
None => "all".to_string(),
};
+ // print the version
if arg.version {
- info(
- "Version",
- &format!("walrs {}", env!("CARGO_PKG_VERSION")),
- !arg.quit,
- );
+ info("Version", env!("CARGO_PKG_VERSION"), send);
exit(0);
}
+ // reload colors without setting wallpaper
if arg.reload_no {
- reload(!arg.quit, true);
+ reload(send, true);
exit(0);
}
+ // reload colors with setting wallpaper
if arg.reload {
- reload(!arg.quit, false);
+ reload(send, false);
exit(0);
}
+ // if user didn't type any thing
if arg.image.is_none() && arg.theme.is_none() && arg.generate.is_none() {
- println!("Usage: walrs [-i <image>] [-k <backend>] [-r] [-R] [-t <theme>] [-g <generate>] [-s <saturation>] [-b <brightness>] [-q] [-v]
-
-walrs - Generate colorscheme from image
-
-Options:
- -i, --image path/to/your/wal.png | path/to/your/wallpapers/
- -k, --backend change the colors backend (walrs -k backends)
- -r, --reload reload without changing the wallpaper
- -R, --reload-no reload with changing the wallpaper
- -t, --theme use external theme file
- -g, --generate generate theme in themes folder (.cache/wal/colorschemes)
- -s, --saturation specify the saturation value -128 => 127
- -b, --brightness specify the brightness value -128 => 127
- -q, --quit set quit mode (no output)
- -v, --version version
- --help, help display usage information
-");
+ warning("Args", "run: walrs --help", send);
exit(1);
}
+ // show or set theme from user
if let Some(v) = arg.theme {
if v == "themes" {
- print_themes(!arg.quit);
+ print_themes(send);
} else {
- if get_config(!arg.quit)
- .join("wal")
- .join("colorscheme")
- .exists()
- || get_config(!arg.quit)
- .join("walrs")
- .join("colorscheme")
- .exists()
- {
- set_theme(v, !arg.quit);
+ let config = get_config(send);
+ if theme_exists(&config) {
+ set_theme(v, send);
} else {
- create_dir_all(&format!(
- "{}/walrs/colorschemes",
- get_config(!arg.quit).to_string_lossy().to_string()
- ))
- .unwrap();
+ let colorschemes_dir = get_config(send).join("walrs").join("colorschemes");
+ create_dir_all(&colorschemes_dir).unwrap();
+ let etc = Path::new("/etc/");
+ if !theme_exists(etc) {
+ warning("theme", "Can't find configuration directory", send);
+ exit(1)
+ }
run(&format!(
- "cp -r /etc/walrs/colorschemes/* {}/walrs/colorschemes",
- get_config(!arg.quit).to_string_lossy().to_string()
+ "cp -r /etc/walrs/colorschemes/* {}",
+ colorschemes_dir.display()
));
- set_theme(v, !arg.quit);
+ set_theme(v, send);
};
}
exit(0);
}
+ // generate a new theme from current colors
if let Some(v) = arg.generate {
- let dis = get_config(!arg.quit).join("walrs").join("colorschemes");
- create_dir_all(&dis.join("dark")).unwrap();
+ let dis = get_config(send).join("walrs").join("colorschemes");
+ create_dir_all(dis.join("dark")).unwrap();
copy(
- get_config(!arg.quit).join("wal").join("colors"),
+ get_cache(send).join("wal").join("colors"),
dis.join("dark").join(v),
)
.unwrap();
- info("Generate", "generate colors", !arg.quit);
+ info("Generate", "generate colors", send);
exit(0);
};
+ // analyze the image and generate the palette
if arg.image.is_some() {
- let image_path = image_path(arg.image, !arg.quit);
-
- let palette = get_colors(
- &image_path,
- &backend,
- !arg.quit,
- arg.brightness,
- arg.saturation,
- );
- info("Generate", "generate colors", !arg.quit);
+ let image_path = image_path(arg.image, send);
+ let palette = get_colors(&image_path, &backend, send, arg.brightness, arg.saturation);
+ info("Generate", "generate colors", send);
- create_template(palette, &image_path, !arg.quit);
- info("Template", "create templates", !arg.quit);
+ create_template(palette, &image_path, send);
+ info("Template", "create templates", send);
- reload(!arg.quit, true);
- print_colors(!arg.quit);
+ reload(send, true);
+ print_colors(send);
};
}
diff --git a/src/reload.rs b/src/reload.rs
index 98130a2..c45ae88 100644
--- a/src/reload.rs
+++ b/src/reload.rs
@@ -1,29 +1,34 @@
+use crate::utils::{get_cache, get_config, info, run, warning};
+use crate::wallpaper::change_wallpaper;
use std::fs::{create_dir_all, OpenOptions};
use std::fs::{read_dir, read_to_string};
use std::io::Write;
-
-use crate::utils::{get_cache, get_home, info, run, warning};
-use crate::wallpaper;
+use std::path::Path;
+use std::process::exit;
fn colors(colors: Vec<String>, send: bool) {
- for i in read_dir("/dev/pts/").expect("Can't load terminals") {
+ for i in read_dir("/dev/pts/").unwrap_or_else(|_| {
+ warning("Terminal", "Unable to find open terminals", send);
+ exit(1)
+ }) {
let file = i.unwrap().file_name().into_string().unwrap();
if file != "ptmx" && file.parse::<i32>().is_ok() {
let special_index = [(10, 7), (11, 0), (12, 15), (708, 5)];
let term = file.parse::<i32>().unwrap();
for (i, value) in colors.iter().enumerate() {
- let sequence = format!("\x1b]4;{};{}\x1b\", i, value);
-
+ let sequence = format!("\x1b]4;{i};{value}\x1b\");
if let Ok(mut file) = OpenOptions::new()
.write(true)
- .open(format!("/dev/pts/{}", term))
+ .open(format!("/dev/pts/{term}"))
{
- let _ = file.write_all(sequence.as_bytes());
+ file.write_all(sequence.as_bytes()).unwrap_or_else(|_| {
+ warning("Colors", "Can't apply terminal colors", send);
+ });
};
}
if let Ok(mut file) = OpenOptions::new()
.write(true)
- .open(format!("/dev/pts/{}", term))
+ .open(format!("/dev/pts/{term}"))
{
for (i, v) in special_index {
let sequence = format!("\x1b]{};{}\x1b\", i, colors[v]);
@@ -36,42 +41,58 @@ fn colors(colors: Vec<String>, send: bool) {
info("Terminal", "terminal colorscheme set", send);
}
+// read ~/.cache/wal/wal file and return the wallpaper path
+pub fn get_wallpaper(cache: &Path, send: bool) -> String {
+
+ read_to_string(cache.join("wal"))
+ .unwrap_or_else(|_| {
+ warning("Wallpaper", "Can't find the wallpaper", send);
+ exit(1)
+ })
+ .lines()
+ .next()
+ .unwrap()
+ .trim()
+ .to_string()
+}
+
pub fn reload(send: bool, set_wal: bool) {
- let cache = get_cache(send).to_string_lossy().to_string();
- let file_path = format!("{}/wal/colors", cache);
+ let cache = get_cache(send).join("wal");
+ let file_path = cache.join("colors");
+ // read the colors file and load all the colors
let lines: Vec<String> = std::fs::read_to_string(&file_path)
- .expect("Can't load colors")
+ .unwrap_or_else(|_| {
+ warning("Colors", "can't read colors", send);
+ exit(1)
+ })
.lines()
.map(|line| line.to_string())
.collect();
+ // applie the wallpaper
if set_wal {
- let wallpaper = read_to_string(format!("{}/wal/wal", cache))
- .expect("run 'cp /etc/walrs/templates/wal ~/.config/walrs/templates/' and restart app")
- .lines()
- .next()
- .unwrap()
- .trim()
- .to_string();
- wallpaper::change_wallpaper(wallpaper.as_str(), send);
+ change_wallpaper(&get_wallpaper(&cache, send), send);
}
- colors(lines, send);
- let scripts_dir = get_home(send).join(".config").join("walrs").join("scripts");
+ // change terminal colors
+ colors(lines, send);
+ // initial scripts files
+ let scripts_dir = get_config(send).join("walrs").join("scripts");
if !scripts_dir.exists() {
match create_dir_all(&scripts_dir) {
Ok(_) => {
run(&format!(
"cp /etc/walrs/scripts/* {}",
- scripts_dir.to_string_lossy().to_string()
+ scripts_dir.to_string_lossy()
));
}
Err(_) => return,
}
}
+ // read the scripts directory and run them
match read_dir(scripts_dir) {
Ok(v) => {
for scr in v {
@@ -97,6 +118,5 @@ pub fn reload(send: bool, set_wal: bool) {
}
_ => return,
}
-
info("Colors", "colorscheme applied successfully", send);
}
diff --git a/src/theme.rs b/src/theme.rs
index 04d9664..eac2838 100644
--- a/src/theme.rs
+++ b/src/theme.rs
@@ -4,8 +4,27 @@ use crate::{
utils::{get_config, run, warning},
};
use std::fs::{create_dir_all, read_dir, read_to_string};
+use std::path::Path;
use std::process::exit;
+pub fn theme_exists(dir: &Path) -> bool {
+ dir.join("walrs").join("colorscheme").exists() || dir.join("wal").join("colorscheme").exists()
+}
+
+pub fn print_themes(send: bool) {
+ let (dark, light) = (collect_themes("dark", send), collect_themes("light", send));
+
+ println!("[\x1b[33mDark\x1b[0m]");
+ for theme in dark {
+ println!(" -{theme}")
+ }
+
+ println!("[\x1b[33mLight\x1b[0m]");
+ for theme in light {
+ println!(" -{theme}")
+ }
+}
+
pub fn collect_themes(subdir: &str, send: bool) -> Vec<String> {
let base = get_config(send);
let mut themes = vec![];
@@ -23,7 +42,18 @@ pub fn collect_themes(subdir: &str, send: bool) -> Vec<String> {
themes
}
+fn hex_to_rgb(file: Vec<String>) -> Vec<(u8, u8, u8)> {
+ file.iter()
+ .map(|h| {
+ u32::from_str_radix(&h[1..], 16)
+ .map(|v| ((v >> 16) as u8, (v >> 8 & 0xFF) as u8, (v & 0xFF) as u8))
+ })
+ .collect::<Result<Vec<_>, _>>()
+ .unwrap()
+}
+
pub fn set_theme(theme_name: String, send: bool) {
+ let base = get_config(send);
let mut theme: Vec<String> = ["dark", "light"]
.iter()
.flat_map(|variant| collect_themes(variant, send))
@@ -34,35 +64,26 @@ pub fn set_theme(theme_name: String, send: bool) {
create_dir_all(&dis).unwrap();
run(&format!(
"cp -r /etc/walrs/colorschemes/* {}/walrs/colorschemes",
- get_config(send).to_string_lossy().to_string()
+ base.display()
));
}
theme.sort();
theme.dedup();
if theme.contains(&theme_name) {
- let base = get_config(send);
-
let file: Vec<String> = [
- base.join("wal/colorschemes/dark").join(&theme_name),
- base.join("wal/colorschemes/light").join(&theme_name),
- base.join("walrs/colorschemes/dark").join(&theme_name),
- base.join("walrs/colorschemes/light").join(&theme_name),
+ base.join("wal/colorschemes/dark"),
+ base.join("wal/colorschemes/light"),
+ base.join("walrs/colorschemes/dark"),
+ base.join("walrs/colorschemes/light"),
]
.into_iter()
- .find_map(|p| read_to_string(p).ok())
+ .find_map(|p| read_to_string(p.join(&theme_name)).ok())
.unwrap()
.lines()
.map(|l| l.to_string())
.collect();
- let rgb_colors = file
- .iter()
- .map(|h| {
- u32::from_str_radix(&h[1..], 16)
- .map(|v| ((v >> 16) as u8, (v >> 8 & 0xFF) as u8, (v & 0xFF) as u8))
- })
- .collect::<Result<Vec<_>, _>>()
- .unwrap();
+ let rgb_colors = hex_to_rgb(file);
create_template((rgb_colors, 100), "None", send);
reload(send, false);
diff --git a/src/utils.rs b/src/utils.rs
index 1b6083e..6643391 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -3,6 +3,42 @@ use std::path::{Path, PathBuf};
use std::process::{exit, Stdio};
use std::{fs, process::Command};
+pub fn image_path(image: Option<String>, send: bool) -> String {
+ match image {
+ Some(ref v) if Path::new(v).exists() => match get_absolute_path(v) {
+ Some(p) => {
+ if Path::new(&p).is_file() {
+ p
+ } else {
+ std::str::from_utf8(
+ &std::process::Command::new("sh")
+ .arg("-c")
+ .arg(format!("find "{p}" -type f | sort -R | head -n1"))
+ .output()
+ .unwrap()
+ .stdout,
+ )
+ .unwrap()
+ .trim()
+ .to_string()
+ }
+ }
+ None => {
+ warning("Wallpaper", "Can't find wallpaper absolute path!", send);
+ exit(1);
+ }
+ },
+ Some(_) => {
+ warning("Image", "Image does not exist", send);
+ exit(1);
+ }
+ None => {
+ warning("Image", "Can't find Image", send);
+ exit(1);
+ }
+ }
+}
+
pub fn run(command: &str) -> bool {
Command::new("sh")
.arg("-c")
@@ -15,16 +51,14 @@ pub fn run(command: &str) -> bool {
}
pub fn print_colors(send: bool) {
- if send {
- if let Ok(output) = Command::new("bash")
+ if send
+ && let Ok(output) = Command::new("bash")
.arg("-c")
.arg(r#"for i in {30..37} 90; do echo -en "\033[0;${i}m●\033[0m "; done; echo"#)
.output()
- {
- if output.status.success() {
- print!("{}", String::from_utf8_lossy(&output.stdout));
- }
- }
+ && output.status.success()
+ {
+ print!("{}", String::from_utf8_lossy(&output.stdout));
}
}
diff --git a/src/wallpaper.rs b/src/wallpaper.rs
index f0e81e2..cae0ce4 100644
--- a/src/wallpaper.rs
+++ b/src/wallpaper.rs
@@ -69,8 +69,8 @@ fn get_desktop_env() -> Option<String> {
// Check for other environment variables
for key in keys.iter() {
- if let Ok(val) = env::var(key) {
- if !val.is_empty() {
+ if let Ok(val) = env::var(key)
+ && !val.is_empty() {
if *key == "DESKTOP_STARTUP_ID" && val.contains("awesome") {
return Some("AWESOME".to_string());
}
@@ -83,24 +83,23 @@ fn get_desktop_env() -> Option<String> {
return Some(val);
}
}
- }
}
None
}
fn set_wm_wallpaper(img: &str, send: bool) {
if run("which xwallpaper") {
- spawn(&format!("xwallpaper --zoom '{}'", img));
+ spawn(&format!("xwallpaper --zoom '{img}'"));
info("Wallpaper", "wallpaper set with xwallpaper", send);
} else if run("which feh") {
// I thought there was a problem, but there isn't.
- spawn(&format!("feh --no-fehbg --bg-fill '{}'", img));
+ spawn(&format!("feh --no-fehbg --bg-fill '{img}'"));
info("Wallpaper", "wallpaper set with feh", send);
} else if run("which hsetroot") {
- spawn(&format!("hsetroot -fill '{}'", img));
+ spawn(&format!("hsetroot -fill '{img}'"));
info("Wallpaper", "wallpaper set with hsetroot", send);
} else if run("which nitrogen") {
- spawn(&format!("nitrogen --set-zoom-fill --save '{}'", img));
+ spawn(&format!("nitrogen --set-zoom-fill --save '{img}'"));
info("Wallpaper", "wallpaper set with nitrogen", send);
} else if run("which xsetroot") {
warning(
@@ -147,8 +146,7 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
} else {
// Fallback to default monitor
spawn(&format!(
- "xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/last-image --set '{}'",
- abs_path
+ "xfconf-query --channel xfce4-desktop --property /backdrop/screen0/monitor0/workspace0/last-image --set '{abs_path}'"
));
}
info("Wallpaper", "wallpaper set with XFCE settings", send);
@@ -157,31 +155,26 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
if run("gsettings get org.gnome.desktop.background picture-uri-dark") {
// GNOME 42+ with light/dark mode support
spawn(&format!(
- "gsettings set org.gnome.desktop.background picture-uri 'file://{}'",
- abs_path
+ "gsettings set org.gnome.desktop.background picture-uri 'file://{abs_path}'"
));
spawn(&format!(
- "gsettings set org.gnome.desktop.background picture-uri-dark 'file://{}'",
- abs_path
+ "gsettings set org.gnome.desktop.background picture-uri-dark 'file://{abs_path}'"
));
} else {
// Older GNOME versions
spawn(&format!(
- "gsettings set org.gnome.desktop.background picture-uri 'file://{}'",
- abs_path
+ "gsettings set org.gnome.desktop.background picture-uri 'file://{abs_path}'"
));
}
info("Wallpaper", "wallpaper set with GNOME settings", send);
} else if d.contains("mate") {
spawn(&format!(
- "gsettings set org.mate.background picture-filename '{}'",
- abs_path
+ "gsettings set org.mate.background picture-filename '{abs_path}'"
));
info("Wallpaper", "wallpaper set with MATE settings", send);
} else if d.contains("cinnamon") {
spawn(&format!(
- "gsettings set org.cinnamon.desktop.background picture-uri 'file://{}'",
- abs_path
+ "gsettings set org.cinnamon.desktop.background picture-uri 'file://{abs_path}'"
));
info("Wallpaper", "wallpaper set with Cinnamon settings", send);
} else if d == "sway" {
@@ -190,12 +183,11 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
spawn("swww init");
}
spawn(&format!(
- "swww img '{}' --transition-type fade --transition-fps 60",
- abs_path
+ "swww img '{abs_path}' --transition-type fade --transition-fps 60"
));
info("Wallpaper", "wallpaper set with swww for Sway", send);
} else if run("which swaybg") {
- spawn(&format!("pkill swaybg; swaybg -i '{}' -m fill &", abs_path));
+ spawn(&format!("pkill swaybg; swaybg -i '{abs_path}' -m fill &"));
info("Wallpaper", "wallpaper set with swaybg for Sway", send);
} else {
warning(
@@ -207,24 +199,21 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
}
} else if d.contains("awesome") {
spawn(&format!(
- "awesome-client "require('gears').wallpaper.maximized('{}')"",
- abs_path
+ "awesome-client "require('gears').wallpaper.maximized('{abs_path}')""
));
info("Wallpaper", "wallpaper set with Awesome WM", send);
} else if d.contains("kde") || d.contains("plasma") {
let script = format!(
- r#"var allDesktops = desktops();for (i=0;i<allDesktops.length;i++){{d = allDesktops[i];d.wallpaperPlugin = "org.kde.image";d.currentConfigGroup = Array("Wallpaper", "org.kde.image", "General");d.writeConfig("Image", "{}");}}"#,
- abs_path
+ r#"var allDesktops = desktops();for (i=0;i<allDesktops.length;i++){{d = allDesktops[i];d.wallpaperPlugin = "org.kde.image";d.currentConfigGroup = Array("Wallpaper", "org.kde.image", "General");d.writeConfig("Image", "{abs_path}");}}"#
);
spawn(&format!(
- "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "{}"",
- script
+ "qdbus org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell.evaluateScript "{script}""
));
info("Wallpaper", "wallpaper set with KDE Plasma settings", send);
} else if d.contains("i3") {
// i3 support
if run("which feh") {
- spawn(&format!("feh --no-fehbg --bg-fill '{}'", abs_path));
+ spawn(&format!("feh --no-fehbg --bg-fill '{abs_path}'"));
info("Wallpaper", "wallpaper set with feh for i3", send);
} else {
set_wm_wallpaper(&abs_path, send);
@@ -232,7 +221,7 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
} else if d.contains("bspwm") {
// bspwm support
if run("which feh") {
- spawn(&format!("feh --no-fehbg --bg-fill '{}'", abs_path));
+ spawn(&format!("feh --no-fehbg --bg-fill '{abs_path}'"));
info("Wallpaper", "wallpaper set with feh for bspwm", send);
} else {
set_wm_wallpaper(&abs_path, send);
@@ -243,13 +232,13 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
} else if d.contains("wayland") {
// Generic Wayland - try multiple approaches
if run("which swaybg") {
- spawn(&format!("pkill swaybg; swaybg -i '{}' -m fill &", abs_path));
+ spawn(&format!("pkill swaybg; swaybg -i '{abs_path}' -m fill &"));
info("Wallpaper", "wallpaper set with swaybg", send);
} else if run("which wbg") {
- spawn(&format!("wbg '{}'", abs_path));
+ spawn(&format!("wbg '{abs_path}'"));
info("Wallpaper", "wallpaper set with wbg", send);
} else if run("which swww") {
- spawn(&format!("swww img '{}'", abs_path));
+ spawn(&format!("swww img '{abs_path}'"));
info("Wallpaper", "wallpaper set with swww", send);
} else {
warning(
@@ -262,31 +251,29 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
} else if d.contains("wayfire") {
// Wayfire compositor
if run("which wbg") {
- spawn(&format!("wbg '{}'", abs_path));
+ spawn(&format!("wbg '{abs_path}'"));
info("Wallpaper", "wallpaper set with wbg for Wayfire", send);
} else {
- spawn(&format!("pkill swaybg; swaybg -i '{}' -m fill &", abs_path));
+ spawn(&format!("pkill swaybg; swaybg -i '{abs_path}' -m fill &"));
info("Wallpaper", "wallpaper set with swaybg for Wayfire", send);
}
} else if d.contains("deepin") {
spawn(&format!(
- "gsettings set com.deepin.wrap.gnome.desktop.background picture-uri 'file://{}'",
- abs_path
+ "gsettings set com.deepin.wrap.gnome.desktop.background picture-uri 'file://{abs_path}'"
));
info("Wallpaper", "wallpaper set with Deepin settings", send);
} else if d.contains("lxqt") {
// LXQt uses pcmanfm-qt for desktop management
- spawn(&format!("pcmanfm-qt --set-wallpaper='{}'", abs_path));
+ spawn(&format!("pcmanfm-qt --set-wallpaper='{abs_path}'"));
info("Wallpaper", "wallpaper set with LXQt settings", send);
} else if d.contains("lxde") {
// LXDE uses pcmanfm for desktop management
- spawn(&format!("pcmanfm --set-wallpaper='{}'", abs_path));
+ spawn(&format!("pcmanfm --set-wallpaper='{abs_path}'"));
info("Wallpaper", "wallpaper set with LXDE settings", send);
} else if d.contains("budgie") {
// Budgie uses GNOME settings
spawn(&format!(
- "gsettings set org.gnome.desktop.background picture-uri 'file://{}'",
- abs_path
+ "gsettings set org.gnome.desktop.background picture-uri 'file://{abs_path}'"
));
info(
"Wallpaper",
@@ -297,8 +284,7 @@ fn set_desktop_wallpaper(desktop: &str, img: &str, send: bool) {
// Enlightenment WM - try using enlightenment_remote
if run("which enlightenment_remote") {
spawn(&format!(
- "enlightenment_remote -desktop-bg-add 0 0 0 0 '{}'",
- abs_path
+ "enlightenment_remote -desktop-bg-add 0 0 0 0 '{abs_path}'"
));
info("Wallpaper", "wallpaper set with Enlightenment", send);
} else {