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
21 changes: 10 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,24 @@ const LOG_FILE: &str = "/tmp/wallbash.log";

fn print_usage() {
eprintln!("[Usage]");
eprintln!(" wallbash start | Start the wallpaper daemon");
eprintln!(" wallbash set <image_path> | Set the wallpaper");
eprintln!(" wallbash stop | Stop the daemon");
eprintln!(" wallbash status | Show daemon status");
eprintln!(" wallbash start | Start the wallpaper daemon");
eprintln!(" wallbash set /path/to/wall.img | Set the wallpaper");
eprintln!(" wallbash stop | Stop the daemon");
eprintln!(" wallbash status | Show daemon status");
}

fn check_daemon() -> bool {
UnixStream::connect(SOCKET_PATH).is_ok()
}

fn wait_loop() -> Result<(), Box<dyn std::error::Error>> {
let max_attempts = 50; // 50 × 100 ms = 5 seconds
for _ in 0..max_attempts {
for _ in 0..100 {
if check_daemon() {
return Ok(());
}
sleep(Duration::from_millis(100));
}
Err("Daemon did not start within 5 seconds".into())
Err("Waiting for daemon...".into())
}

fn send_command(cmd: &str) -> Result<(), Box<dyn std::error::Error>> {
Expand All @@ -68,7 +67,7 @@ fn main() {
return;
}
if let Err(e) = wallbashed::run(SOCKET_PATH) {
eprintln!("Failed to start daemon: {}", e);
eprintln!("Failed to start daemon {}", e);
}
}
"set" => {
Expand All @@ -86,19 +85,19 @@ fn main() {
.spawn()
.expect("Failed to start daemon");
if let Err(e) = wait_loop() {
eprintln!("Error: {}", e);
eprintln!("Error {}", e);
let _ = child.kill();
return;
}
}
let cmd = format!("set {}", args[2]);
if let Err(e) = send_command(&cmd) {
eprintln!("Failed to set wallpaper: {}. Is the daemon running?", e);
eprintln!("Failed to set wallpaper {}. Is the daemon running?", e);
}
}
"stop" => {
if let Err(e) = send_command("stop") {
eprintln!("Failed to stop daemon: {}. Is it running?", e);
eprintln!("Failed to stop daemon {}. Is it running?", e);
}
}
"status" => {
Expand Down
44 changes: 10 additions & 34 deletions src/vulkan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ pub struct VulkanSurfchain {
pub struct VulkanTexture {
pub image: vk::Image,
pub _memory: vk::DeviceMemory,
pub _view: vk::ImageView,
}


Expand Down Expand Up @@ -197,7 +196,15 @@ pub fn vulkan_surfchain(
f.color_space == vk::ColorSpaceKHR::SRGB_NONLINEAR
})
.copied().unwrap_or(formats[0]);
println!("[v] surface config: {:?}", chosen_format);
let extent = if caps.current_extent.width != u32::MAX {
caps.current_extent
} else {
vk::Extent2D {
width: width.clamp(caps.min_image_extent.width, caps.max_image_extent.width),
height: height.clamp(caps.min_image_extent.height, caps.max_image_extent.height),
}
};
println!("[v] surface config: {:?} | {:?}", chosen_format, extent);

// configure swapchain
let swapchain_loader = swapchain::Device::new(instance, device);
Expand All @@ -206,7 +213,7 @@ pub fn vulkan_surfchain(
.min_image_count(2.max(caps.min_image_count))
.image_format(chosen_format.format)
.image_color_space(chosen_format.color_space)
.image_extent(vk::Extent2D { width, height })
.image_extent(extent)
.image_array_layers(1)
.image_usage(vk::ImageUsageFlags::TRANSFER_DST | vk::ImageUsageFlags::COLOR_ATTACHMENT)
.image_sharing_mode(vk::SharingMode::EXCLUSIVE)
Expand Down Expand Up @@ -465,33 +472,6 @@ pub fn load_texture(
}


// --------------------------------------------------------------------- / read texture

pub fn view_texture(
device: &ash::Device,
image: vk::Image,
format: vk::Format,
) -> Result<vk::ImageView, Box<dyn std::error::Error>> {

// describe the view
let view_info = vk::ImageViewCreateInfo::default()
.image(image)
.view_type(vk::ImageViewType::TYPE_2D)
.format(format)
.subresource_range(vk::ImageSubresourceRange {
aspect_mask: vk::ImageAspectFlags::COLOR,
base_mip_level: 0,
level_count: 1,
base_array_layer: 0,
layer_count: 1,
});

// create the view to read texture
let view = unsafe { device.create_image_view(&view_info, None)? };
Ok(view)
}


// --------------------------------------------------------------------- / vulkan wrapper

pub fn vulkan_pipeline(
Expand All @@ -515,9 +495,6 @@ pub fn vulkan_pipeline(
// load pixed data from buffer to texture
load_texture(device, graphics_queue, command_pool, command_buffer, buffer, texture, width, height)?;

// sample/read the texture
let view = view_texture(device, texture, vk::Format::R8G8B8A8_SRGB)?;

// drop the staging buffer (no longer needed)
unsafe {
device.destroy_buffer(buffer, None);
Expand All @@ -527,7 +504,6 @@ pub fn vulkan_pipeline(
Ok(VulkanTexture {
image: texture,
_memory: vram,
_view: view,
})
}

Expand Down
8 changes: 5 additions & 3 deletions src/wallbashed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ fn set_wallpaper(
// drop the old texture resources (if any)
if let Some(old_tex) = wallpaper.take() {
unsafe {
vk_core.device.destroy_image_view(old_tex._view, None);
vk_core.device.destroy_image(old_tex.image, None);
vk_core.device.free_memory(old_tex._memory, None);
}
Expand Down Expand Up @@ -175,13 +174,15 @@ pub fn run(socket_path: &str) -> Result<(), Box<dyn std::error::Error>> {
Ok(()) => println!("[wallbash] wallpaper set."),
Err(e) if e.to_string().contains("out of date") => {
println!("[wallbash] swapchain out of date, recreating...");

// destroy old swapchain and surface
vulkan::destroy_surfchain(
&vk_core.entry,
&vk_core.instance,
&vk_core.device,
&mut vk_surfchain,
);

// create a new one with the current layer dimensions
vk_surfchain = match vulkan::vulkan_surfchain(
&vk_core.entry,
Expand All @@ -200,6 +201,7 @@ pub fn run(socket_path: &str) -> Result<(), Box<dyn std::error::Error>> {
continue;
}
};

// retry setting the wallpaper once
if let Err(e3) = set_wallpaper(
&resolved,
Expand All @@ -222,10 +224,10 @@ pub fn run(socket_path: &str) -> Result<(), Box<dyn std::error::Error>> {
std::thread::sleep(std::time::Duration::from_millis(25));
}

// clean shutdowon
// clean shutdowon
unsafe { vk_core.device.device_wait_idle()?; }
if let Some(tex) = wallpaper.take() {
unsafe {
vk_core.device.destroy_image_view(tex._view, None);
vk_core.device.destroy_image(tex.image, None);
vk_core.device.free_memory(tex._memory, None);
}
Expand Down
1 change: 1 addition & 0 deletions src/wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ pub fn wayland_core() -> Result<WaylandCore, Box<dyn std::error::Error>> {
println!("[w] {} (v{})", zwlr_layer_surface_v1::ZwlrLayerSurfaceV1::interface().name, layer_surface.version());

// commit and sync layer config
layer_surface.set_size(0, 0);
surface.commit();
state.layer_surface = Some(layer_surface);
event.roundtrip(&mut state)?;
Expand Down
Loading