dioxus_desktop/
hooks.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::rc::Rc;

use crate::{
    assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext,
    ShortcutHandle, ShortcutRegistryError, WryEventHandler,
};
use dioxus_core::{
    prelude::{consume_context, use_hook_with_cleanup},
    use_hook, Runtime,
};

use dioxus_hooks::use_callback;
use tao::{event::Event, event_loop::EventLoopWindowTarget};
use wry::RequestAsyncResponder;

/// Get an imperative handle to the current window
pub fn use_window() -> DesktopContext {
    use_hook(consume_context::<DesktopContext>)
}

/// Register an event handler that runs when a wry event is processed.
pub fn use_wry_event_handler(
    mut handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
) -> WryEventHandler {
    use dioxus_core::prelude::current_scope_id;

    // Capture the current runtime and scope ID.
    let runtime = Runtime::current().unwrap();
    let scope_id = current_scope_id().unwrap();

    use_hook_with_cleanup(
        move || {
            window().create_wry_event_handler(move |event, target| {
                runtime.on_scope(scope_id, || handler(event, target))
            })
        },
        move |handler| handler.remove(),
    )
}

/// Register an event handler that runs when a muda event is processed.
#[cfg_attr(
    docsrs,
    doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
)]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub fn use_muda_event_handler(
    mut handler: impl FnMut(&muda::MenuEvent) + 'static,
) -> WryEventHandler {
    use_wry_event_handler(move |event, _| {
        if let Event::UserEvent(UserWindowEvent::MudaMenuEvent(event)) = event {
            handler(event);
        }
    })
}

/// Register an event handler that runs when a tray icon menu event is processed.
#[cfg_attr(
    docsrs,
    doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
)]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub fn use_tray_menu_event_handler(
    mut handler: impl FnMut(&tray_icon::menu::MenuEvent) + 'static,
) -> WryEventHandler {
    use_wry_event_handler(move |event, _| {
        if let Event::UserEvent(UserWindowEvent::TrayMenuEvent(event)) = event {
            handler(event);
        }
    })
}

/// Register an event handler that runs when a tray icon event is processed.
/// This is only for tray icon and not it's menus.
/// If you want to register tray icon menus handler use `use_tray_menu_event_handler` instead.
#[cfg_attr(
    docsrs,
    doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
)]
#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
pub fn use_tray_icon_event_handler(
    mut handler: impl FnMut(&tray_icon::TrayIconEvent) + 'static,
) -> WryEventHandler {
    use_wry_event_handler(move |event, _| {
        if let Event::UserEvent(UserWindowEvent::TrayIconEvent(event)) = event {
            handler(event);
        }
    })
}

/// Provide a callback to handle asset loading yourself.
///
/// The callback takes a path as requested by the web view, and it should return `Some(response)`
/// if you want to load the asset, and `None` if you want to fallback on the default behavior.
pub fn use_asset_handler(
    name: &str,
    mut handler: impl FnMut(AssetRequest, RequestAsyncResponder) + 'static,
) {
    // wrap the user's handler in something that keeps it up to date
    let cb = use_callback(move |(asset, responder)| handler(asset, responder));

    use_hook_with_cleanup(
        || {
            crate::window()
                .asset_handlers
                .register_handler(name.to_string(), cb);

            Rc::new(name.to_string())
        },
        move |name| {
            _ = crate::window().asset_handlers.remove_handler(name.as_ref());
        },
    );
}

/// Get a closure that executes any JavaScript in the WebView context.
pub fn use_global_shortcut(
    accelerator: impl IntoAccelerator,
    mut handler: impl FnMut() + 'static,
) -> Result<ShortcutHandle, ShortcutRegistryError> {
    // wrap the user's handler in something that keeps it up to date
    let cb = use_callback(move |_| handler());

    use_hook_with_cleanup(
        move || window().create_shortcut(accelerator.accelerator(), move || cb(())),
        |handle| {
            if let Ok(handle) = handle {
                handle.remove();
            }
        },
    )
}