diff --git a/config/src/lib.rs b/config/src/lib.rs index 36c297d..c5644d8 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -13,6 +13,7 @@ pub const NAME: &str = "com.system76.CosmicBackground"; pub const BACKGROUNDS: &str = "backgrounds"; pub const DEFAULT_BACKGROUND: &str = "all"; pub const SAME_ON_ALL: &str = "same-on-all"; +pub const SEARCH_SUBFOLDERS: &str = "search-subfolders"; /// Create a context to the `cosmic-bg` config. /// @@ -73,6 +74,24 @@ impl Context { Ok(()) } + + pub fn search_subfolders(&self) -> bool { + if let Ok(value) = self.0.get::(SEARCH_SUBFOLDERS) { + return value; + } + + let _res = self.0.set(SEARCH_SUBFOLDERS, true); + + true + } + + pub fn set_search_subfolders(&self, value: bool) -> Result<(), cosmic_config::Error> { + if self.search_subfolders() != value { + return self.0.set(SEARCH_SUBFOLDERS, value); + } + + Ok(()) + } } #[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Setters)] @@ -211,6 +230,7 @@ pub struct Config { pub outputs: HashSet, pub backgrounds: Vec, pub default_background: Entry, + pub search_subfolders: bool, } impl Default for Config { @@ -220,6 +240,7 @@ impl Default for Config { outputs: HashSet::new(), backgrounds: Vec::new(), default_background: Entry::fallback(), + search_subfolders: true, } } } @@ -233,6 +254,7 @@ impl Config { pub fn load(context: &Context) -> Result { let mut config = Self { same_on_all: context.same_on_all(), + search_subfolders: context.search_subfolders(), ..Default::default() }; diff --git a/src/main.rs b/src/main.rs index 94f9114..f031907 100755 --- a/src/main.rs +++ b/src/main.rs @@ -155,6 +155,14 @@ fn main() -> color_eyre::Result<()> { changes_applied = true; } + cosmic_bg_config::SEARCH_SUBFOLDERS => { + tracing::debug!("updating search_subfolders"); + state.config.search_subfolders = conf_context.search_subfolders(); + + + changes_applied = true; + } + _ => { tracing::debug!(key, "key modified"); if let Some(output) = key.strip_prefix("output.") @@ -179,6 +187,7 @@ fn main() -> color_eyre::Result<()> { outputs = ?state.config.outputs, backgrounds = ?state.config.backgrounds, default_background = ?state.config.default_background.source, + search_subfolders = state.config.search_subfolders, "new state" ); } @@ -209,6 +218,7 @@ fn main() -> color_eyre::Result<()> { qh.clone(), event_loop.handle(), source_tx.clone(), + config.search_subfolders, ) }) }); @@ -220,6 +230,7 @@ fn main() -> color_eyre::Result<()> { qh.clone(), event_loop.handle(), source_tx.clone(), + config.search_subfolders, )); wallpapers @@ -280,6 +291,7 @@ impl CosmicBg { self.qh.clone(), self.loop_handle.clone(), self.source_tx.clone(), + self.config.search_subfolders, ); let mut backgrounds = self.config.backgrounds.clone(); @@ -298,6 +310,7 @@ impl CosmicBg { self.qh.clone(), self.loop_handle.clone(), self.source_tx.clone(), + self.config.search_subfolders, ); new_wallpaper diff --git a/src/wallpaper.rs b/src/wallpaper.rs index 7c967f2..50dcd31 100644 --- a/src/wallpaper.rs +++ b/src/wallpaper.rs @@ -34,6 +34,7 @@ pub struct Wallpaper { // Cache of source image, if `current_source` is a `Source::Path` current_image: Option, timer_token: Option, + subfolder_search: bool, } impl Drop for Wallpaper { @@ -50,6 +51,8 @@ impl Wallpaper { queue_handle: QueueHandle, loop_handle: calloop::LoopHandle<'static, CosmicBg>, source_tx: calloop::channel::SyncSender<(String, notify::Event)>, + subfolder_search: bool, + ) -> Self { let mut wallpaper = Wallpaper { entry, @@ -60,6 +63,7 @@ impl Wallpaper { timer_token: None, loop_handle, queue_handle, + subfolder_search, }; wallpaper.load_images(); @@ -210,13 +214,22 @@ impl Wallpaper { pub fn load_images(&mut self) { let mut image_queue = VecDeque::new(); let xdg_data_dirs: Vec = match std::env::var("XDG_DATA_DIRS") { - Ok(raw_xdg_data_dirs) => raw_xdg_data_dirs + // Only Ok if the xdg var exists and is not empty + Ok(raw_xdg_data_dirs) if !raw_xdg_data_dirs.is_empty() => raw_xdg_data_dirs .split(':') .map(|s| format!("{}/backgrounds/", s)) .collect(), - Err(_) => Vec::new(), + // fallback to defaults in compliance with XDG standards + _ => vec![ + "/usr/local/share/backgrounds/".to_string(), + "/usr/share/backgrounds/".to_string() + ], }; + + + tracing::debug!(?xdg_data_dirs); + match self.entry.source { Source::Path(ref source) => { tracing::debug!(?source, "loading images"); @@ -225,7 +238,7 @@ impl Wallpaper { if source.is_dir() { if xdg_data_dirs .iter() - .any(|xdg_data_dir| source.starts_with(xdg_data_dir)) + .any(|xdg_data_dir| source.starts_with(xdg_data_dir)) || self.subfolder_search { // Store paths of wallpapers to be used for the slideshow. for img_path in WalkDir::new(source)