From 5461cb7f9300aeb03dfb7443d341759fa5e085ca Mon Sep 17 00:00:00 2001 From: tittu Date: Fri, 12 Jun 2026 23:46:20 +0530 Subject: [PATCH] adding anchoring feature --- src/main.rs | 22 +++++++++++++++++++++- src/vulkan.rs | 14 +++++++++----- src/wallbashed.rs | 15 +++++++++++++-- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index cc398ea..e0e56a8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -50,6 +50,25 @@ fn send_command(cmd: &str) -> Result<(), Box> { Ok(()) } +fn parse_anchor(args: &[String]) -> (f32, f32) { + let i = args.iter().position(|a| a == "--anchor" || a == "-a"); + let num = i + .and_then(|i| args.get(i + 1)) + .and_then(|val| val.parse::().ok()); + match num { + Some(1) => (0.0, 0.0), + Some(2) => (0.5, 0.0), + Some(3) => (1.0, 0.0), + Some(4) => (0.0, 0.5), + Some(5) => (0.5, 0.5), + Some(6) => (1.0, 0.5), + Some(7) => (0.0, 1.0), + Some(8) => (0.5, 1.0), + Some(9) => (1.0, 1.0), + _ => (0.5, 0.5), + } +} + // --------------------------------------------------------------------- / main @@ -90,7 +109,8 @@ fn main() { return; } } - let cmd = format!("set {}", args[2]); + let (anchor_h, anchor_v) = parse_anchor(&args); + let cmd = format!("set {} {} {}", args[2], anchor_h, anchor_v); if let Err(e) = send_command(&cmd) { eprintln!("Failed to set wallpaper {}. Is the daemon running?", e); } diff --git a/src/vulkan.rs b/src/vulkan.rs index 6d0b056..5ee3d10 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -523,6 +523,8 @@ pub fn draw_wallpaper( texture_height: u32, swapchain_extent_width: u32, swapchain_extent_height: u32, + anchor_x: f32, + anchor_y: f32, ) -> Result<(), Box> { // acquire swapchain image @@ -594,18 +596,20 @@ pub fn draw_wallpaper( ); } - // preserve aspect ratios and fill screen + // preserve aspect ratios and fill screen (anchored crop) let src_aspect = texture_width as f64 / texture_height as f64; let dst_aspect = swapchain_extent_width as f64 / swapchain_extent_height as f64; let (src_x, src_y, src_w, src_h) = if src_aspect > dst_aspect { - // Image is wider than screen → crop left/right + // Image is wider → crop left/right, horizontal anchor controls which side is kept let new_width = (texture_height as f64 * dst_aspect) as u32; - let x = (texture_width - new_width) / 2; + let max_x = (texture_width - new_width) as f32; + let x = (max_x * anchor_x) as u32; (x, 0, new_width, texture_height) } else { - // Image is taller than screen → crop top/bottom + // Image is taller → crop top/bottom, vertical anchor controls which part is kept let new_height = (texture_width as f64 / dst_aspect) as u32; - let y = (texture_height - new_height) / 2; + let max_y = (texture_height - new_height) as f32; + let y = (max_y * anchor_y) as u32; (0, y, texture_width, new_height) }; diff --git a/src/wallbashed.rs b/src/wallbashed.rs index fcd83a0..84b4fff 100644 --- a/src/wallbashed.rs +++ b/src/wallbashed.rs @@ -62,6 +62,8 @@ fn set_wallpaper( layer_width: u32, layer_height: u32, wallpaper: &mut Option, + anchor_x: f32, + anchor_y: f32, ) -> Result<(), Box> { // load the wallpaper @@ -105,6 +107,8 @@ fn set_wallpaper( img.height(), layer_width, layer_height, + anchor_x, + anchor_y, )?; Ok(()) @@ -157,12 +161,15 @@ pub fn run(socket_path: &str) -> Result<(), Box> { println!("[wallbash] stopping daemon."); running = false; } else if raw.starts_with("set ") { - let path = raw[4..].trim().to_string(); + let args: Vec<&str> = raw[4..].trim().split_whitespace().collect(); + let path = args[..args.len()-2].join(" "); + let anchor_x: f32 = args[args.len()-2].parse().unwrap_or(0.5); + let anchor_y: f32 = args[args.len()-1].parse().unwrap_or(0.5); let resolved = std::fs::canonicalize(&path) .map(|p| p.to_string_lossy().to_string()) .unwrap_or(path); - println!("[wallbash] loading {}", resolved); + println!("[wallbash] loading {} (anchor {}/{})", resolved, anchor_x, anchor_y); match set_wallpaper( &resolved, &vk_core, @@ -170,6 +177,8 @@ pub fn run(socket_path: &str) -> Result<(), Box> { wl_core.state.layer_width, wl_core.state.layer_height, &mut wallpaper, + anchor_x, + anchor_y, ) { Ok(()) => println!("[wallbash] wallpaper set."), Err(e) if e.to_string().contains("out of date") => { @@ -210,6 +219,8 @@ pub fn run(socket_path: &str) -> Result<(), Box> { wl_core.state.layer_width, wl_core.state.layer_height, &mut wallpaper, + anchor_x, + anchor_y, ) { eprintln!("[wallbash] error after swapchain recreation {}", e3); }