1use std::rc::Rc;
2
3use crate::{
4 assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext,
5 HotKeyState, ShortcutHandle, ShortcutRegistryError, WryEventHandler,
6};
7use dioxus_core::{consume_context, use_hook, use_hook_with_cleanup, Runtime};
8
9use dioxus_hooks::use_callback;
10use tao::{event::Event, event_loop::EventLoopWindowTarget};
11use wry::RequestAsyncResponder;
12
13pub fn use_window() -> DesktopContext {
15 use_hook(consume_context::<DesktopContext>)
16}
17
18pub fn use_wry_event_handler(
20 mut handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
21) -> WryEventHandler {
22 use dioxus_core::current_scope_id;
23
24 let runtime = Runtime::current();
26 let scope_id = current_scope_id();
27
28 use_hook_with_cleanup(
29 move || {
30 window().create_wry_event_handler(move |event, target| {
31 runtime.in_scope(scope_id, || handler(event, target))
32 })
33 },
34 move |handler| handler.remove(),
35 )
36}
37
38#[cfg_attr(
40 docsrs,
41 doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
42)]
43#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
44pub fn use_muda_event_handler(
45 mut handler: impl FnMut(&muda::MenuEvent) + 'static,
46) -> WryEventHandler {
47 use_wry_event_handler(move |event, _| {
48 if let Event::UserEvent(UserWindowEvent::MudaMenuEvent(event)) = event {
49 handler(event);
50 }
51 })
52}
53
54#[cfg_attr(
56 docsrs,
57 doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
58)]
59#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
60pub fn use_tray_menu_event_handler(
61 mut handler: impl FnMut(&tray_icon::menu::MenuEvent) + 'static,
62) -> WryEventHandler {
63 use_wry_event_handler(move |event, _| {
64 if let Event::UserEvent(UserWindowEvent::TrayMenuEvent(event)) = event {
65 handler(event);
66 }
67 })
68}
69
70#[cfg_attr(
74 docsrs,
75 doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
76)]
77#[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
78pub fn use_tray_icon_event_handler(
79 mut handler: impl FnMut(&tray_icon::TrayIconEvent) + 'static,
80) -> WryEventHandler {
81 use_wry_event_handler(move |event, _| {
82 if let Event::UserEvent(UserWindowEvent::TrayIconEvent(event)) = event {
83 handler(event);
84 }
85 })
86}
87
88pub fn use_asset_handler(
93 name: &str,
94 mut handler: impl FnMut(AssetRequest, RequestAsyncResponder) + 'static,
95) {
96 let cb = use_callback(move |(asset, responder)| handler(asset, responder));
98
99 use_hook_with_cleanup(
100 || {
101 crate::window()
102 .asset_handlers
103 .register_handler(name.to_string(), cb);
104
105 Rc::new(name.to_string())
106 },
107 move |name| {
108 _ = crate::window().asset_handlers.remove_handler(name.as_ref());
109 },
110 );
111}
112
113pub fn use_global_shortcut(
115 accelerator: impl IntoAccelerator,
116 handler: impl FnMut(HotKeyState) + 'static,
117) -> Result<ShortcutHandle, ShortcutRegistryError> {
118 let cb = use_callback(handler);
120
121 use_hook_with_cleanup(
122 #[allow(clippy::redundant_closure)]
123 move || window().create_shortcut(accelerator.accelerator(), move |state| cb(state)),
124 |handle| {
125 if let Ok(handle) = handle {
126 handle.remove();
127 }
128 },
129 )
130}