1
0

hooks.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. use std::rc::Rc;
  2. use crate::{
  3. assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext,
  4. HotKeyState, ShortcutHandle, ShortcutRegistryError, WryEventHandler,
  5. };
  6. use dioxus_core::{
  7. prelude::{consume_context, use_hook_with_cleanup},
  8. use_hook, Runtime,
  9. };
  10. use dioxus_hooks::use_callback;
  11. use tao::{event::Event, event_loop::EventLoopWindowTarget};
  12. use wry::RequestAsyncResponder;
  13. /// Get an imperative handle to the current window
  14. pub fn use_window() -> DesktopContext {
  15. use_hook(consume_context::<DesktopContext>)
  16. }
  17. /// Register an event handler that runs when a wry event is processed.
  18. pub fn use_wry_event_handler(
  19. mut handler: impl FnMut(&Event<UserWindowEvent>, &EventLoopWindowTarget<UserWindowEvent>) + 'static,
  20. ) -> WryEventHandler {
  21. use dioxus_core::prelude::current_scope_id;
  22. // Capture the current runtime and scope ID.
  23. let runtime = Runtime::current().unwrap();
  24. let scope_id = current_scope_id().unwrap();
  25. use_hook_with_cleanup(
  26. move || {
  27. window().create_wry_event_handler(move |event, target| {
  28. runtime.on_scope(scope_id, || handler(event, target))
  29. })
  30. },
  31. move |handler| handler.remove(),
  32. )
  33. }
  34. /// Register an event handler that runs when a muda event is processed.
  35. #[cfg_attr(
  36. docsrs,
  37. doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
  38. )]
  39. #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
  40. pub fn use_muda_event_handler(
  41. mut handler: impl FnMut(&muda::MenuEvent) + 'static,
  42. ) -> WryEventHandler {
  43. use_wry_event_handler(move |event, _| {
  44. if let Event::UserEvent(UserWindowEvent::MudaMenuEvent(event)) = event {
  45. handler(event);
  46. }
  47. })
  48. }
  49. /// Register an event handler that runs when a tray icon menu event is processed.
  50. #[cfg_attr(
  51. docsrs,
  52. doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
  53. )]
  54. #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
  55. pub fn use_tray_menu_event_handler(
  56. mut handler: impl FnMut(&tray_icon::menu::MenuEvent) + 'static,
  57. ) -> WryEventHandler {
  58. use_wry_event_handler(move |event, _| {
  59. if let Event::UserEvent(UserWindowEvent::TrayMenuEvent(event)) = event {
  60. handler(event);
  61. }
  62. })
  63. }
  64. /// Register an event handler that runs when a tray icon event is processed.
  65. /// This is only for tray icon and not it's menus.
  66. /// If you want to register tray icon menus handler use `use_tray_menu_event_handler` instead.
  67. #[cfg_attr(
  68. docsrs,
  69. doc(cfg(any(target_os = "windows", target_os = "linux", target_os = "macos")))
  70. )]
  71. #[cfg(any(target_os = "windows", target_os = "linux", target_os = "macos"))]
  72. pub fn use_tray_icon_event_handler(
  73. mut handler: impl FnMut(&tray_icon::TrayIconEvent) + 'static,
  74. ) -> WryEventHandler {
  75. use_wry_event_handler(move |event, _| {
  76. if let Event::UserEvent(UserWindowEvent::TrayIconEvent(event)) = event {
  77. handler(event);
  78. }
  79. })
  80. }
  81. /// Provide a callback to handle asset loading yourself.
  82. ///
  83. /// The callback takes a path as requested by the web view, and it should return `Some(response)`
  84. /// if you want to load the asset, and `None` if you want to fallback on the default behavior.
  85. pub fn use_asset_handler(
  86. name: &str,
  87. mut handler: impl FnMut(AssetRequest, RequestAsyncResponder) + 'static,
  88. ) {
  89. // wrap the user's handler in something that keeps it up to date
  90. let cb = use_callback(move |(asset, responder)| handler(asset, responder));
  91. use_hook_with_cleanup(
  92. || {
  93. crate::window()
  94. .asset_handlers
  95. .register_handler(name.to_string(), cb);
  96. Rc::new(name.to_string())
  97. },
  98. move |name| {
  99. _ = crate::window().asset_handlers.remove_handler(name.as_ref());
  100. },
  101. );
  102. }
  103. /// Get a closure that executes any JavaScript in the WebView context.
  104. pub fn use_global_shortcut(
  105. accelerator: impl IntoAccelerator,
  106. handler: impl FnMut(HotKeyState) + 'static,
  107. ) -> Result<ShortcutHandle, ShortcutRegistryError> {
  108. // wrap the user's handler in something that keeps it up to date
  109. let cb = use_callback(handler);
  110. use_hook_with_cleanup(
  111. #[allow(clippy::redundant_closure)]
  112. move || window().create_shortcut(accelerator.accelerator(), move |state| cb(state)),
  113. |handle| {
  114. if let Ok(handle) = handle {
  115. handle.remove();
  116. }
  117. },
  118. )
  119. }