alttabway 0.4.5

Alt-tab window switcher for wayland compositors
Documentation
use fast_image_resize::{
    PixelType, Resizer,
    images::{Image, ImageRef},
};
use image::DynamicImage;
use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender};

#[derive(Debug)]
pub struct ImageResizer<T: Send + 'static> {
    sender: UnboundedSender<(T, Image<'static>)>,
    receiver: UnboundedReceiver<(T, Image<'static>)>,
}

impl<T: Send + 'static> ImageResizer<T> {
    pub fn new() -> Self {
        let (sender, receiver) = mpsc::unbounded_channel();
        Self { sender, receiver }
    }

    pub fn resize_image(&mut self, key: T, src_image: DynamicImage, destination: (u32, u32)) {
        let (dst_width, dst_height) = destination;
        let sender = self.sender.clone();
        tokio::spawn(async move {
            let mut dst_image = Image::new(dst_width, dst_height, PixelType::U8x4);

            tracing::trace!(
                "attempting to resize image! {}x{} => {}x{}",
                src_image.width(),
                src_image.height(),
                dst_width,
                dst_height
            );

            let mut resizer = Resizer::new();
            if let Err(err) = resizer.resize(&src_image, &mut dst_image, None) {
                tracing::warn!("failed to resize image! {}", err);
                return;
            }

            let _ = sender.send((key, dst_image));
        });
    }

    pub fn resize_rgb_pixels(&mut self, key: T, source: (Vec<u8>, u32), destination: (u32, u32)) {
        let (mut pixels, width) = source;
        let height = pixels.len() as u32 / width / 3;

        let (dst_width, dst_height) = destination;
        let sender = self.sender.clone();
        tokio::spawn(async move {
            let src_image = match ImageRef::new(width, height, &mut pixels, PixelType::U8x3) {
                Ok(image_ref) => image_ref,
                Err(err) => {
                    tracing::warn!("Failed to read pixels as image: {}", err);
                    return;
                }
            };
            let mut dst_image = Image::new(dst_width, dst_height, PixelType::U8x3);

            tracing::debug!(
                "attempting to resize image! {}x{} => {}x{}",
                width,
                height,
                dst_width,
                dst_height
            );

            let mut resizer = Resizer::new();
            if let Err(err) = resizer.resize(&src_image, &mut dst_image, None) {
                tracing::warn!("failed to resize image! {}", err);
                return;
            }

            let _ = sender.send((key, dst_image));
        });
    }

    pub async fn recv(&mut self) -> Option<(T, Image<'static>)> {
        self.receiver.recv().await
    }
}