diff --git a/packages/desktop/src/app.rs b/packages/desktop/src/app.rs
index c40029b34..e4d758b7d 100644
--- a/packages/desktop/src/app.rs
+++ b/packages/desktop/src/app.rs
@@ -1,10 +1,11 @@
use crate::{
cfg::{Config, WindowCloseBehaviour},
- desktop_context::{EventData, UserWindowEvent, WindowEventHandlers},
+ desktop_context::WindowEventHandlers,
edits::WebviewQueue,
element::DesktopElement,
file_upload::FileDialogRequest,
ipc::IpcMessage,
+ ipc::{EventData, UserWindowEvent},
query::QueryResult,
shortcut::{GlobalHotKeyEvent, ShortcutRegistry},
webview::WebviewInstance,
@@ -12,7 +13,6 @@ use crate::{
use crossbeam_channel::Receiver;
use dioxus_core::{Component, ElementId, VirtualDom};
use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent, MountedData};
-use futures_util::{pin_mut, FutureExt};
use std::{cell::Cell, collections::HashMap, rc::Rc, sync::Arc};
use tao::{
event::Event,
@@ -33,6 +33,10 @@ pub(crate) struct App
{
pub(crate) webviews: HashMap,
pub(crate) window_behavior: WindowCloseBehaviour,
+ /// This bit of state is shared between all the windows, providing a way for us to communicate with
+ /// running instances.
+ ///
+ /// Todo: everything in this struct is wrapped in Rc<>, but we really only need the one top-level refcell
pub(crate) shared: SharedContext,
}
@@ -249,10 +253,7 @@ impl App {
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
for webview in self.webviews.values_mut() {
webview.dom.replace_template(template);
- }
-
- for id in self.webviews.keys().copied().collect::>() {
- self.poll_vdom(id);
+ webview.poll_vdom();
}
}
dioxus_hot_reload::HotReloadMsg::Shutdown => {
@@ -300,24 +301,7 @@ impl App {
return;
};
- let mut cx = std::task::Context::from_waker(&view.waker);
-
- // Continously poll the virtualdom until it's pending
- // Wait for work will return Ready when it has edits to be sent to the webview
- // It will return Pending when it needs to be polled again - nothing is ready
- loop {
- {
- let fut = view.dom.wait_for_work();
- pin_mut!(fut);
-
- match fut.poll_unpin(&mut cx) {
- std::task::Poll::Ready(_) => {}
- std::task::Poll::Pending => return,
- }
- }
-
- view.desktop_context.send_edits(view.dom.render_immediate());
- }
+ view.poll_vdom();
}
}
diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs
index 3988bbbce..b02eca60e 100644
--- a/packages/desktop/src/desktop_context.rs
+++ b/packages/desktop/src/desktop_context.rs
@@ -1,19 +1,21 @@
-use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
-use crate::AssetHandler;
-use crate::Config;
-use crate::{app::SharedContext, ipc::IpcMessage};
-use crate::{assets::AssetFuture, edits::WebviewQueue};
-use crate::{assets::AssetHandlerRegistry, edits::EditQueue};
-use crate::{query::QueryEngine, webview::WebviewInstance};
-use dioxus_core::Mutations;
-use dioxus_core::VirtualDom;
+use crate::{
+ app::SharedContext,
+ assets::{AssetFuture, AssetHandlerRegistry},
+ edits::EditQueue,
+ ipc::{EventData, UserWindowEvent},
+ query::QueryEngine,
+ shortcut::{HotKey, ShortcutId, ShortcutRegistryError},
+ webview::WebviewInstance,
+ AssetHandler, Config,
+};
+use dioxus_core::{Mutations, VirtualDom};
use dioxus_interpreter_js::binary_protocol::Channel;
use rustc_hash::FxHashMap;
use slab::Slab;
use std::{cell::RefCell, fmt::Debug, rc::Rc, rc::Weak, sync::atomic::AtomicU16};
use tao::{
event::Event,
- event_loop::{EventLoopProxy, EventLoopWindowTarget},
+ event_loop::EventLoopWindowTarget,
window::{Fullscreen as WryFullscreen, Window, WindowId},
};
use wry::WebView;
@@ -52,21 +54,13 @@ pub struct DesktopService {
/// The tao window itself
pub window: Window,
- /// The receiver for queries about the current window
- pub(super) query: QueryEngine,
-
pub(crate) shared: SharedContext,
- // pub(crate) event_handlers: WindowEventHandlers,
- // pub(super) pending_windows: WebviewQueue,
- // pub(crate) shortcut_manager: ShortcutRegistry,
-
- // pub(crate) event_loop: EventLoopWindowTarget,
+ /// The receiver for queries about the current window
+ pub(super) query: QueryEngine,
pub(crate) edit_queue: EditQueue,
-
pub(crate) templates: RefCell>,
pub(crate) max_template_count: AtomicU16,
-
pub(crate) channel: RefCell,
pub(crate) asset_handlers: AssetHandlerRegistry,
@@ -153,22 +147,17 @@ impl DesktopService {
/// onmousedown: move |_| { desktop.drag_window(); }
/// ```
pub fn drag(&self) {
- let window = &self.window;
-
- // if the drag_window has any errors, we don't do anything
- if window.fullscreen().is_none() {
- window.drag_window().unwrap();
+ if self.window.fullscreen().is_none() {
+ _ = self.window.drag_window();
}
}
/// Toggle whether the window is maximized or not
pub fn toggle_maximized(&self) {
- let window = &self.window;
-
- window.set_maximized(!window.is_maximized())
+ self.window.set_maximized(!self.window.is_maximized())
}
- /// close window
+ /// Close this window
pub fn close(&self) {
let _ = self
.shared
@@ -176,7 +165,7 @@ impl DesktopService {
.send_event(UserWindowEvent(EventData::CloseWindow, self.id()));
}
- /// close window
+ /// Close a particular window, given its ID
pub fn close_window(&self, id: WindowId) {
let _ = self
.shared
@@ -304,23 +293,6 @@ impl DesktopService {
}
}
-#[derive(Debug, Clone)]
-pub struct UserWindowEvent(pub EventData, pub WindowId);
-
-#[derive(Debug, Clone)]
-pub enum EventData {
- Poll,
-
- Ipc(IpcMessage),
-
- #[cfg(all(feature = "hot-reload", debug_assertions))]
- HotReloadEvent(dioxus_hot_reload::HotReloadMsg),
-
- NewWindow,
-
- CloseWindow,
-}
-
#[cfg(target_os = "ios")]
fn is_main_thread() -> bool {
use objc::runtime::{Class, BOOL, NO};
diff --git a/packages/desktop/src/hooks.rs b/packages/desktop/src/hooks.rs
index 0f53f7ee6..d57d1bc5b 100644
--- a/packages/desktop/src/hooks.rs
+++ b/packages/desktop/src/hooks.rs
@@ -1,7 +1,9 @@
use std::rc::Rc;
-use crate::{assets::*, shortcut::IntoAccelerator, ShortcutHandle, ShortcutRegistryError};
-use crate::{desktop_context::UserWindowEvent, window, DesktopContext, WryEventHandler};
+use crate::{
+ assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext,
+ ShortcutHandle, ShortcutRegistryError, WryEventHandler,
+};
use dioxus_core::ScopeState;
use tao::{event::Event, event_loop::EventLoopWindowTarget};
diff --git a/packages/desktop/src/ipc.rs b/packages/desktop/src/ipc.rs
index 54c6d0eb0..5d939e808 100644
--- a/packages/desktop/src/ipc.rs
+++ b/packages/desktop/src/ipc.rs
@@ -1,4 +1,22 @@
use serde::{Deserialize, Serialize};
+use tao::window::WindowId;
+
+#[derive(Debug, Clone)]
+pub struct UserWindowEvent(pub EventData, pub WindowId);
+
+#[derive(Debug, Clone)]
+pub enum EventData {
+ Poll,
+
+ Ipc(IpcMessage),
+
+ #[cfg(all(feature = "hot-reload", debug_assertions))]
+ HotReloadEvent(dioxus_hot_reload::HotReloadMsg),
+
+ NewWindow,
+
+ CloseWindow,
+}
/// A message struct that manages the communication between the webview and the eventloop code
///
diff --git a/packages/desktop/src/launch.rs b/packages/desktop/src/launch.rs
index 8cdcec9b4..c8676c507 100644
--- a/packages/desktop/src/launch.rs
+++ b/packages/desktop/src/launch.rs
@@ -1,7 +1,6 @@
use crate::{
app::App,
- desktop_context::{EventData, UserWindowEvent},
- ipc::IpcMethod,
+ ipc::{EventData, IpcMethod, UserWindowEvent},
Config,
};
use dioxus_core::*;
diff --git a/packages/desktop/src/waker.rs b/packages/desktop/src/waker.rs
index 488c8f677..de59d81c9 100644
--- a/packages/desktop/src/waker.rs
+++ b/packages/desktop/src/waker.rs
@@ -1,4 +1,4 @@
-use crate::desktop_context::{EventData, UserWindowEvent};
+use crate::ipc::{EventData, UserWindowEvent};
use futures_util::task::ArcWake;
use std::sync::Arc;
use tao::{event_loop::EventLoopProxy, window::WindowId};
diff --git a/packages/desktop/src/webview.rs b/packages/desktop/src/webview.rs
index 3ffee1a3a..286109e13 100644
--- a/packages/desktop/src/webview.rs
+++ b/packages/desktop/src/webview.rs
@@ -1,14 +1,15 @@
use crate::{
app::SharedContext,
assets::AssetHandlerRegistry,
- desktop_context::{EventData, UserWindowEvent},
edits::EditQueue,
eval::DesktopEvalProvider,
+ ipc::{EventData, UserWindowEvent},
protocol::{self},
waker::tao_waker,
Config, DesktopContext, DesktopService,
};
use dioxus_core::VirtualDom;
+use futures_util::{pin_mut, FutureExt};
use std::{rc::Rc, task::Waker};
use wry::{WebContext, WebViewBuilder};
@@ -160,4 +161,25 @@ impl WebviewInstance {
_web_context: web_context,
}
}
+
+ pub fn poll_vdom(&mut self) {
+ let mut cx = std::task::Context::from_waker(&self.waker);
+
+ // Continously poll the virtualdom until it's pending
+ // Wait for work will return Ready when it has edits to be sent to the webview
+ // It will return Pending when it needs to be polled again - nothing is ready
+ loop {
+ {
+ let fut = self.dom.wait_for_work();
+ pin_mut!(fut);
+
+ match fut.poll_unpin(&mut cx) {
+ std::task::Poll::Ready(_) => {}
+ std::task::Poll::Pending => return,
+ }
+ }
+
+ self.desktop_context.send_edits(self.dom.render_immediate());
+ }
+ }
}