Show_image event handler usage

Hi, I'm writing a rust chip8 emulator and need my display struct to handle keyboard events. The graphics crate I'm using right now is show-image (no specific reason other than it seemed the simplest for a rust newbie like myself).

I am not quite sure how to write the event handler function (what's the expected function signature):

here is my code snippet:

use std::{sync::{Arc, Mutex}};

use show_image::{ImageView, ImageInfo, create_window, WindowProxy, event};

pub const WIDTH: usize = 64;
pub const HEIGHT: usize = 32;

const ON_PIXEL: u8 = 0xFF;
const OFF_PIXEL: u8 = 0x0;

// We implement the display using a linear vector of 8 bit values.
pub struct Display {
    buf: Mutex<[u8; WIDTH * HEIGHT]>,
    window: Option<Mutex<WindowProxy>>,

impl Display {
    pub fn new() -> Arc<Display> {
        let disp = Arc::new(Display {
            buf: Mutex::new([1; WIDTH * HEIGHT]),
            window: Some(Mutex::new(create_window("image", Default::default()).unwrap_or_else(|e| {
                panic!("{}", e);

        let disp_clone = Arc::clone(&disp);
        disp_clone.window.unwrap().lock().unwrap().add_event_handler(handler); // how is the handler defined.

        return disp;

Note that I'm using an Arc since this object needs to also be accessed by another struct (the CPU) in the main thread.

Alternatively, if this is the wrong crate altogether (I really just need a monochrome display), then I'd be grateful for suggestions regarding what's the right crate to use.

Have you considered alternatives for that crate? If so which have you chosen?

I ended up sticking with show_image at least for the time being.

I was able to use the following as an event handler (I run it in a separate thread):

    fn handle_window_events(window: &mut WindowProxy) {
        for event in window.event_channel() {
            match event.recv_timeout(Duration::from_micros(THREAD_LOOP_SLEEP_US)) {
                Ok(wevent) => {
                    match wevent {
                        show_image::event::WindowEvent::KeyboardInput(kb_input) => { /* Handle event */},
                        show_image::event::WindowEvent::CloseRequested(_) => std::process::exit(0),
                        _ => {},
                Err(_) => {},

Keeping the timeout allows me to then update the display in the same thread (It's not efficient, but it's probably enough for my the requirements of my emulator).

My complete implementation is here if you are interested in seeing this usage in proper context.

Hope this helps.