Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed multiwindow closing issue again #3588

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
1 change: 1 addition & 0 deletions packages/desktop/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ impl App {
self.persist_window_state();

self.webviews.remove(&id);

if self.webviews.is_empty() {
self.control_flow = ControlFlow::Exit
}
Expand Down
6 changes: 3 additions & 3 deletions packages/desktop/src/desktop_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use tao::platform::ios::WindowExtIOS;
///
/// This function will panic if it is called outside of the context of a Dioxus App.
pub fn window() -> DesktopContext {
dioxus_core::prelude::consume_context()
dioxus_core::prelude::consume_context::<WeakDesktopContext>().upgrade().unwrap()
}

/// A handle to the [`DesktopService`] that can be passed around.
Expand Down Expand Up @@ -111,7 +111,7 @@ impl DesktopService {

let cx = window.dom.in_runtime(|| {
ScopeId::ROOT
.consume_context::<Rc<DesktopService>>()
.consume_context::<WeakDesktopContext>()
.unwrap()
});

Expand All @@ -122,7 +122,7 @@ impl DesktopService {

self.shared.pending_webviews.borrow_mut().push(window);

Rc::downgrade(&cx)
cx
}

/// trigger the drag-window event
Expand Down
19 changes: 8 additions & 11 deletions packages/desktop/src/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,14 @@ pub struct DesktopDocument {
}

impl DesktopDocument {
pub fn new(desktop_ctx: DesktopContext) -> Self {
let desktop_ctx = std::rc::Rc::downgrade(&desktop_ctx);
pub fn new(desktop_ctx: WeakDesktopContext) -> Self {
Self { desktop_ctx }
}
}

impl Document for DesktopDocument {
fn eval(&self, js: String) -> Eval {
Eval::new(DesktopEvaluator::create(
self.desktop_ctx
.upgrade()
.expect("Window to exist when document is alive"),
js,
))
Eval::new(DesktopEvaluator::create(self.desktop_ctx.clone(), js))
}

fn set_title(&self, title: String) {
Expand Down Expand Up @@ -87,9 +81,12 @@ pub(crate) struct DesktopEvaluator {

impl DesktopEvaluator {
/// Creates a new evaluator for desktop-based targets.
pub fn create(desktop_ctx: DesktopContext, js: String) -> GenerationalBox<Box<dyn Evaluator>> {
let ctx = desktop_ctx.clone();
let query = desktop_ctx.query.new_query(&js, ctx);
pub fn create(
weak_desktop_ctx: WeakDesktopContext,
js: String,
) -> GenerationalBox<Box<dyn Evaluator>> {
let desktop_ctx = weak_desktop_ctx.upgrade().unwrap();
let query = desktop_ctx.query.new_query(&js, weak_desktop_ctx);

// We create a generational box that is owned by the query slot so that when we drop the query slot, the generational box is also dropped.
let owner = UnsyncStorage::owner();
Expand Down
6 changes: 3 additions & 3 deletions packages/desktop/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ use dioxus_html::{
MountedResult, RenderedElementBacking,
};

use crate::{desktop_context::DesktopContext, query::QueryEngine};
use crate::{desktop_context::DesktopContext, query::QueryEngine, WeakDesktopContext};

#[derive(Clone)]
/// A mounted element passed to onmounted events
pub struct DesktopElement {
id: ElementId,
webview: DesktopContext,
webview: WeakDesktopContext,
query: QueryEngine,
}

impl DesktopElement {
pub(crate) fn new(id: ElementId, webview: DesktopContext, query: QueryEngine) -> Self {
pub(crate) fn new(id: ElementId, webview: WeakDesktopContext, query: QueryEngine) -> Self {
Self { id, webview, query }
}
}
Expand Down
12 changes: 7 additions & 5 deletions packages/desktop/src/query.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::DesktopContext;
use crate::{DesktopContext, WeakDesktopContext};
use futures_util::{FutureExt, StreamExt};
use generational_box::Owner;
use serde::{de::DeserializeOwned, Deserialize};
Expand Down Expand Up @@ -45,7 +45,7 @@ impl QueryEngine {
pub fn new_query<V: DeserializeOwned>(
&self,
script: &str,
context: DesktopContext,
weak_context: WeakDesktopContext,
) -> Query<V> {
let (tx, rx) = futures_channel::mpsc::unbounded();
let (return_tx, return_rx) = futures_channel::oneshot::channel();
Expand All @@ -55,6 +55,8 @@ impl QueryEngine {
owner: None,
});

let context = weak_context.upgrade().unwrap();

// start the query
// We embed the return of the eval in a function so we can send it back to the main thread
if let Err(err) = context.webview.evaluate_script(&format!(
Expand Down Expand Up @@ -107,7 +109,7 @@ impl QueryEngine {
id: request_id,
receiver: rx,
return_receiver: Some(return_rx),
desktop: context,
desktop: weak_context,
phantom: std::marker::PhantomData,
}
}
Expand Down Expand Up @@ -140,7 +142,7 @@ impl QueryEngine {
}

pub(crate) struct Query<V: DeserializeOwned> {
desktop: DesktopContext,
desktop: WeakDesktopContext,
receiver: futures_channel::mpsc::UnboundedReceiver<Value>,
return_receiver: Option<futures_channel::oneshot::Receiver<Result<Value, String>>>,
pub id: usize,
Expand All @@ -161,7 +163,7 @@ impl<V: DeserializeOwned> Query<V> {
let data = message.to_string();
let script = format!(r#"window.getQuery({queue_id}).rustSend({data});"#);

self.desktop
self.desktop.upgrade().unwrap()
.webview
.evaluate_script(&script)
.map_err(|e| QueryError::Send(e.to_string()))?;
Expand Down
18 changes: 12 additions & 6 deletions packages/desktop/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,22 +108,25 @@ impl WebviewEdits {
bubbles,
data,
} = event;
let Some(desktop_context) = self.desktop_context.get() else {
let Some(weak_desktop_context) = self.desktop_context.get() else {
tracing::error!(
"Tried to handle event before setting the desktop context on the event handler"
);
return Default::default();
};

let desktop_context = desktop_context.upgrade().unwrap();
let Some(desktop_context) = weak_desktop_context.upgrade() else {
return Default::default();
};

let query = desktop_context.query.clone();
let recent_file = desktop_context.file_hover.clone();

// check for a mounted event placeholder and replace it with a desktop specific element
let as_any = match data {
dioxus_html::EventData::Mounted => {
let element = DesktopElement::new(element, desktop_context.clone(), query.clone());
let element =
DesktopElement::new(element, weak_desktop_context.clone(), query.clone());
Rc::new(PlatformEventData::new(Box::new(element)))
}
dioxus_html::EventData::Drag(ref drag) => {
Expand Down Expand Up @@ -413,12 +416,15 @@ impl WebviewInstance {
file_hover,
));

let weak_desktop_context: WeakDesktopContext = Rc::downgrade(&desktop_context);

// Provide the desktop context to the virtual dom and edit handler
edits.set_desktop_context(Rc::downgrade(&desktop_context));
let provider: Rc<dyn Document> = Rc::new(DesktopDocument::new(desktop_context.clone()));
edits.set_desktop_context(weak_desktop_context.clone());
let provider: Rc<dyn Document> =
Rc::new(DesktopDocument::new(weak_desktop_context.clone()));
let history_provider: Rc<dyn History> = Rc::new(MemoryHistory::default());
dom.in_runtime(|| {
ScopeId::ROOT.provide_context(desktop_context.clone());
ScopeId::ROOT.provide_context(weak_desktop_context.clone());
ScopeId::ROOT.provide_context(provider);
ScopeId::ROOT.provide_context(history_provider);
});
Expand Down
Loading