فهرست منبع

Merge pull request #945 from ProfXwing/return-context

make new_window return desktop context instead of webview
Jon Kelley 2 سال پیش
والد
کامیت
014bdef744
4فایلهای تغییر یافته به همراه41 افزوده شده و 32 حذف شده
  1. 17 12
      packages/desktop/src/desktop_context.rs
  2. 21 15
      packages/desktop/src/lib.rs
  3. 1 1
      packages/desktop/src/shortcut.rs
  4. 2 4
      packages/desktop/src/webview.rs

+ 17 - 12
packages/desktop/src/desktop_context.rs

@@ -51,10 +51,9 @@ pub(crate) type WebviewQueue = Rc<RefCell<Vec<WebviewHandler>>>;
 /// ```rust, ignore
 ///     let desktop = cx.consume_context::<DesktopContext>().unwrap();
 /// ```
-#[derive(Clone)]
-pub struct DesktopContext {
+pub struct DesktopService {
     /// The wry/tao proxy to the current window
-    pub webview: Rc<WebView>,
+    pub webview: WebView,
 
     /// The proxy to the event loop
     pub proxy: ProxyType,
@@ -74,8 +73,10 @@ pub struct DesktopContext {
     pub(crate) views: Rc<RefCell<Vec<*mut objc::runtime::Object>>>,
 }
 
+pub type DesktopContext = Rc<DesktopService>;
+
 /// 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: WebView,
         proxy: ProxyType,
         event_loop: EventLoopWindowTarget<UserWindowEvent>,
         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<WebView> {
+    pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak<DesktopService> {
         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::<Rc<DesktopService>>()
+            .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,
         }
     })

+ 21 - 15
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<P: 'static>(root: Component<P>, 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<P: 'static>(root: Component<P>, 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<P: 'static>(root: Component<P>, 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<P: 'static>(root: Component<P>, 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<P: 'static>(root: Component<P>, 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<wry::webview::WebView>,
+    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);
     }
 }
 

+ 1 - 1
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 {

+ 2 - 4
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<UserWindowEvent>,
     proxy: EventLoopProxy<UserWindowEvent>,
-) -> (Rc<WebView>, 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)
 }