diff --git a/Cargo.lock b/Cargo.lock index 5b0a57e..17b89ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -795,20 +795,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "rwpspread" -version = "0.1.1" -dependencies = [ - "clap", - "colored", - "glob", - "image", - "md5", - "smithay-client-toolkit", - "toml", - "wayland-client", -] - [[package]] name = "scoped-tls" version = "1.0.1" @@ -893,6 +879,20 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "swaybg-spread" +version = "0.1.1" +dependencies = [ + "clap", + "colored", + "glob", + "image", + "md5", + "smithay-client-toolkit", + "toml", + "wayland-client", +] + [[package]] name = "syn" version = "1.0.107" diff --git a/Cargo.toml b/Cargo.toml index 2b26ced..7c48547 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rwpspread" +name = "swaybg-spread" version = "0.1.1" edition = "2021" diff --git a/src/main.rs b/src/main.rs index 66b0e67..54db155 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,6 @@ mod parser; mod splitter; mod outputs; -mod wpaperd; use std::process; use colored::Colorize; diff --git a/src/parser.rs b/src/parser.rs index bbe3ee1..9aaae1f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,24 +10,29 @@ struct Args { #[arg(short, long)] image: String, - /// Use wpaperd integration - #[arg(short, long)] - wpaperd: bool, - /// Force Resplit even if cache exists #[arg(short, long)] force_resplit: bool, /// Don't downscale base image, even if it's bigger than needed #[arg(short, long)] - dont_downscale: bool, + no_downscale: bool, + + /// Don't downscale base image, even if it's bigger than needed + #[arg(short, long)] + dont_set: bool, + + /// Don't downscale base image, even if it's bigger than needed + #[arg(short, long)] + silent: bool, } pub struct Config { pub image_path: PathBuf, - pub with_wpaperd: bool, pub force_resplit: bool, - pub dont_downscale: bool, + pub no_downscale: bool, + pub dont_set: bool, + pub silent: bool, } impl Config { @@ -46,9 +51,10 @@ impl Config { // construct Ok(Self { image_path: in_path, - with_wpaperd: args.wpaperd, force_resplit: args.force_resplit, - dont_downscale: args.dont_downscale + no_downscale: args.no_downscale, + dont_set: args.dont_set, + silent: args.silent, }) } diff --git a/src/splitter.rs b/src/splitter.rs index 54df0f6..e9b3ea7 100644 --- a/src/splitter.rs +++ b/src/splitter.rs @@ -6,8 +6,8 @@ use glob::glob; use std::fs::remove_file; use std::path::Path; use crate::Config; -use crate::wpaperd::{WpaperdConfig, cmd_wrapper}; use crate::outputs::Monitor; +use std::process::{Command, Stdio}; pub struct ResultPaper { pub monitor_name: String, @@ -50,77 +50,45 @@ impl Splitter { config ); - // check if we need to generate wpaperd config - if config.with_wpaperd { - // create new wpaperd instance - let wpaperd = WpaperdConfig::new( - format!( - "{}/.config/wpaperd/wallpaper.toml", - var("HOME").unwrap() - ), - self.hash.clone() - ); - - // check caches - let caches_present = self.check_caches(); + // check caches + let caches_present = self.check_caches(); + // TODO: self.result_papers not being set if cache exists. - // do we need to resplit - if - config.force_resplit || - ! caches_present - { - // cleanup caches first - self.cleanup_cache(); - - // we need to resplit - self.result_papers = self.perform_split( - img, - config, - format!("{}/.cache/",var("HOME").unwrap()) - ).map_err( - |err| err.to_string() - )?; - } - - //check wpaper config hash - let wpaperd_present = wpaperd.check_existing().map_err( - |err| err.to_string() - )?; - - // do we need to rebuild config - // also always rebuild when force resplit was set - if - config.force_resplit || - ! wpaperd_present - { - // yes we do - wpaperd.build(&self.result_papers).map_err( - |err| err.to_string() - )?; - } - - // finally, run wrapper - cmd_wrapper().map_err( - |err| err.to_string() - )?; + // do we need to resplit + if + true + // config.force_resplit || + // ! caches_present + { + // cleanup caches first + self.cleanup_cache(); - // no wpaperd to worry about, just split - } else { - // just split + // we need to resplit self.result_papers = self.perform_split( img, config, - format!("{}/",var("PWD").unwrap()) + format!("{}/.cache/",var("HOME").unwrap()) ).map_err( |err| err.to_string() )?; } - // return + for monitor in &self.result_papers { + if (!config.silent) { + // Output in sway config style. + println!("output {} bg {} fill", monitor.monitor_name.to_string(), monitor.image_full_path.to_string()); + } + if (!config.dont_set) { + // Set background for this monitor. + cmd_setbg(&monitor)?; + } + } + Ok(()) } // do the actual splitting + // TODO: Very slow for some reason (especially resizing and saving), try to optimize. fn perform_split(&self, mut img: DynamicImage, config: &Config, save_path: String) -> Result, String> { /* Calculate Overall Size @@ -147,7 +115,7 @@ impl Splitter { // either if user doesn't deny // or if image is too small if - config.dont_downscale == false + config.no_downscale == false || img.dimensions().0 < overall_width || img.dimensions().1 < overall_height { @@ -178,7 +146,7 @@ impl Splitter { ), image: cropped_image } - ) + ); } // save our result images @@ -208,7 +176,7 @@ impl Splitter { format!( "# {:?}{:?}{:?}\n", img_hash, - compute(config.dont_downscale.to_string()), + compute(config.no_downscale.to_string()), compute(hash_string.as_bytes()) ) } @@ -230,6 +198,7 @@ impl Splitter { } fn check_caches(&self) -> bool { + // what we search for let base_format = format!( "{}/.cache/rwps_{}", @@ -255,3 +224,32 @@ impl Splitter { true } } + + +fn cmd_setbg(wallpaper: &ResultPaper) -> Result<(), String> { + + let sway_socket = var("SWAYSOCK") + .map_err(|_| "MY_VAR environment variable not set".to_string())?; + + Command::new("swaymsg") + .arg("-s") + .arg(&sway_socket) + .arg("output") + .arg(&wallpaper.monitor_name) + .arg("bg") + .arg(&wallpaper.image_full_path) + .arg("fill") + .stdout(Stdio::null()) + .status() + //.and_then(|exit_status| exit_status.exit_ok().map_err(|e| e.to_string())) + //.map_err(|err| err.to_string()) + .map_or_else( + |err| Err(err.to_string()), + |exit_status| if exit_status.success() { + Ok(()) + } else { + Err("Exit with error".to_string()) + } + ) +} + diff --git a/src/wpaperd.rs b/src/wpaperd.rs deleted file mode 100644 index 0ed1bbe..0000000 --- a/src/wpaperd.rs +++ /dev/null @@ -1,106 +0,0 @@ -use std::fs::File; -use std::io::Write; -use std::process::{Command, Stdio}; -use toml::{Value, to_string_pretty}; -use crate::splitter::ResultPaper; - -pub struct WpaperdConfig { - pub config_path: String, - pub config_hash: String -} - -impl WpaperdConfig { - pub fn new(config_path: String, config_hash: String) -> Self { - Self { - config_path, - config_hash - } - } - - // build new wpaperd config to file - pub fn build(&self, wallpapers: &Vec) -> Result<(), String> { - // Create a new config file - let mut file = File::create(&self.config_path).map_err( - |_| "unable to open config" - )?; - - // Open the file - let read_file = std::fs::read_to_string(&self.config_path).map_err( - |_| "unable to read config" - )?; - - // Parse the string into a TOML value - let mut values = read_file.parse::().map_err( - |_| "unable to parse config" - )?; - - // Add new output sections - for monitor in wallpapers { - // insert new section - values.as_table_mut().unwrap().insert( - monitor.monitor_name.to_string(), - Value::Table(Default::default()) - ); - // add path value - let path = values.get_mut( - monitor.monitor_name.to_string() - ).unwrap(); - path.as_table_mut().unwrap().insert( - "path".to_string(), - Value::String(monitor.image_full_path.to_string()) - ); - } - - // write the file - file.write(self.config_hash.as_bytes()).unwrap(); - file.write(b"# AUTOGENERATED CONFIG BY RWPSPREAD\n\n").unwrap(); - file.write_all(to_string_pretty(&values).unwrap().as_bytes()).unwrap(); - - // return - Ok(()) - } - - // check for existing config - pub fn check_existing(&self) -> Result { - // Open the file - let read_file = std::fs::read_to_string(&self.config_path).map_err( - |_| "unable to open config" - )?; - - // check if we find the correct hash - if read_file.starts_with(&self.config_hash) { - // hash matches, don't regenerate - return Ok(true) - } - - // return - Ok(false) - } -} - -pub fn cmd_wrapper() -> Result<(), String> { - // Check if there is a running wpaperd process - match Command::new("pidof") - .args(&["wpaperd"]) - .stdout(Stdio::null()) - .status() { - Ok(_) => { - // kill it with fire - Command::new("killall") - .args(&["-9", "wpaperd"]) - .stdout(Stdio::null()) - .output().map_err( - |err| err.to_string() - )?; - }, - Err(_) => {}, - } - - // Spawn new wpaperd instance - Command::new("wpaperd") - .spawn().map_err( - |err| err.to_string() - )?; - - Ok(()) -}