From a5c46b0e5ce6acd2594f93bde35a5c486f35a828 Mon Sep 17 00:00:00 2001 From: Andrew Collins <50530928+ProfXwing@users.noreply.github.com> Date: Sat, 8 Apr 2023 11:23:48 -0400 Subject: [PATCH 1/4] new window returns desktop context --- packages/desktop/src/desktop_context.rs | 9 +++----- packages/desktop/src/lib.rs | 30 +++++++++++++++---------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 2ed4bbee9..03166d272 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::rc::Rc; -use std::rc::Weak; use crate::create_new_window; use crate::eval::EvalResult; @@ -112,8 +111,8 @@ 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 { - let window = create_new_window( + pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> DesktopContext { + let (window, desktop_context) = create_new_window( cfg, &self.event_loop, &self.proxy, @@ -133,11 +132,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) + desktop_context } /// trigger the drag-window event diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 75c67dd22..0a9a8558c 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -144,8 +144,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, @@ -153,7 +152,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; @@ -280,26 +282,30 @@ fn create_new_window( queue: &WebviewQueue, event_handlers: &WindowEventHandlers, shortcut_manager: ShortcutRegistry, -) -> WebviewHandler { +) -> (WebviewHandler, DesktopContext) { let webview = webview::build(&mut cfg, event_loop, proxy.clone()); - - dom.base_scope().provide_context(DesktopContext::new( + let desktop_context = DesktopContext::new( webview.clone(), proxy.clone(), event_loop.clone(), queue.clone(), event_handlers.clone(), shortcut_manager, - )); + ); + + dom.base_scope().provide_context(desktop_context.clone()); let id = 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, - dom, - waker: waker::tao_waker(proxy, id), - } + ( + WebviewHandler { + webview, + dom, + waker: waker::tao_waker(proxy, id), + }, + desktop_context, + ) } struct WebviewHandler { From 0e1f015b78e82e28e4a1889eaa6552c6ef981ee1 Mon Sep 17 00:00:00 2001 From: Andrew Collins <50530928+ProfXwing@users.noreply.github.com> Date: Tue, 11 Apr 2023 11:03:46 -0400 Subject: [PATCH 2/4] turn desktop context into Rc --- packages/desktop/src/desktop_context.rs | 19 +++++++++++++------ packages/desktop/src/lib.rs | 22 ++++++++++------------ packages/desktop/src/shortcut.rs | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 03166d272..35da2eab3 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -1,5 +1,6 @@ use std::cell::RefCell; use std::rc::Rc; +use std::rc::Weak; use crate::create_new_window; use crate::eval::EvalResult; @@ -30,8 +31,8 @@ use wry::webview::WebView; pub type ProxyType = EventLoopProxy; /// Get an imperative handle to the current window -pub fn use_window(cx: &ScopeState) -> &DesktopContext { - cx.use_hook(|| cx.consume_context::()) +pub fn use_window(cx: &ScopeState) -> &Rc { + cx.use_hook(|| cx.consume_context::>()) .as_ref() .unwrap() } @@ -111,8 +112,8 @@ 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) -> DesktopContext { - let (window, desktop_context) = create_new_window( + pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak { + let window = create_new_window( cfg, &self.event_loop, &self.proxy, @@ -122,6 +123,12 @@ impl DesktopContext { self.shortcut_manager.clone(), ); + let desktop_context = window + .dom + .base_scope() + .consume_context::>() + .unwrap(); + let id = window.webview.window().id(); self.proxy @@ -134,7 +141,7 @@ impl DesktopContext { self.pending_windows.borrow_mut().push(window); - desktop_context + Rc::downgrade(&desktop_context) } /// trigger the drag-window event @@ -420,7 +427,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 0a9a8558c..2a6f5aa6b 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -144,7 +144,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) let shortcut_manager = ShortcutRegistry::new(&event_loop); - let (web_view, _) = create_new_window( + let web_view = create_new_window( cfg, &event_loop, &proxy, @@ -282,30 +282,28 @@ fn create_new_window( queue: &WebviewQueue, event_handlers: &WindowEventHandlers, shortcut_manager: ShortcutRegistry, -) -> (WebviewHandler, DesktopContext) { +) -> WebviewHandler { let webview = webview::build(&mut cfg, event_loop, proxy.clone()); - let desktop_context = DesktopContext::new( + let desktop_context = Rc::from(DesktopContext::new( webview.clone(), proxy.clone(), event_loop.clone(), queue.clone(), event_handlers.clone(), shortcut_manager, - ); + )); dom.base_scope().provide_context(desktop_context.clone()); let id = 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, - dom, - waker: waker::tao_waker(proxy, id), - }, - desktop_context, - ) + + WebviewHandler { + webview, + dom, + waker: waker::tao_waker(proxy, id), + } } struct WebviewHandler { diff --git a/packages/desktop/src/shortcut.rs b/packages/desktop/src/shortcut.rs index 5232bdb8b..e70d13235 100644 --- a/packages/desktop/src/shortcut.rs +++ b/packages/desktop/src/shortcut.rs @@ -146,7 +146,7 @@ pub struct ShortcutId { /// A global shortcut. This will be automatically removed when it is dropped. pub struct ShortcutHandle { - desktop: DesktopContext, + desktop: Rc, /// The id of the shortcut pub shortcut_id: ShortcutId, } From 64575eaee24fec9d10545648aa7d74f1c766de53 Mon Sep 17 00:00:00 2001 From: Andrew Collins <50530928+ProfXwing@users.noreply.github.com> Date: Tue, 11 Apr 2023 11:06:16 -0400 Subject: [PATCH 3/4] forgot one --- packages/desktop/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 2a6f5aa6b..270eb1580 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -248,7 +248,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) webviews[&event.1] .dom .base_scope() - .consume_context::() + .consume_context::>() .unwrap() .eval .send(msg.params()) From d6b9d8f5b65fc0931bd5381ea967fb7f7d487a74 Mon Sep 17 00:00:00 2001 From: Andrew Collins <50530928+ProfXwing@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:45:00 -0400 Subject: [PATCH 4/4] remove rc around webview and add type for desktopcontext --- packages/desktop/src/desktop_context.rs | 23 +++++++++++----------- packages/desktop/src/lib.rs | 26 +++++++++++++------------ packages/desktop/src/shortcut.rs | 4 ++-- packages/desktop/src/webview.rs | 6 ++---- 4 files changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 35da2eab3..effd9acd1 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -31,8 +31,8 @@ use wry::webview::WebView; pub type ProxyType = EventLoopProxy; /// Get an imperative handle to the current window -pub fn use_window(cx: &ScopeState) -> &Rc { - cx.use_hook(|| cx.consume_context::>()) +pub fn use_window(cx: &ScopeState) -> &DesktopContext { + cx.use_hook(|| cx.consume_context::()) .as_ref() .unwrap() } @@ -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, @@ -126,10 +127,10 @@ impl DesktopContext { let desktop_context = window .dom .base_scope() - .consume_context::>() + .consume_context::>() .unwrap(); - let id = window.webview.window().id(); + let id = window.desktop_context.webview.window().id(); self.proxy .send_event(UserWindowEvent(EventData::NewWindow, id)) diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 270eb1580..fe8ba237e 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -15,9 +15,11 @@ mod webview; 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::HtmlEvent; pub use eval::{use_eval, EvalResult}; @@ -186,7 +188,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)); } @@ -232,12 +234,12 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) view.dom .handle_event(&evt.name, evt.data.into_any(), evt.element, evt.bubbles); - send_edits(view.dom.render_immediate(), &view.webview); + send_edits(view.dom.render_immediate(), &view.desktop_context.webview); } 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); } // When the webview chirps back with the result of the eval, we send it to the active receiver @@ -248,7 +250,7 @@ pub fn launch_with_props(root: Component

, props: P, cfg: Config) webviews[&event.1] .dom .base_scope() - .consume_context::>() + .consume_context::() .unwrap() .eval .send(msg.params()) @@ -284,8 +286,8 @@ fn create_new_window( shortcut_manager: ShortcutRegistry, ) -> WebviewHandler { let webview = webview::build(&mut cfg, event_loop, proxy.clone()); - let desktop_context = Rc::from(DesktopContext::new( - webview.clone(), + let desktop_context = Rc::from(DesktopService::new( + webview, proxy.clone(), event_loop.clone(), queue.clone(), @@ -295,12 +297,12 @@ fn create_new_window( dom.base_scope().provide_context(desktop_context.clone()); - let id = webview.window().id(); + 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), } @@ -308,7 +310,7 @@ fn create_new_window( struct WebviewHandler { dom: VirtualDom, - webview: Rc, + desktop_context: DesktopContext, waker: Waker, } @@ -331,7 +333,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 e70d13235..8d1c09d1a 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 { @@ -146,7 +146,7 @@ pub struct ShortcutId { /// A global shortcut. This will be automatically removed when it is dropped. pub struct ShortcutHandle { - desktop: Rc, + desktop: DesktopContext, /// The id of the shortcut pub shortcut_id: ShortcutId, } diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs index 099a2bd94..8e1687374 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 { +) -> WebView { let builder = cfg.window.clone(); let window = builder.build(event_loop).unwrap(); let file_handler = cfg.file_drop_handler.take(); @@ -82,5 +80,5 @@ pub fn build( webview = webview.with_devtools(true); } - Rc::new(webview.build().unwrap()) + webview.build().unwrap() }