Skip to content

Commit 18f4863

Browse files
committed
fix: align window creation and channel usage
1 parent 49cd696 commit 18f4863

5 files changed

Lines changed: 31 additions & 10 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ dioxus-asset-resolver = { version = "0.7" }
7676
manganis = { version = "0.7" }
7777
dioxus-document = { version = "0.7" }
7878
dioxus-history = { version = "0.7" }
79+
futures-channel = "0.3"
7980

8081
# Dioxus hot reload
8182
dioxus-devtools = { version = "0.7" }

examples/multi_window.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ fn app() -> Element {
3535
let attributes = WindowAttributes::default()
3636
.with_title(title)
3737
.with_inner_size(winit::dpi::LogicalSize::new(400.0, 300.0));
38-
let receiver = provider.create_document_window(vdom, attributes);
38+
let receiver = provider.new_window(vdom, attributes);
3939
let mut spawned_windows = spawned_windows;
4040
spawn(async move {
4141
if let Ok((window_id, window)) = receiver.await {

packages/dioxus-native/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ vello-cpu-base = ["alt-renderer", "dep:anyrender_vello_cpu"]
3838
alt-renderer = []
3939

4040
# Other features
41-
net = ["dep:blitz-net"]
41+
net = ["dep:blitz-net", "dep:tokio"]
4242
html = ["dep:blitz-html"]
4343

4444
# Dev
@@ -95,7 +95,8 @@ winit = { workspace = true }
9595
keyboard-types = { workspace = true }
9696

9797
# Runtime + channels
98-
tokio = { workspace = true, features = ["rt-multi-thread", "sync"] }
98+
tokio = { workspace = true, features = ["rt-multi-thread"], optional = true }
99+
futures-channel = { workspace = true }
99100
webbrowser = { workspace = true }
100101

101102
# Other dependencies

packages/dioxus-native/src/dioxus_application.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ use blitz_shell::{BlitzApplication, View};
33
use blitz_traits::{navigation::NavigationProvider, net::NetProvider};
44
use dioxus_core::{provide_context, ScopeId};
55
use dioxus_history::{History, MemoryHistory};
6+
use futures_channel::oneshot;
67
use std::any::Any;
78
use std::rc::Rc;
89
use std::sync::Arc;
9-
use tokio::sync::oneshot;
1010
use winit::application::ApplicationHandler;
11+
1112
use winit::event::{StartCause, WindowEvent};
1213
use winit::event_loop::{ActiveEventLoop, EventLoopProxy};
1314
use winit::window::Window;
@@ -44,20 +45,29 @@ impl<T: ?Sized> OpaquePtr<T> {
4445
}
4546

4647
#[doc(hidden)]
47-
pub struct UnsafeBox<T: ?Sized>(Box<T>);
48+
pub struct UnsafeBox<T: ?Sized> {
49+
value: Box<T>,
50+
owner: std::thread::ThreadId,
51+
}
4852

49-
// Safety: this wrapper exists solely to satisfy the `Send + Sync` bound imposed by the embedder
50-
// event channel. The payloads are only ever created and consumed on the event loop thread.
5153
unsafe impl<T: ?Sized> Send for UnsafeBox<T> {}
5254
unsafe impl<T: ?Sized> Sync for UnsafeBox<T> {}
5355

5456
impl<T: ?Sized> UnsafeBox<T> {
5557
pub fn new(value: Box<T>) -> Self {
56-
Self(value)
58+
Self {
59+
value,
60+
owner: std::thread::current().id(),
61+
}
5762
}
5863

5964
pub fn into_inner(self) -> Box<T> {
60-
self.0
65+
assert_eq!(
66+
self.owner,
67+
std::thread::current().id(),
68+
"UnsafeBox accessed from a different thread",
69+
);
70+
self.value
6171
}
6272
}
6373

@@ -142,6 +152,14 @@ impl DioxusNativeProvider {
142152
receiver
143153
}
144154

155+
pub fn new_window(
156+
&self,
157+
vdom: dioxus_core::VirtualDom,
158+
attributes: winit::window::WindowAttributes,
159+
) -> oneshot::Receiver<(WindowId, Arc<Window>)> {
160+
self.create_document_window(vdom, attributes)
161+
}
162+
145163
pub fn get_window(&self, window_id: WindowId) -> oneshot::Receiver<Option<Arc<Window>>> {
146164
let (sender, receiver) = oneshot::channel();
147165
let reply = UnsafeBox::new(Box::new(sender));
@@ -207,7 +225,7 @@ impl DioxusNativeApplication {
207225
provide_context(shared);
208226
});
209227

210-
let shell_provider = doc.as_ref().shell_provider.clone();
228+
let shell_provider = doc.inner.borrow().shell_provider.clone();
211229
doc.vdom
212230
.in_scope(ScopeId::ROOT, move || provide_context(shell_provider));
213231

0 commit comments

Comments
 (0)