~whynothugo/shotman

fb76f8ee3ea12a147e5aaad4d5099bdf557804a4 — Hugo Osvaldo Barrera 8 months ago 7984195
Simplify declaration of encoder callback
1 files changed, 33 insertions(+), 27 deletions(-)

M src/main.rs
M src/main.rs => src/main.rs +33 -27
@@ 12,6 12,7 @@ use std::thread;

use anyhow::{bail, Context};
use calloop::futures::{executor, Scheduler};
use calloop::LoopHandle;
use calloop_wayland_source::WaylandSource;
use clap::Parser;
use cli::{Cli, RequestedTarget};


@@ 121,7 122,7 @@ enum DesiredTarget {
#[derive(Default)]
struct DetectorUserData {}

fn main() {
fn main() -> anyhow::Result<()> {
    let cli = Cli::parse();
    let log_level = cli.verbose.unwrap_or(log::Level::Warn);
    simple_logger::init_with_level(log_level).expect("logger configuration is valid");


@@ 164,25 165,24 @@ fn main() {
    let qh = event_queue.handle();

    // # SAFETY: these fail only if the process has reached the maximum file descriptiors.
    let (encoder_executor, encoder_scheduler) = executor().expect("initialise calloop scheduler");
    let (pipe_executor, pipe_scheduler) = executor().expect("initialise calloop scheduler");

    let mut event_loop = EventLoop::<State>::try_new().expect("initialize the event loop");
    let loop_signal = event_loop.get_signal();
    let handle = event_loop.handle();

    let mut state = State::new(
        target,
        cli.anchor,
        &qh,
        &globals,
        encoder_scheduler,
        pipe_scheduler,
        cli.image_editor,
        handle.clone(),
    )
    .unwrap();
    state.autocopy = cli.copy;

    let mut event_loop = EventLoop::<State>::try_new().expect("initialize the event loop");
    let loop_signal = event_loop.get_signal();
    let handle = event_loop.handle();

    let wl_source = WaylandSource::new(conn, event_queue);

    handle


@@ 192,22 192,6 @@ fn main() {
        .expect("add wayland source into event loop");

    handle
        .insert_source(encoder_executor, |maybe_png, _, state| {
            trace!("Encoder future is done.");
            state.futures.fetch_sub(1, Ordering::Release);

            match maybe_png {
                Ok(p) => state.png_ready(p),
                Err(e) => {
                    error!("Encoding the screenshot into PNG failed.");
                    error!("The file will not be saved. Pasting will not work!");
                    error!("Encoding error: {}", e);
                    state.png_state = PngState::Failed;
                }
            };
        })
        .expect("add executor source into event loop");
    handle
        .insert_source(pipe_executor, |_, _, state| {
            trace!("Async executor done.");
            state.futures.fetch_sub(1, Ordering::Release);


@@ 232,6 216,7 @@ fn main() {

    // TODO: if we've deleted the file, we don't need to wait for the file thread.
    // ... maybe expose a method on state `should_terminate()`?
    Ok(())
}

/// Helper type that holds references to all Wayland globals that are used at runtime.


@@ 320,7 305,6 @@ struct State {
    /// These futures need to be allowed to complete before existing (e.g.:
    /// writing to file; writing to a clipboard file descriptor).
    futures: AtomicU8,
    encoder_scheduler: Scheduler<Result<Vec<u8>, Canceled>>,
    pipe_scheduler: Scheduler<Result<(), Canceled>>,
    window_anchor: zwlr_layer_surface_v1::Anchor,
    current_output: Option<wl_output::WlOutput>,


@@ 330,6 314,7 @@ struct State {
    configure: Configure,
    image_editor: OsString,
    scale: Scale,
    loop_handle: LoopHandle<'static, State>,
}

/// Information on the buffer for the screenshot.


@@ 421,9 406,9 @@ impl State {
        anchor: zwlr_layer_surface_v1::Anchor,
        qh: &QueueHandle<Self>,
        global_list: &GlobalList,
        encoder_scheduler: Scheduler<Result<Vec<u8>, Canceled>>,
        pipe_scheduler: Scheduler<Result<(), Canceled>>,
        image_editor: OsString,
        loop_handle: LoopHandle<'static, State>,
    ) -> anyhow::Result<Self> {
        let globals = Globals::new(qh, global_list)?;
        let wlr_layer_shell =


@@ 535,7 520,6 @@ impl State {
            delete_file_on_paste: false,
            current_selection: None,
            futures: 0.into(),
            encoder_scheduler,
            pipe_scheduler,
            window_anchor: anchor,
            current_output: None,


@@ 544,6 528,7 @@ impl State {
            configure: Configure::Uninitialised,
            image_editor,
            scale: Scale::Unknown,
            loop_handle,
        })
    }



@@ 866,7 851,13 @@ impl State {
            });

            self.futures.fetch_add(1, Ordering::Release);
            if let Err(err) = self.encoder_scheduler.schedule(rx) {

            let (executor, scheduler) = executor().context("initialising encoder executor")?;
            self.loop_handle
                .insert_source(executor, image_encoded_cb)
                .expect("insert encoder executor into main loop");

            if let Err(err) = scheduler.schedule(rx) {
                self.futures.fetch_sub(1, Ordering::Release);
                bail!(err);
            };


@@ 929,6 920,21 @@ impl State {
    }
}

fn image_encoded_cb(maybe_png: Result<Vec<u8>, Canceled>, _: &mut (), state: &mut State) {
    trace!("Encoder future is done.");
    state.futures.fetch_sub(1, Ordering::Release);

    match maybe_png {
        Ok(p) => state.png_ready(p),
        Err(e) => {
            error!("Encoding the screenshot into PNG failed.");
            error!("The file will not be saved. Pasting will not work!");
            error!("Encoding error: {}", e);
            state.png_state = PngState::Failed;
        }
    };
}

impl ProvidesRegistryState for State {
    fn registry(&mut self) -> &mut RegistryState {
        &mut self.registry_state