diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 6af6401f3..0db972c73 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -51,10 +51,9 @@ pub(crate) type WebviewQueue = Rc>>; /// ```rust, ignore /// let desktop = cx.consume_context::().unwrap(); /// ``` -#[derive(Clone)] -pub struct DesktopContext { +pub struct DesktopService { /// The wry/tao proxy to the current window - pub webview: Rc, + pub webview: WebView, /// The proxy to the event loop pub proxy: ProxyType, @@ -74,8 +73,10 @@ pub struct DesktopContext { pub(crate) views: Rc>>, } +pub type DesktopContext = Rc; + /// A smart pointer to the current window. -impl std::ops::Deref for DesktopContext { +impl std::ops::Deref for DesktopService { type Target = Window; fn deref(&self) -> &Self::Target { @@ -83,9 +84,9 @@ impl std::ops::Deref for DesktopContext { } } -impl DesktopContext { +impl DesktopService { pub(crate) fn new( - webview: Rc, + webview: WebView, proxy: ProxyType, event_loop: EventLoopWindowTarget, webviews: WebviewQueue, @@ -112,7 +113,7 @@ impl DesktopContext { /// You can use this to control other windows from the current window. /// /// Be careful to not create a cycle of windows, or you might leak memory. - pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak { + pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak { let window = create_new_window( cfg, &self.event_loop, @@ -123,7 +124,13 @@ impl DesktopContext { self.shortcut_manager.clone(), ); - let id = window.webview.window().id(); + let desktop_context = window + .dom + .base_scope() + .consume_context::>() + .unwrap(); + + let id = window.desktop_context.webview.window().id(); self.proxy .send_event(UserWindowEvent(EventData::NewWindow, id)) @@ -133,11 +140,9 @@ impl DesktopContext { .send_event(UserWindowEvent(EventData::Poll, id)) .unwrap(); - let webview = window.webview.clone(); - self.pending_windows.borrow_mut().push(window); - Rc::downgrade(&webview) + Rc::downgrade(&desktop_context) } /// trigger the drag-window event @@ -405,7 +410,7 @@ pub fn use_wry_event_handler( let id = desktop.create_wry_event_handler(handler); WryEventHandler { - handlers: desktop.event_handlers, + handlers: desktop.event_handlers.clone(), id, } }) diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 69161e2a5..fc574dfc0 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -19,9 +19,11 @@ mod webview; use crate::query::QueryResult; pub use cfg::Config; pub use desktop_context::{ - use_window, use_wry_event_handler, DesktopContext, WryEventHandler, WryEventHandlerId, + use_window, use_wry_event_handler, DesktopService, WryEventHandler, WryEventHandlerId, +}; +use desktop_context::{ + DesktopContext, EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers, }; -use desktop_context::{EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers}; use dioxus_core::*; use dioxus_html::MountedData; use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent}; @@ -150,8 +152,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) let shortcut_manager = ShortcutRegistry::new(&event_loop); - // By default, we'll create a new window when the app starts - queue.borrow_mut().push(create_new_window( + let web_view = create_new_window( cfg, &event_loop, &proxy, @@ -159,7 +160,10 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) &queue, &event_handlers, shortcut_manager.clone(), - )); + ); + + // By default, we'll create a new window when the app starts + queue.borrow_mut().push(web_view); event_loop.run(move |window_event, event_loop, control_flow| { *control_flow = ControlFlow::Wait; @@ -190,7 +194,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) Event::NewEvents(StartCause::Init) | Event::UserEvent(UserWindowEvent(EventData::NewWindow, _)) => { for handler in queue.borrow_mut().drain(..) { - let id = handler.webview.window().id(); + let id = handler.desktop_context.webview.window().id(); webviews.insert(id, handler); _ = proxy.send_event(UserWindowEvent(EventData::Poll, id)); } @@ -260,7 +264,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) view.dom.handle_event(&name, as_any, element, bubbles); - send_edits(view.dom.render_immediate(), &view.webview); + send_edits(view.dom.render_immediate(), &view.desktop_context.webview); } // When the webview sends a query, we need to send it to the query manager which handles dispatching the data to the correct pending query @@ -282,7 +286,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) EventData::Ipc(msg) if msg.method() == "initialize" => { let view = webviews.get_mut(&event.1).unwrap(); - send_edits(view.dom.rebuild(), &view.webview); + send_edits(view.dom.rebuild(), &view.desktop_context.webview); } EventData::Ipc(msg) if msg.method() == "browser_open" => { @@ -342,9 +346,8 @@ fn create_new_window( shortcut_manager: ShortcutRegistry, ) -> WebviewHandler { let (webview, web_context) = webview::build(&mut cfg, event_loop, proxy.clone()); - - dom.base_scope().provide_context(DesktopContext::new( - webview.clone(), + let desktop_context = Rc::from(DesktopService::new( + webview, proxy.clone(), event_loop.clone(), queue.clone(), @@ -352,11 +355,14 @@ fn create_new_window( shortcut_manager, )); - let id = webview.window().id(); + dom.base_scope().provide_context(desktop_context.clone()); + + let id = desktop_context.webview.window().id(); // We want to poll the virtualdom and the event loop at the same time, so the waker will be connected to both + WebviewHandler { - webview, + desktop_context, dom, waker: waker::tao_waker(proxy, id), web_context, @@ -365,7 +371,7 @@ fn create_new_window( struct WebviewHandler { dom: VirtualDom, - webview: Rc, + desktop_context: DesktopContext, waker: Waker, // This is nessisary because of a bug in wry. Wry assumes the webcontext is alive for the lifetime of the webview. We need to keep the webcontext alive, otherwise the webview will crash #[allow(dead_code)] @@ -391,7 +397,7 @@ fn poll_vdom(view: &mut WebviewHandler) { } } - send_edits(view.dom.render_immediate(), &view.webview); + send_edits(view.dom.render_immediate(), &view.desktop_context.webview); } } diff --git a/packages/desktop/src/shortcut.rs b/packages/desktop/src/shortcut.rs index e5cc05315..ffa87dd05 100644 --- a/packages/desktop/src/shortcut.rs +++ b/packages/desktop/src/shortcut.rs @@ -10,7 +10,7 @@ use wry::application::{ keyboard::{KeyCode, ModifiersState}, }; -use crate::{use_window, DesktopContext}; +use crate::{desktop_context::DesktopContext, use_window}; #[derive(Clone)] pub(crate) struct ShortcutRegistry { diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs index 0b7152cfd..469aa8068 100644 --- a/packages/desktop/src/webview.rs +++ b/packages/desktop/src/webview.rs @@ -1,5 +1,3 @@ -use std::rc::Rc; - use crate::desktop_context::EventData; use crate::protocol; use crate::{desktop_context::UserWindowEvent, Config}; @@ -13,7 +11,7 @@ pub fn build( cfg: &mut Config, event_loop: &EventLoopWindowTarget, proxy: EventLoopProxy, -) -> (Rc, WebContext) { +) -> (WebView, WebContext) { let builder = cfg.window.clone(); let window = builder.build(event_loop).unwrap(); let file_handler = cfg.file_drop_handler.take(); @@ -96,5 +94,5 @@ pub fn build( webview = webview.with_devtools(true); } - (Rc::new(webview.build().unwrap()), web_context) + (webview.build().unwrap(), web_context) }