use crate::cli::Config;
use crate::theme::update_theme_file;
use crate::traits::Backend;
use crate::wallpaper::WallpaperCache;
use std::time::Duration;
use tokio::signal::unix::{SignalKind, signal};
use tokio::time::sleep;
mod render;
pub use render::awww::detect_awww_binary;
pub use render::awww::ensure_awww_daemon;
pub async fn run_loop<B: Backend>(config: Config, backend: B) -> anyhow::Result<()> {
crate::theme::ensure_theme_exists()?;
let cache = WallpaperCache::new(&config.wallpaper_dir)?;
let period: Duration =
humantime::parse_duration(config.time.as_ref().expect("daemon mode requires --time"))
.map_err(|e| anyhow::anyhow!("invalid duration: {e}"))?;
let mut renderer = render::Renderer::new(&config).await?;
let mut sig_usr1 = signal(SignalKind::user_defined1())?;
loop {
let monitors = match backend.get_active_monitors().await {
Ok(m) => m,
Err(e) => {
log::error!("Failed to get monitors: {e}. Retrying in 5s...");
sleep(Duration::from_secs(5)).await;
continue;
}
};
let img = cache.pick_random();
let _ = update_theme_file(img);
renderer.apply(&config, &cache, &monitors).await?;
tokio::select! {
() = sleep(period) => {}
_ = sig_usr1.recv() => {
log::info!("Received skip signal (SIGUSR1). Cycling wallpaper immediately.");
}
}
}
}