Fix more examples to work with dioxus-native (#5179)

* Enable native for hotdog, file-explorer, and bluetooth-scanner examples

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Fix crash in calculator example

Signed-off-by: Nico Burns <nico@nicoburns.com>

* Add config macro for native

* Add Config struct to dioxus-native

* Re-export dioxus-native as dioxus::native

* Fix calculator example to work with dioxus-native

* Fix calculator_mutable example to work with dioxus-native

---------

Signed-off-by: Nico Burns <nico@nicoburns.com>
This commit is contained in:
Nico Burns authored and GitHub committed 2026-01-17 00:32:45 +00:00
1 parent 8aefb2a1e2
commit 35e289fe28
13 files changed
+93 -18

No files matched your search

Generated
+1
View File
@@ -5875,6 +5875,7 @@ dependencies = [
"wasm-streams", "wasm-streams",
"web-time", "web-time",
"wgpu 26.0.1", "wgpu 26.0.1",
"winit",
] ]
[[package]] [[package]]
+2 -1
View File
@@ -461,6 +461,7 @@ ciborium = { workspace = true, optional = true }
base64 = { workspace = true, optional = true } base64 = { workspace = true, optional = true }
http-range = { version = "0.1.5" } http-range = { version = "0.1.5" }
wgpu = { workspace = true, optional = true } wgpu = { workspace = true, optional = true }
winit = { workspace = true, optional = true }
ouroboros = { version = "*", optional = true } ouroboros = { version = "*", optional = true }
wasm-splitter = { workspace = true } wasm-splitter = { workspace = true }
@@ -516,7 +517,7 @@ tokio = { version = "1.48", features = ["full"] }
[features] [features]
default = ["desktop"] default = ["desktop"]
desktop = ["dioxus/desktop"] desktop = ["dioxus/desktop"]
native = ["dioxus/native"] native = ["dioxus/native", "winit"]
liveview = ["dioxus/liveview"] liveview = ["dioxus/liveview"]
server = ["dioxus/server"] server = ["dioxus/server"]
mobile = ["dioxus/mobile"] mobile = ["dioxus/mobile"]
@@ -8,7 +8,12 @@ publish = false
[dependencies] [dependencies]
tokio = { workspace = true, features = ["full"] } tokio = { workspace = true, features = ["full"] }
dioxus = { workspace = true, features = ["desktop"] } dioxus = { workspace = true }
futures-channel = { workspace = true } futures-channel = { workspace = true }
futures = { workspace = true } futures = { workspace = true }
btleplug = "0.11.8" btleplug = "0.11.8"
[features]
default = ["desktop"]
desktop = ["dioxus/desktop"]
native = ["dioxus/native"]
+12 -3
View File
@@ -12,15 +12,24 @@ use dioxus::events::*;
use dioxus::html::input_data::keyboard_types::Key; use dioxus::html::input_data::keyboard_types::Key;
use dioxus::prelude::*; use dioxus::prelude::*;
const TITLE: &str = "Calculator";
const STYLE: Asset = asset!("/examples/assets/calculator.css"); const STYLE: Asset = asset!("/examples/assets/calculator.css");
fn main() { fn main() {
dioxus::LaunchBuilder::desktop() dioxus::LaunchBuilder::new()
.with_cfg(desktop!({ .with_cfg(desktop!({
use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
Config::new().with_window( Config::new().with_window(
WindowBuilder::default() WindowBuilder::default()
.with_title("Calculator") .with_title(TITLE)
.with_inner_size(LogicalSize::new(300.0, 525.0)),
)
}))
.with_cfg(native!({
use dioxus::native::{Config, LogicalSize, WindowAttributes};
Config::new().with_window_attributes(
WindowAttributes::default()
.with_title(TITLE)
.with_inner_size(LogicalSize::new(300.0, 525.0)), .with_inner_size(LogicalSize::new(300.0, 525.0)),
) )
})) }))
@@ -146,7 +155,7 @@ fn calc_val(val: &str) -> f64 {
let mut temp_value; let mut temp_value;
let mut fin_index = 0; let mut fin_index = 0;
if &val[0..1] == "-" { if val.len() > 1 && &val[0..1] == "-" {
temp_value = String::from("-"); temp_value = String::from("-");
fin_index = 1; fin_index = 1;
start_index += 1; start_index += 1;
+13 -6
View File
@@ -6,22 +6,29 @@
//! Generally, you'll want to split your state into several signals if you have a large application, but for small //! Generally, you'll want to split your state into several signals if you have a large application, but for small
//! applications, or focused components, this is a great way to manage state. //! applications, or focused components, this is a great way to manage state.
use dioxus::desktop::tao::dpi::LogicalSize;
use dioxus::desktop::{Config, WindowBuilder};
use dioxus::html::MouseEvent; use dioxus::html::MouseEvent;
use dioxus::html::input_data::keyboard_types::Key; use dioxus::html::input_data::keyboard_types::Key;
use dioxus::prelude::*; use dioxus::prelude::*;
fn main() { fn main() {
dioxus::LaunchBuilder::desktop() dioxus::LaunchBuilder::new()
.with_cfg( .with_cfg(desktop! {{
use dioxus::desktop::{Config, LogicalSize, WindowBuilder};
Config::new().with_window( Config::new().with_window(
WindowBuilder::new() WindowBuilder::new()
.with_title("Calculator Demo") .with_title("Calculator Demo")
.with_resizable(false) .with_resizable(false)
.with_inner_size(LogicalSize::new(320.0, 530.0)), .with_inner_size(LogicalSize::new(320.0, 530.0)),
), )
) }})
.with_cfg(native! {{
use dioxus::native::{Config, LogicalSize, WindowAttributes};
Config::new().with_window_attributes(
WindowAttributes::default()
.with_title("Calculator Demo")
.with_inner_size(LogicalSize::new(300.0, 525.0)),
)
}})
.launch(app); .launch(app);
} }
@@ -7,5 +7,10 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dioxus = { workspace = true, features = ["desktop"] } dioxus = { workspace = true }
open = { workspace = true } open = { workspace = true }
[features]
default = ["desktop"]
desktop = ["dioxus/desktop"]
native = ["dioxus/native"]
+1
View File
@@ -17,5 +17,6 @@ anyhow = { workspace = true }
default = ["web", "server"] default = ["web", "server"]
web = ["dioxus/web"] web = ["dioxus/web"]
desktop = ["dioxus/desktop"] desktop = ["dioxus/desktop"]
native = ["dioxus/native"]
mobile = ["dioxus/mobile"] mobile = ["dioxus/mobile"]
server = ["dioxus/server", "dep:rusqlite"] server = ["dioxus/server", "dep:rusqlite"]
+1
View File
@@ -20,6 +20,7 @@ quote = { workspace = true }
default = [] default = []
fullstack = [] fullstack = []
desktop = [] desktop = []
native = []
mobile = [] mobile = []
web = [] web = []
ssr = [] ssr = []
+1
View File
@@ -31,6 +31,7 @@ define_config_macro!(server_only if any(feature = "ssr", feature = "liveview"));
define_config_macro!(client if any(feature = "desktop", feature = "web", feature = "mobile")); define_config_macro!(client if any(feature = "desktop", feature = "web", feature = "mobile"));
define_config_macro!(web if feature = "web"); define_config_macro!(web if feature = "web");
define_config_macro!(desktop if feature = "desktop"); define_config_macro!(desktop if feature = "desktop");
define_config_macro!(native if feature = "native");
define_config_macro!(mobile if feature = "mobile"); define_config_macro!(mobile if feature = "mobile");
define_config_macro!(fullstack if feature = "fullstack"); define_config_macro!(fullstack if feature = "fullstack");
define_config_macro!(ssr if feature = "ssr"); define_config_macro!(ssr if feature = "ssr");
+1 -1
View File
@@ -105,7 +105,7 @@ web = [
] ]
ssr = ["dep:dioxus-ssr", "dioxus-config-macro/ssr"] ssr = ["dep:dioxus-ssr", "dioxus-config-macro/ssr"]
liveview = ["dep:dioxus-liveview", "dioxus-config-macro/liveview"] liveview = ["dep:dioxus-liveview", "dioxus-config-macro/liveview"]
native = ["dep:dioxus-native"] # todo(jon): decompose the desktop crate such that "webview" is the default and native is opt-in native = ["dep:dioxus-native", "dioxus-config-macro/native"] # todo(jon): decompose the desktop crate such that "webview" is the default and native is opt-in
server = [ server = [
"dep:dioxus-server", "dep:dioxus-server",
"dioxus-fullstack?/server", "dioxus-fullstack?/server",
+4
View File
@@ -112,6 +112,10 @@ pub use dioxus_desktop as desktop;
#[cfg_attr(docsrs, doc(cfg(feature = "mobile")))] #[cfg_attr(docsrs, doc(cfg(feature = "mobile")))]
pub use dioxus_desktop as mobile; pub use dioxus_desktop as mobile;
#[cfg(feature = "native")]
#[cfg_attr(docsrs, doc(cfg(feature = "native")))]
pub use dioxus_native as native;
#[cfg(feature = "liveview")] #[cfg(feature = "liveview")]
#[cfg_attr(docsrs, doc(cfg(feature = "liveview")))] #[cfg_attr(docsrs, doc(cfg(feature = "liveview")))]
pub use dioxus_liveview as liveview; pub use dioxus_liveview as liveview;
+32
View File
@@ -0,0 +1,32 @@
use dioxus_core::LaunchConfig;
use winit::window::WindowAttributes;
/// The configuration for the desktop application.
pub struct Config {
pub(crate) window_attributes: WindowAttributes,
}
impl LaunchConfig for Config {}
impl Default for Config {
fn default() -> Self {
Self {
window_attributes: WindowAttributes::default().with_title(
dioxus_cli_config::app_title().unwrap_or_else(|| "Dioxus App".to_string()),
),
}
}
}
impl Config {
pub fn new() -> Self {
Self::default()
}
/// Set the configuration for the window.
pub fn with_window_attributes(mut self, attrs: WindowAttributes) -> Self {
// We need to do a swap because the window builder only takes itself as muy self
self.window_attributes = attrs;
self
}
}
+13 -5
View File
@@ -10,6 +10,7 @@
//! - `tracing`: Enables tracing support. //! - `tracing`: Enables tracing support.
mod assets; mod assets;
mod config;
mod contexts; mod contexts;
mod dioxus_application; mod dioxus_application;
mod dioxus_renderer; mod dioxus_renderer;
@@ -29,12 +30,15 @@ pub use dioxus_renderer::{DioxusNativeWindowRenderer, Features, Limits};
#[cfg(not(all(target_os = "ios", target_abi = "sim")))] #[cfg(not(all(target_os = "ios", target_abi = "sim")))]
pub use dioxus_renderer::use_wgpu; pub use dioxus_renderer::use_wgpu;
use blitz_shell::{create_default_event_loop, BlitzShellEvent, Config, WindowConfig}; pub use config::Config;
pub use winit::dpi::{LogicalSize, PhysicalSize};
pub use winit::window::WindowAttributes;
use blitz_shell::{create_default_event_loop, BlitzShellEvent, WindowConfig};
use dioxus_core::{ComponentFunction, Element, VirtualDom}; use dioxus_core::{ComponentFunction, Element, VirtualDom};
use link_handler::DioxusNativeNavigationProvider; use link_handler::DioxusNativeNavigationProvider;
use std::any::Any; use std::any::Any;
use std::sync::Arc; use std::sync::Arc;
use winit::window::WindowAttributes;
/// Launch an interactive HTML/CSS renderer driven by the Dioxus virtualdom /// Launch an interactive HTML/CSS renderer driven by the Dioxus virtualdom
pub fn launch(app: fn() -> Element) { pub fn launch(app: fn() -> Element) {
@@ -77,15 +81,19 @@ pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
let mut features = None; let mut features = None;
let mut limits = None; let mut limits = None;
let mut window_attributes = None; let mut window_attributes = None;
let mut _config = None; let mut config = None;
for mut cfg in configs { for mut cfg in configs {
cfg = try_read_config!(cfg, features, Features); cfg = try_read_config!(cfg, features, Features);
cfg = try_read_config!(cfg, limits, Limits); cfg = try_read_config!(cfg, limits, Limits);
cfg = try_read_config!(cfg, window_attributes, WindowAttributes); cfg = try_read_config!(cfg, window_attributes, WindowAttributes);
cfg = try_read_config!(cfg, _config, Config); cfg = try_read_config!(cfg, config, Config);
let _ = cfg; 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::<BlitzShellEvent>(); let event_loop = create_default_event_loop::<BlitzShellEvent>();
// Turn on the runtime and enter it // Turn on the runtime and enter it
@@ -148,7 +156,7 @@ pub fn launch_cfg_with_props<P: Clone + 'static, M: 'static>(
let config = WindowConfig::with_attributes( let config = WindowConfig::with_attributes(
Box::new(doc) as _, Box::new(doc) as _,
renderer.clone(), renderer.clone(),
window_attributes.unwrap_or_default(), config.window_attributes,
); );
// Create application // Create application