dioxus_desktop/
event_handlers.rs

1use crate::{ipc::UserWindowEvent, window};
2use slab::Slab;
3use std::cell::RefCell;
4use tao::{event::Event, event_loop::EventLoopWindowTarget, window::WindowId};
5
6/// The unique identifier of a window event handler. This can be used to later remove the handler.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub struct WryEventHandler(pub(crate) usize);
9
10impl WryEventHandler {
11    /// Unregister this event handler from the window
12    pub fn remove(&self) {
13        window().shared.event_handlers.remove(*self)
14    }
15}
16
17#[derive(Default)]
18pub struct WindowEventHandlers {
19    handlers: RefCell<Slab<WryWindowEventHandlerInner>>,
20}
21
22struct WryWindowEventHandlerInner {
23    window_id: WindowId,
24
25    #[allow(clippy::type_complexity)]
26    handler:
27        Box<dyn FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static>,
28}
29
30impl WindowEventHandlers {
31    pub(crate) fn add(
32        &self,
33        window_id: WindowId,
34        handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
35    ) -> WryEventHandler {
36        WryEventHandler(
37            self.handlers
38                .borrow_mut()
39                .insert(WryWindowEventHandlerInner {
40                    window_id,
41                    handler: Box::new(handler),
42                }),
43        )
44    }
45
46    pub(crate) fn remove(&self, id: WryEventHandler) {
47        self.handlers.borrow_mut().try_remove(id.0);
48    }
49
50    pub fn apply_event(
51        &self,
52        event: &Event<UserWindowEvent>,
53        target: &EventLoopWindowTarget<UserWindowEvent>,
54    ) {
55        for (_, handler) in self.handlers.borrow_mut().iter_mut() {
56            // if this event does not apply to the window this listener cares about, return
57            if let Event::WindowEvent { window_id, .. } = event {
58                if *window_id != handler.window_id {
59                    return;
60                }
61            }
62            (handler.handler)(event, target)
63        }
64    }
65}