From 35e289fe28887503ac7d3830e7f9b029346fd118 Mon Sep 17 00:00:00 2001 From: Nico Burns Date: Sat, 17 Jan 2026 00:32:45 +0000 Subject: [PATCH] Fix more examples to work with `dioxus-native` (#5179) * Enable native for hotdog, file-explorer, and bluetooth-scanner examples Signed-off-by: Nico Burns * Fix crash in calculator example Signed-off-by: Nico Burns * 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 --- Cargo.lock | 1 + Cargo.toml | 3 +- .../01-app-demos/bluetooth-scanner/Cargo.toml | 7 +++- examples/01-app-demos/calculator.rs | 15 +++++++-- examples/01-app-demos/calculator_mutable.rs | 19 +++++++---- .../01-app-demos/file-explorer/Cargo.toml | 7 +++- examples/01-app-demos/hotdog/Cargo.toml | 1 + packages/config-macro/Cargo.toml | 1 + packages/config-macro/src/lib.rs | 1 + packages/dioxus/Cargo.toml | 2 +- packages/dioxus/src/lib.rs | 4 +++ packages/native/src/config.rs | 32 +++++++++++++++++++ packages/native/src/lib.rs | 18 ++++++++--- 13 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 packages/native/src/config.rs diff --git a/Cargo.lock b/Cargo.lock index c5b19cef5..5b8181d0a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5875,6 +5875,7 @@ dependencies = [ "wasm-streams", "web-time", "wgpu 26.0.1", + "winit", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f3e89d12a..0fe2aa575 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -461,6 +461,7 @@ ciborium = { workspace = true, optional = true } base64 = { workspace = true, optional = true } http-range = { version = "0.1.5" } wgpu = { workspace = true, optional = true } +winit = { workspace = true, optional = true } ouroboros = { version = "*", optional = true } wasm-splitter = { workspace = true } @@ -516,7 +517,7 @@ tokio = { version = "1.48", features = ["full"] } [features] default = ["desktop"] desktop = ["dioxus/desktop"] -native = ["dioxus/native"] +native = ["dioxus/native", "winit"] liveview = ["dioxus/liveview"] server = ["dioxus/server"] mobile = ["dioxus/mobile"] diff --git a/examples/01-app-demos/bluetooth-scanner/Cargo.toml b/examples/01-app-demos/bluetooth-scanner/Cargo.toml index 5e72efa52..0136afa29 100644 --- a/examples/01-app-demos/bluetooth-scanner/Cargo.toml +++ b/examples/01-app-demos/bluetooth-scanner/Cargo.toml @@ -8,7 +8,12 @@ publish = false [dependencies] tokio = { workspace = true, features = ["full"] } -dioxus = { workspace = true, features = ["desktop"] } +dioxus = { workspace = true } futures-channel = { workspace = true } futures = { workspace = true } btleplug = "0.11.8" + +[features] +default = ["desktop"] +desktop = ["dioxus/desktop"] +native = ["dioxus/native"] diff --git a/examples/01-app-demos/calculator.rs b/examples/01-app-demos/calculator.rs index 5e6df0900..83c469f8c 100644 --- a/examples/01-app-demos/calculator.rs +++ b/examples/01-app-demos/calculator.rs @@ -12,15 +12,24 @@ use dioxus::events::*; use dioxus::html::input_data::keyboard_types::Key; use dioxus::prelude::*; +const TITLE: &str = "Calculator"; const STYLE: Asset = asset!("/examples/assets/calculator.css"); fn main() { - dioxus::LaunchBuilder::desktop() + dioxus::LaunchBuilder::new() .with_cfg(desktop!({ use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; Config::new().with_window( 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)), ) })) @@ -146,7 +155,7 @@ fn calc_val(val: &str) -> f64 { let mut temp_value; let mut fin_index = 0; - if &val[0..1] == "-" { + if val.len() > 1 && &val[0..1] == "-" { temp_value = String::from("-"); fin_index = 1; start_index += 1; diff --git a/examples/01-app-demos/calculator_mutable.rs b/examples/01-app-demos/calculator_mutable.rs index 4102e6ff2..9da91e5c9 100644 --- a/examples/01-app-demos/calculator_mutable.rs +++ b/examples/01-app-demos/calculator_mutable.rs @@ -6,22 +6,29 @@ //! 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. -use dioxus::desktop::tao::dpi::LogicalSize; -use dioxus::desktop::{Config, WindowBuilder}; use dioxus::html::MouseEvent; use dioxus::html::input_data::keyboard_types::Key; use dioxus::prelude::*; fn main() { - dioxus::LaunchBuilder::desktop() - .with_cfg( + dioxus::LaunchBuilder::new() + .with_cfg(desktop! {{ + use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; Config::new().with_window( WindowBuilder::new() .with_title("Calculator Demo") .with_resizable(false) .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); } diff --git a/examples/01-app-demos/file-explorer/Cargo.toml b/examples/01-app-demos/file-explorer/Cargo.toml index 8957e85cb..90ad2c66f 100644 --- a/examples/01-app-demos/file-explorer/Cargo.toml +++ b/examples/01-app-demos/file-explorer/Cargo.toml @@ -7,5 +7,10 @@ publish = false # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -dioxus = { workspace = true, features = ["desktop"] } +dioxus = { workspace = true } open = { workspace = true } + +[features] +default = ["desktop"] +desktop = ["dioxus/desktop"] +native = ["dioxus/native"] diff --git a/examples/01-app-demos/hotdog/Cargo.toml b/examples/01-app-demos/hotdog/Cargo.toml index 7b56b2e0c..537a171ff 100644 --- a/examples/01-app-demos/hotdog/Cargo.toml +++ b/examples/01-app-demos/hotdog/Cargo.toml @@ -17,5 +17,6 @@ anyhow = { workspace = true } default = ["web", "server"] web = ["dioxus/web"] desktop = ["dioxus/desktop"] +native = ["dioxus/native"] mobile = ["dioxus/mobile"] server = ["dioxus/server", "dep:rusqlite"] diff --git a/packages/config-macro/Cargo.toml b/packages/config-macro/Cargo.toml index 6cbb86024..6a80c467c 100644 --- a/packages/config-macro/Cargo.toml +++ b/packages/config-macro/Cargo.toml @@ -20,6 +20,7 @@ quote = { workspace = true } default = [] fullstack = [] desktop = [] +native = [] mobile = [] web = [] ssr = [] diff --git a/packages/config-macro/src/lib.rs b/packages/config-macro/src/lib.rs index 85db30944..c555daea6 100644 --- a/packages/config-macro/src/lib.rs +++ b/packages/config-macro/src/lib.rs @@ -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!(web if feature = "web"); define_config_macro!(desktop if feature = "desktop"); +define_config_macro!(native if feature = "native"); define_config_macro!(mobile if feature = "mobile"); define_config_macro!(fullstack if feature = "fullstack"); define_config_macro!(ssr if feature = "ssr"); diff --git a/packages/dioxus/Cargo.toml b/packages/dioxus/Cargo.toml index 94e605fee..5c10fdcff 100644 --- a/packages/dioxus/Cargo.toml +++ b/packages/dioxus/Cargo.toml @@ -105,7 +105,7 @@ web = [ ] ssr = ["dep:dioxus-ssr", "dioxus-config-macro/ssr"] 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 = [ "dep:dioxus-server", "dioxus-fullstack?/server", diff --git a/packages/dioxus/src/lib.rs b/packages/dioxus/src/lib.rs index ae68a43f1..72b9f1f0e 100644 --- a/packages/dioxus/src/lib.rs +++ b/packages/dioxus/src/lib.rs @@ -112,6 +112,10 @@ pub use dioxus_desktop as desktop; #[cfg_attr(docsrs, doc(cfg(feature = "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_attr(docsrs, doc(cfg(feature = "liveview")))] pub use dioxus_liveview as liveview; diff --git a/packages/native/src/config.rs b/packages/native/src/config.rs new file mode 100644 index 000000000..d71fa79a5 --- /dev/null +++ b/packages/native/src/config.rs @@ -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 + } +} diff --git a/packages/native/src/lib.rs b/packages/native/src/lib.rs index bf977cd0f..63afe1649 100644 --- a/packages/native/src/lib.rs +++ b/packages/native/src/lib.rs @@ -10,6 +10,7 @@ //! - `tracing`: Enables tracing support. mod assets; +mod config; mod contexts; mod dioxus_application; mod dioxus_renderer; @@ -29,12 +30,15 @@ pub use dioxus_renderer::{DioxusNativeWindowRenderer, Features, Limits}; #[cfg(not(all(target_os = "ios", target_abi = "sim")))] 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 link_handler::DioxusNativeNavigationProvider; use std::any::Any; use std::sync::Arc; -use winit::window::WindowAttributes; /// Launch an interactive HTML/CSS renderer driven by the Dioxus virtualdom pub fn launch(app: fn() -> Element) { @@ -77,15 +81,19 @@ pub fn launch_cfg_with_props( let mut features = None; let mut limits = None; let mut window_attributes = None; - let mut _config = None; + let mut config = None; for mut cfg in configs { 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); + 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::(); // Turn on the runtime and enter it @@ -148,7 +156,7 @@ pub fn launch_cfg_with_props( let config = WindowConfig::with_attributes( Box::new(doc) as _, renderer.clone(), - window_attributes.unwrap_or_default(), + config.window_attributes, ); // Create application