Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,25 @@ fn send_command(cmd: &str) -> Result<(), Box<dyn std::error::Error>> {
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::<u8>().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

Expand Down Expand Up @@ -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);
}
Expand Down
14 changes: 9 additions & 5 deletions src/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<dyn std::error::Error>> {

// acquire swapchain image
Expand Down Expand Up @@ -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)
};

Expand Down
15 changes: 13 additions & 2 deletions src/wallbashed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ fn set_wallpaper(
layer_width: u32,
layer_height: u32,
wallpaper: &mut Option<vulkan::VulkanTexture>,
anchor_x: f32,
anchor_y: f32,
) -> Result<(), Box<dyn std::error::Error>> {

// load the wallpaper
Expand Down Expand Up @@ -105,6 +107,8 @@ fn set_wallpaper(
img.height(),
layer_width,
layer_height,
anchor_x,
anchor_y,
)?;

Ok(())
Expand Down Expand Up @@ -157,19 +161,24 @@ pub fn run(socket_path: &str) -> Result<(), Box<dyn std::error::Error>> {
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,
&vk_surfchain,
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") => {
Expand Down Expand Up @@ -210,6 +219,8 @@ pub fn run(socket_path: &str) -> Result<(), Box<dyn std::error::Error>> {
wl_core.state.layer_width,
wl_core.state.layer_height,
&mut wallpaper,
anchor_x,
anchor_y,
) {
eprintln!("[wallbash] error after swapchain recreation {}", e3);
}
Expand Down
Loading