From 5a6b313de2b088bc24beb8259fc56c8ae2c6baf6 Mon Sep 17 00:00:00 2001 From: luckyturtledev Date: Thu, 15 Feb 2024 20:19:32 +0100 Subject: [PATCH] finish xfce read --- more-wallpapers/src/error.rs | 4 ++ more-wallpapers/src/linux/xfce.rs | 89 ++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 26 deletions(-) diff --git a/more-wallpapers/src/error.rs b/more-wallpapers/src/error.rs index 7cb4ef9..e58042d 100644 --- a/more-wallpapers/src/error.rs +++ b/more-wallpapers/src/error.rs @@ -57,6 +57,10 @@ pub enum WallpaperError { #[error("{0:?} {1}")] IOError(String, io::Error), + + #[cfg(target_os = "linux")] + #[error("Unknow XFCE wallpaper mode {0:?}")] + UnknownMode(String), } pub(crate) trait Context { diff --git a/more-wallpapers/src/linux/xfce.rs b/more-wallpapers/src/linux/xfce.rs index 91da73e..cb2dfcb 100644 --- a/more-wallpapers/src/linux/xfce.rs +++ b/more-wallpapers/src/linux/xfce.rs @@ -1,41 +1,78 @@ -use crate::{error::CommandError, load_env_var, Environment, WallpaperBuilder, WallpaperError}; -use crate::Screen; use super::check_command_error; -use std::process::Command; +use crate::{error::CommandError, load_env_var, Environment, Mode, Screen, WallpaperBuilder, WallpaperError}; +use std::{collections::HashMap, process::Command}; -fn load_property(property: &str) -> Result { +fn load_property(property: &str) -> Result { let mut command = Command::new("xfconf-query"); - command.args(["--channel", "xfce4-desktop", "p"]); - command.arg(property); - let output = check_command_error(command.output(), "xfconf-query")?; - let output = String::from_utf8(output).unwrap(); - Ok(output) + command.args(["--channel", "xfce4-desktop", "p"]); + command.arg(property); + let output = check_command_error(command.output(), "xfconf-query")?; + let output = String::from_utf8(output).unwrap(); + Ok(output) } - pub(crate) fn get_screens() -> Result, WallpaperError> { let mut command = Command::new("xfconf-query"); command.args(["--channel", "xfce4-desktop", "--list"]); let output = check_command_error(command.output(), "xfconf-query")?; let output = String::from_utf8(output).unwrap(); - let mut current_screen_wallpaper = None; - let mut current_screen_mode = None; - for line in output.lines() { - if line.starts_with("/backdrop/") { + // the outpult looks like the following: + // + // /backdrop/screen0/monitor0/image-style + // /backdrop/screen0/monitor0/last-image + // /backdrop/screen0/monitor0/last-single-image + // /backdrop/screen0/monitorVirtual-1/workspace0/color-style + // /backdrop/screen0/monitorVirtual-1/workspace0/image-style + // /backdrop/screen0/monitorVirtual-1/workspace0/last-image + // /backdrop/screen0/monitorVirtual-1/workspace1/color-style + // /backdrop/screen0/monitorVirtual-1/workspace1/image-style + // /backdrop/screen0/monitorVirtual-1/workspace1/last-image + let mut screens: HashMap = Default::default(); + for line in output.lines().filter_map(|s| s.strip_prefix("/backdrop/")) { + let mut split = line.split('/'); + let first = split.next(); + let second = split.next(); + let third = split.next(); + if split.next().is_some() { + //to long -> wrong key break; } - if line.ends_with("/image-style"){ - let value = load_property(line)?; - current_screen_mode.is_some panic - current_screen_mode = Some(("screenname_TODO".to_owned(), value)); - + let (Some(first), Some(second)) = (first, second) else { + //to short -> wrong key + break; + }; + let (screen_name, key_type, active) = if let Some(third) = third { + // if name exist out of two part, the screen is active. + // Otherwise it is default for new workspaces + (format!("{}/{}", first, second), third, true) + } else { + (first.to_owned(), second, false) + }; + if !(key_type == "last_image" || key_type == "image_style") { + // wrong key + break; } - if line.ends_with("/last-image"){ - let value = load_property(line)?; - current_screen_mode.unwrap() = "screenname_TODO"; - current_screen_wallpaper.is_some panic - current_screen_wallpaper = Some(("screenname_TODO".to_owned(), value)); + let value = load_property(line)?; + let screen = screens.entry(screen_name.clone()).or_insert_with(|| Screen { + name: screen_name, + wallpaper: None, + mode: None, + active, + }); + if key_type == "last_image" { + screen.wallpaper = Some(value.into()); + } else { + let mode = match value.as_str() { + "0" => None, //single color background is used instead of a image + "1" => Some(Mode::Center), + "2" => Some(Mode::Tile), + "3" => Some(Mode::Stretch), + "4" => Some(Mode::Fit), + "5" => Some(Mode::Crop), + _ => return Err(WallpaperError::UnknownMode(value)), + }; + screen.mode = mode; } } - todo!() -} \ No newline at end of file + Ok(screens.into_values().collect()) +}