webview.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. use crate::desktop_context::{EditQueue, EventData};
  2. use crate::protocol;
  3. use crate::{desktop_context::UserWindowEvent, Config};
  4. use tao::event_loop::{EventLoopProxy, EventLoopWindowTarget};
  5. pub use wry;
  6. pub use wry::application as tao;
  7. use wry::application::window::Window;
  8. use wry::webview::{WebContext, WebView, WebViewBuilder};
  9. pub fn build(
  10. cfg: &mut Config,
  11. event_loop: &EventLoopWindowTarget<UserWindowEvent>,
  12. proxy: EventLoopProxy<UserWindowEvent>,
  13. ) -> (WebView, WebContext, EditQueue) {
  14. let builder = cfg.window.clone();
  15. let window = builder.build(event_loop).unwrap();
  16. let file_handler = cfg.file_drop_handler.take();
  17. let custom_head = cfg.custom_head.clone();
  18. let index_file = cfg.custom_index.clone();
  19. let root_name = cfg.root_name.clone();
  20. // We assume that if the icon is None in cfg, then the user just didnt set it
  21. if cfg.window.window.window_icon.is_none() {
  22. window.set_window_icon(Some(
  23. tao::window::Icon::from_rgba(
  24. include_bytes!("./assets/default_icon.bin").to_vec(),
  25. 460,
  26. 460,
  27. )
  28. .expect("image parse failed"),
  29. ));
  30. }
  31. let mut web_context = WebContext::new(cfg.data_dir.clone());
  32. let edit_queue = EditQueue::default();
  33. let mut webview = WebViewBuilder::new(window)
  34. .unwrap()
  35. .with_transparent(cfg.window.window.transparent)
  36. .with_url("dioxus://index.html/")
  37. .unwrap()
  38. .with_ipc_handler(move |window: &Window, payload: String| {
  39. // defer the event to the main thread
  40. if let Ok(message) = serde_json::from_str(&payload) {
  41. _ = proxy.send_event(UserWindowEvent(EventData::Ipc(message), window.id()));
  42. }
  43. })
  44. .with_asynchronous_custom_protocol("dioxus".into(), {
  45. let edit_queue = edit_queue.clone();
  46. move |r, responder| {
  47. protocol::desktop_handler(
  48. &r,
  49. responder,
  50. custom_head.clone(),
  51. index_file.clone(),
  52. &root_name,
  53. &edit_queue,
  54. )
  55. }
  56. })
  57. .with_file_drop_handler(move |window, evet| {
  58. file_handler
  59. .as_ref()
  60. .map(|handler| handler(window, evet))
  61. .unwrap_or_default()
  62. })
  63. .with_web_context(&mut web_context);
  64. #[cfg(windows)]
  65. {
  66. // Windows has a platform specific settings to disable the browser shortcut keys
  67. use wry::webview::WebViewBuilderExtWindows;
  68. webview = webview.with_browser_accelerator_keys(false);
  69. }
  70. if let Some(color) = cfg.background_color {
  71. webview = webview.with_background_color(color);
  72. }
  73. // These are commented out because wry is currently broken in wry
  74. // let mut web_context = WebContext::new(cfg.data_dir.clone());
  75. // .with_web_context(&mut web_context);
  76. for (name, handler) in cfg.protocols.drain(..) {
  77. webview = webview.with_custom_protocol(name, handler)
  78. }
  79. if cfg.disable_context_menu {
  80. // in release mode, we don't want to show the dev tool or reload menus
  81. webview = webview.with_initialization_script(
  82. r#"
  83. if (document.addEventListener) {
  84. document.addEventListener('contextmenu', function(e) {
  85. e.preventDefault();
  86. }, false);
  87. } else {
  88. document.attachEvent('oncontextmenu', function() {
  89. window.event.returnValue = false;
  90. });
  91. }
  92. "#,
  93. )
  94. } else {
  95. // in debug, we are okay with the reload menu showing and dev tool
  96. webview = webview.with_devtools(true);
  97. }
  98. (webview.build().unwrap(), web_context, edit_queue)
  99. }