Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 14 additions & 11 deletions packages/native/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,12 @@ homepage = "https://dioxuslabs.com/learn/0.7/getting_started"
keywords = ["dom", "ui", "gui", "react"]

[features]
default = ["accessibility", "hot-reload", "net", "html", "svg", "system-fonts", "clipboard", "file_dialog", "vello-hybrid", "incremental", "woff", "apple-font-embolden"]
default = ["shell", "accessibility", "hot-reload", "net", "html", "svg", "system-fonts", "clipboard", "file_dialog", "vello-hybrid", "incremental", "woff", "apple-font-embolden"]
prelude = ["dep:dioxus-core-macro", "dep:dioxus-hooks", "dep:dioxus-signals", "dep:dioxus-stores", "dep:manganis"]

# Blitz-shell/Winit integration.
shell = ["dep:blitz-shell", "dep:winit"]

# DOM features
svg = ["blitz-dom/svg", "blitz-paint/svg"]
floats = ["blitz-dom/floats"]
Expand All @@ -24,11 +27,11 @@ system-fonts = ["blitz-dom/system_fonts"]
woff = ["blitz-dom/woff"]

# Shell Features
clipboard = ["blitz-shell/clipboard"]
file_dialog = ["file-dialog"] # Backwards compat. Remove in next breaking version
file-dialog = ["blitz-shell/file_dialog"]
accessibility = ["blitz-shell/accessibility", "blitz-dom/accessibility"]
data-uri = ["blitz-shell/data-uri"]
clipboard = ["shell", "blitz-shell/clipboard"]
file_dialog = ["shell", "file-dialog"] # Backwards compat. Remove in next breaking version
file-dialog = ["shell", "blitz-shell/file_dialog"]
accessibility = ["shell", "blitz-shell/accessibility", "blitz-dom/accessibility"]
data-uri = ["shell", "blitz-shell/data-uri"]

# Renderer features
vello = ["dep:anyrender_vello", "dep:wgpu_context"]
Expand Down Expand Up @@ -60,7 +63,7 @@ log-frame-times = [
"anyrender_vello_hybrid?/log_frame_times",
"anyrender_skia?/log_frame_times",
]
tracing = ["dep:tracing", "dioxus-native-dom/tracing", "blitz-shell/tracing", "blitz-dom/tracing", "blitz-html/tracing", "blitz-net/tracing"]
tracing = ["dep:tracing", "dioxus-native-dom/tracing", "blitz-shell?/tracing", "blitz-dom/tracing", "blitz-html/tracing", "blitz-net/tracing"]

[dependencies]
# Blitz dependencies
Expand All @@ -69,7 +72,7 @@ blitz-html = { workspace = true, optional = true }
blitz-net = { workspace = true, optional = true }
blitz-paint = { workspace = true, optional = true, features = ["custom-widget"] }
blitz-traits = { workspace = true }
blitz-shell = { workspace = true }
blitz-shell = { workspace = true, optional = true }

# AnyRender dependencies
anyrender = { workspace = true }
Expand Down Expand Up @@ -99,7 +102,7 @@ dioxus-core-macro = { workspace = true, optional = true }
manganis = { workspace = true, features = ["dioxus"], optional = true }

# Windowing & Input
winit = { workspace = true }
winit = { workspace = true, optional = true }
keyboard-types = { workspace = true }

# IO & Networking
Expand All @@ -115,8 +118,8 @@ cfg-if = "1.0.4"
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tokio = { workspace = true, features = ["rt-multi-thread"], optional = true }

[target.'cfg(target_os = "android")'.dependencies]
android-activity = { version = "0.6", default-features = false }
[target.'cfg(all(target_os = "android", feature = "shell"))'.dependencies]
android-activity = { version = "0.6", default-features = false, optional = true }

[target.'cfg(all(target_os = "ios", target_abi = "sim"))'.dependencies]
anyrender_vello_cpu = { workspace = true, features = ["pixels_window_renderer"]}
Expand Down
7 changes: 6 additions & 1 deletion packages/native/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use blitz_dom::FontContext;
use dioxus_core::LaunchConfig;
#[cfg(feature = "shell")]
use winit::window::WindowAttributes;

/// Launch-time configuration for a dioxus-native application.
pub struct Config {
#[cfg(feature = "shell")]
pub(crate) window_attributes: WindowAttributes,
pub(crate) font_ctx: Option<FontContext>,
}
Expand All @@ -12,6 +14,7 @@ impl LaunchConfig for Config {}

impl Default for Config {
fn default() -> Self {
#[cfg(feature = "shell")]
let window_attributes = WindowAttributes::default()
.with_title(dioxus_cli_config::app_title().unwrap_or_else(|| "Dioxus App".to_string()));

Expand All @@ -21,7 +24,7 @@ impl Default for Config {
// the canvas's CSS layout box when winit reports a 0×0 initial size.
// To target an existing `<canvas>`, replace these attributes via
// [`Config::with_window_attributes`].
#[cfg(target_arch = "wasm32")]
#[cfg(all(feature = "shell", target_arch = "wasm32"))]
let window_attributes = {
use winit::platform::web::WindowAttributesWeb;
window_attributes.with_platform_attributes(Box::new(
Expand All @@ -30,6 +33,7 @@ impl Default for Config {
};

Self {
#[cfg(feature = "shell")]
window_attributes,
font_ctx: None,
}
Expand All @@ -42,6 +46,7 @@ impl Config {
}

/// Set the configuration for the window.
#[cfg(feature = "shell")]
pub fn with_window_attributes(mut self, attrs: WindowAttributes) -> Self {
self.window_attributes = attrs;
self
Expand Down
203 changes: 5 additions & 198 deletions packages/native/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,45 +8,21 @@
//! - `hot-reload`: Enables hot-reloading of Dioxus RSX.
//! - `menu`: Enables the [`muda`](https://docs.rs/muda/latest/muda/) menubar.
//! - `tracing`: Enables tracing support.
//! - `shell`: Enables window and event-loop integration with blitz-shell and winit.

mod assets;
mod config;
mod contexts;
mod dioxus_application;
mod dioxus_renderer;
mod link_handler;
#[cfg(feature = "shell")]
mod shell;

#[cfg(feature = "prelude")]
pub mod prelude;

#[cfg(all(feature = "net", not(target_arch = "wasm32")))]
use blitz_traits::net::NetProvider;
#[doc(inline)]
pub use dioxus_native_dom::*;

use assets::DioxusNativeNetProvider;
pub use dioxus_application::{DioxusNativeApplication, DioxusNativeEvent};
pub use dioxus_renderer::DioxusNativeWindowRenderer;

#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
/// Set the current [`AndroidApp`](android_activity::AndroidApp).
pub fn set_android_app(app: android_activity::AndroidApp) {
blitz_shell::set_android_app(app);
}

#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
/// Get the current [`AndroidApp`](android_activity::AndroidApp).
/// This will panic if the android activity has not been setup with [`set_android_app`].
pub fn current_android_app() -> android_activity::AndroidApp {
blitz_shell::current_android_app()
}

#[cfg(target_os = "android")]
#[cfg_attr(docsrs, doc(cfg(target_os = "android")))]
pub use android_activity::AndroidApp;

#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
pub use {
dioxus_renderer::{Features, Limits},
Expand All @@ -55,175 +31,6 @@ pub use {

pub use blitz_dom::{FontContext, Widget, build_single_font_ctx};
pub use config::Config;
pub use winit::dpi::{LogicalSize, PhysicalSize};
pub use winit::window::WindowAttributes;

use blitz_shell::{BlitzShellEvent, BlitzShellProxy, WindowConfig, create_default_event_loop};
use dioxus_core::{ComponentFunction, Element, VirtualDom, consume_context, use_hook};
use link_handler::DioxusNativeNavigationProvider;
use std::any::Any;
use std::sync::Arc;
use winit::{
raw_window_handle::{HasWindowHandle as _, RawWindowHandle},
window::Window,
};

pub fn use_window() -> Arc<dyn Window> {
use_hook(consume_context::<Arc<dyn Window>>)
}

pub fn use_raw_window_handle() -> RawWindowHandle {
use_hook(|| {
consume_context::<Arc<dyn Window>>()
.window_handle()
.unwrap()
.as_raw()
})
}

/// Launch an interactive HTML/CSS renderer driven by the Dioxus virtualdom
pub fn launch(app: fn() -> Element) {
launch_cfg(app, vec![], vec![])
}

pub fn launch_cfg(
app: fn() -> Element,
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
cfg: Vec<Box<dyn Any>>,
) {
launch_cfg_with_props(app, (), contexts, cfg)
}

// todo: props shouldn't have the clone bound - should try and match dioxus-desktop behavior
pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
app: impl ComponentFunction<P, M>,
props: P,
contexts: Vec<Box<dyn Fn() -> Box<dyn Any> + Send + Sync>>,
configs: Vec<Box<dyn Any>>,
) {
// Macro to attempt to downcast a type out of a Box<dyn Any>
macro_rules! try_read_config {
($input:ident, $store:ident, $kind:ty) => {
// Try to downcast the Box<dyn Any> to type $kind
match $input.downcast::<$kind>() {
// If the type matches then write downcast value to variable $store
Ok(value) => {
$store = Some(*value);
continue;
}
// Else extract the original Box<dyn Any> value out of the error type
// and return it so that we can try again with a different type.
Err(cfg) => cfg,
}
};
}

// Read config values
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
let (mut features, mut limits) = (None, None);
let mut window_attributes = None;
let mut config = None;
for mut cfg in configs {
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
{
cfg = try_read_config!(cfg, features, Features);
cfg = try_read_config!(cfg, limits, Limits);
}
cfg = try_read_config!(cfg, window_attributes, WindowAttributes);
cfg = try_read_config!(cfg, config, Config);
let _ = cfg;
}

let mut config = config.unwrap_or_default();
if let Some(window_attributes) = window_attributes {
config.window_attributes = window_attributes;
}
let event_loop = create_default_event_loop();
let winit_proxy = event_loop.create_proxy();
let (proxy, event_queue) = BlitzShellProxy::new(winit_proxy);

// Turn on the runtime and enter it
#[cfg(feature = "net")]
#[cfg(not(target_arch = "wasm32"))]
let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.unwrap();
#[cfg(feature = "net")]
#[cfg(not(target_arch = "wasm32"))]
let _guard = rt.enter();

// Setup hot-reloading if enabled.
#[cfg(all(feature = "hot-reload", debug_assertions))]
#[cfg(not(target_arch = "wasm32"))]
{
let proxy = proxy.clone();
dioxus_devtools::connect(move |event| {
let dxn_event = DioxusNativeEvent::DevserverEvent(event);
proxy.send_event(BlitzShellEvent::embedder_event(dxn_event));
})
}

// Build the vdom first; the net provider, document, and other window-bound
// contexts are attached below once the event-loop proxy exists.
let mut vdom = VirtualDom::new_with_props(app, props);

for context in contexts {
vdom.insert_any_root_context(context());
}

#[cfg(all(feature = "net", not(target_arch = "wasm32")))]
let net_provider = {
let net_waker = Some(Arc::new(proxy.clone()) as _);
let inner_net_provider = Arc::new(blitz_net::Provider::new(net_waker));
vdom.provide_root_context(Arc::clone(&inner_net_provider));

Arc::new(DioxusNativeNetProvider::with_inner(
proxy.clone(),
inner_net_provider as _,
)) as Arc<dyn NetProvider>
};

#[cfg(any(not(feature = "net"), target_arch = "wasm32"))]
let net_provider = DioxusNativeNetProvider::shared(proxy.clone());

vdom.provide_root_context(Arc::clone(&net_provider));

#[cfg(feature = "html")]
let html_parser_provider = {
let html_parser = Arc::new(blitz_html::HtmlProvider) as _;
vdom.provide_root_context(Arc::clone(&html_parser));
Some(html_parser)
};
#[cfg(not(feature = "html"))]
let html_parser_provider = None;

let navigation_provider = Some(Arc::new(DioxusNativeNavigationProvider) as _);

// Create document + window from the baked virtualdom
let doc = DioxusDocument::new(
vdom,
DocumentConfig {
net_provider: Some(net_provider),
html_parser_provider,
navigation_provider,
font_ctx: config.font_ctx,
..Default::default()
},
);
#[cfg(any(feature = "vello", feature = "vello-hybrid"))]
let renderer = DioxusNativeWindowRenderer::with_features_and_limits(features, limits);
#[cfg(not(any(feature = "vello", feature = "vello-hybrid")))]
let renderer = DioxusNativeWindowRenderer::new();
let config = WindowConfig::with_attributes(
Box::new(doc) as _,
renderer.clone(),
config.window_attributes,
);

// Create application
let application = DioxusNativeApplication::new(proxy, event_queue, config);

// Run event loop
event_loop.run_app(application).unwrap();
}
#[cfg(feature = "shell")]
pub use shell::*;
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ use winit::window::WindowId;
#[cfg(target_os = "macos")]
use winit::platform::macos::ApplicationHandlerExtMacOS;

use crate::DioxusDocument;
use crate::DioxusNativeWindowRenderer;
use crate::{BlitzShellEvent, DioxusDocument, WindowConfig, contexts::DioxusNativeDocument};
use crate::shell::contexts::DioxusNativeDocument;
use blitz_shell::{BlitzShellEvent, WindowConfig};

/// Dioxus-native specific event type
pub enum DioxusNativeEvent {
Expand Down
Loading
Loading