Merge branch 'master' into jk/rework-desktop-crate
This commit is contained in:
125 files changed
+5577
-1255
No files matched your search
@@ -11,7 +11,12 @@ keywords = ["dom", "ui", "gui", "react"]
|
||||
|
||||
[dependencies]
|
||||
dioxus-core = { workspace = true, features = ["serialize"] }
|
||||
dioxus-html = { workspace = true, features = ["serialize", "native-bind"] }
|
||||
dioxus-html = { workspace = true, features = [
|
||||
"serialize",
|
||||
"native-bind",
|
||||
"mounted",
|
||||
"eval",
|
||||
] }
|
||||
dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] }
|
||||
dioxus-hot-reload = { workspace = true, optional = true }
|
||||
|
||||
@@ -45,8 +50,12 @@ crossbeam-channel = "0.5.8"
|
||||
tao = { version = "0.24.0", features = ["rwh_05"] }
|
||||
muda = "0.11.3"
|
||||
|
||||
|
||||
[target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies]
|
||||
# This is only for debug mode, and it appears mobile does not support some packages this uses
|
||||
manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", features = [
|
||||
"webp",
|
||||
"html",
|
||||
] }
|
||||
rfd = "0.12"
|
||||
global-hotkey = "0.4.1"
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ pub(crate) fn check_app_exits(app: Component) {
|
||||
|
||||
dioxus_desktop::launch_cfg(
|
||||
app,
|
||||
Config::new().with_window(WindowBuilder::new().with_visible(false)),
|
||||
Config::new().with_window(WindowBuilder::new().with_visible(true)),
|
||||
);
|
||||
|
||||
// Stop deadman's switch
|
||||
@@ -221,7 +221,7 @@ fn app(cx: Scope) -> Element {
|
||||
desktop_context.close();
|
||||
}
|
||||
|
||||
cx.render(rsx! {
|
||||
render! {
|
||||
div {
|
||||
button {
|
||||
id: "button",
|
||||
@@ -229,7 +229,10 @@ fn app(cx: Scope) -> Element {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().is_empty());
|
||||
assert_eq!(event.data.trigger_button(), Some(dioxus_html::input_data::MouseButton::Primary));
|
||||
assert_eq!(
|
||||
event.data.trigger_button(),
|
||||
Some(dioxus_html::input_data::MouseButton::Primary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -238,7 +241,12 @@ fn app(cx: Scope) -> Element {
|
||||
onmousemove: move |event| {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert!(
|
||||
event
|
||||
.data
|
||||
.held_buttons()
|
||||
.contains(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -247,8 +255,16 @@ fn app(cx: Scope) -> Element {
|
||||
onclick: move |event| {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert_eq!(event.data.trigger_button(), Some(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert!(
|
||||
event
|
||||
.data
|
||||
.held_buttons()
|
||||
.contains(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
assert_eq!(
|
||||
event.data.trigger_button(),
|
||||
Some(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -257,9 +273,19 @@ fn app(cx: Scope) -> Element {
|
||||
ondoubleclick: move |event| {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Primary));
|
||||
assert!(event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert_eq!(event.data.trigger_button(), Some(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert!(
|
||||
event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Primary),
|
||||
);
|
||||
assert!(
|
||||
event
|
||||
.data
|
||||
.held_buttons()
|
||||
.contains(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
assert_eq!(
|
||||
event.data.trigger_button(),
|
||||
Some(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -268,8 +294,16 @@ fn app(cx: Scope) -> Element {
|
||||
onmousedown: move |event| {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().contains(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert_eq!(event.data.trigger_button(), Some(dioxus_html::input_data::MouseButton::Secondary));
|
||||
assert!(
|
||||
event
|
||||
.data
|
||||
.held_buttons()
|
||||
.contains(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
assert_eq!(
|
||||
event.data.trigger_button(),
|
||||
Some(dioxus_html::input_data::MouseButton::Secondary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -279,7 +313,10 @@ fn app(cx: Scope) -> Element {
|
||||
println!("{:?}", event.data);
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert!(event.data.held_buttons().is_empty());
|
||||
assert_eq!(event.data.trigger_button(), Some(dioxus_html::input_data::MouseButton::Primary));
|
||||
assert_eq!(
|
||||
event.data.trigger_button(),
|
||||
Some(dioxus_html::input_data::MouseButton::Primary),
|
||||
);
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
}
|
||||
@@ -303,10 +340,9 @@ fn app(cx: Scope) -> Element {
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert_eq!(event.data.key().to_string(), "a");
|
||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||
assert_eq!(event.data.location, 0);
|
||||
assert_eq!(event.data.location(), Location::Standard);
|
||||
assert!(event.data.is_auto_repeating());
|
||||
received_events.modify(|x| *x + 1)
|
||||
|
||||
}
|
||||
}
|
||||
input {
|
||||
@@ -316,7 +352,7 @@ fn app(cx: Scope) -> Element {
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert_eq!(event.data.key().to_string(), "a");
|
||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||
assert_eq!(event.data.location, 0);
|
||||
assert_eq!(event.data.location(), Location::Standard);
|
||||
assert!(!event.data.is_auto_repeating());
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
@@ -328,7 +364,7 @@ fn app(cx: Scope) -> Element {
|
||||
assert!(event.data.modifiers().is_empty());
|
||||
assert_eq!(event.data.key().to_string(), "a");
|
||||
assert_eq!(event.data.code().to_string(), "KeyA");
|
||||
assert_eq!(event.data.location, 0);
|
||||
assert_eq!(event.data.location(), Location::Standard);
|
||||
assert!(!event.data.is_auto_repeating());
|
||||
received_events.modify(|x| *x + 1)
|
||||
}
|
||||
@@ -348,5 +384,5 @@ fn app(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ pub(crate) fn check_app_exits(app: Component) {
|
||||
|
||||
dioxus_desktop::launch_cfg(
|
||||
app,
|
||||
Config::new().with_window(WindowBuilder::new().with_visible(false)),
|
||||
Config::new().with_window(WindowBuilder::new().with_visible(true)),
|
||||
);
|
||||
|
||||
should_panic.store(false, std::sync::atomic::Ordering::SeqCst);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
pub fn copy_assets() {
|
||||
#[cfg(all(
|
||||
debug_assertions,
|
||||
any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)
|
||||
))]
|
||||
{
|
||||
// The CLI will copy assets to the current working directory
|
||||
if std::env::var_os("DIOXUS_ACTIVE").is_some() {
|
||||
return;
|
||||
}
|
||||
use manganis_cli_support::AssetManifest;
|
||||
use manganis_cli_support::AssetManifestExt;
|
||||
use manganis_cli_support::Config;
|
||||
use std::path::PathBuf;
|
||||
let config = Config::current();
|
||||
let asset_location = config.assets_serve_location();
|
||||
let asset_location = PathBuf::from(asset_location);
|
||||
let _ = std::fs::remove_dir_all(&asset_location);
|
||||
|
||||
println!("Finding assets... (Note: if you run a dioxus desktop application with the CLI. This process will be significantly faster.)");
|
||||
let manifest = AssetManifest::load();
|
||||
let has_assets = manifest
|
||||
.packages()
|
||||
.iter()
|
||||
.any(|package| !package.assets().is_empty());
|
||||
|
||||
if has_assets {
|
||||
println!("Copying and optimizing assets...");
|
||||
manifest.copy_static_assets_to(&asset_location).unwrap();
|
||||
println!("Copied assets to {}", asset_location.display());
|
||||
} else {
|
||||
println!("No assets found");
|
||||
}
|
||||
}
|
||||
#[cfg(not(all(
|
||||
debug_assertions,
|
||||
any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)
|
||||
)))]
|
||||
{
|
||||
println!(
|
||||
"Skipping assets in release mode. You compile assets with the dioxus-cli in release mode"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ use dioxus_html::{geometry::euclid::Rect, MountedResult, RenderedElementBacking}
|
||||
|
||||
use crate::{desktop_context::DesktopContext, query::QueryEngine};
|
||||
|
||||
#[derive(Clone)]
|
||||
/// A mounted element passed to onmounted events
|
||||
pub struct DesktopElement {
|
||||
id: ElementId,
|
||||
@@ -17,8 +18,8 @@ impl DesktopElement {
|
||||
}
|
||||
|
||||
impl RenderedElementBacking for DesktopElement {
|
||||
fn get_raw_element(&self) -> dioxus_html::MountedResult<&dyn std::any::Any> {
|
||||
Ok(self)
|
||||
fn as_any(&self) -> &dyn std::any::Any {
|
||||
self
|
||||
}
|
||||
|
||||
fn get_client_rect(
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
//! Convert a serialized event to an event trigger
|
||||
|
||||
use dioxus_html::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::element::DesktopElement;
|
||||
|
||||
#[derive(Deserialize, Serialize, Debug, Clone)]
|
||||
pub struct IpcMessage {
|
||||
method: String,
|
||||
params: serde_json::Value,
|
||||
}
|
||||
|
||||
impl IpcMessage {
|
||||
pub(crate) fn method(&self) -> &str {
|
||||
self.method.as_str()
|
||||
}
|
||||
|
||||
pub(crate) fn params(self) -> serde_json::Value {
|
||||
self.params
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SerializedHtmlEventConverter;
|
||||
|
||||
impl HtmlEventConverter for SerializedHtmlEventConverter {
|
||||
fn convert_animation_data(&self, event: &PlatformEventData) -> AnimationData {
|
||||
event
|
||||
.downcast::<SerializedAnimationData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_clipboard_data(&self, event: &PlatformEventData) -> ClipboardData {
|
||||
event
|
||||
.downcast::<SerializedClipboardData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_composition_data(&self, event: &PlatformEventData) -> CompositionData {
|
||||
event
|
||||
.downcast::<SerializedCompositionData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_drag_data(&self, event: &PlatformEventData) -> DragData {
|
||||
event
|
||||
.downcast::<SerializedDragData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_focus_data(&self, event: &PlatformEventData) -> FocusData {
|
||||
event
|
||||
.downcast::<SerializedFocusData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_form_data(&self, event: &PlatformEventData) -> FormData {
|
||||
event
|
||||
.downcast::<SerializedFormData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_image_data(&self, event: &PlatformEventData) -> ImageData {
|
||||
event
|
||||
.downcast::<SerializedImageData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_keyboard_data(&self, event: &PlatformEventData) -> KeyboardData {
|
||||
event
|
||||
.downcast::<SerializedKeyboardData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_media_data(&self, event: &PlatformEventData) -> MediaData {
|
||||
event
|
||||
.downcast::<SerializedMediaData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_mounted_data(&self, event: &PlatformEventData) -> MountedData {
|
||||
event.downcast::<DesktopElement>().cloned().unwrap().into()
|
||||
}
|
||||
|
||||
fn convert_mouse_data(&self, event: &PlatformEventData) -> MouseData {
|
||||
event
|
||||
.downcast::<SerializedMouseData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_pointer_data(&self, event: &PlatformEventData) -> PointerData {
|
||||
event
|
||||
.downcast::<SerializedPointerData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_scroll_data(&self, event: &PlatformEventData) -> ScrollData {
|
||||
event
|
||||
.downcast::<SerializedScrollData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_selection_data(&self, event: &PlatformEventData) -> SelectionData {
|
||||
event
|
||||
.downcast::<SerializedSelectionData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_toggle_data(&self, event: &PlatformEventData) -> ToggleData {
|
||||
event
|
||||
.downcast::<SerializedToggleData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_touch_data(&self, event: &PlatformEventData) -> TouchData {
|
||||
event
|
||||
.downcast::<SerializedTouchData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_transition_data(&self, event: &PlatformEventData) -> TransitionData {
|
||||
event
|
||||
.downcast::<SerializedTransitionData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
|
||||
fn convert_wheel_data(&self, event: &PlatformEventData) -> WheelData {
|
||||
event
|
||||
.downcast::<SerializedWheelData>()
|
||||
.cloned()
|
||||
.unwrap()
|
||||
.into()
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
mod app;
|
||||
mod assets;
|
||||
mod cfg;
|
||||
mod collect_assets;
|
||||
mod desktop_context;
|
||||
mod edits;
|
||||
mod element;
|
||||
|
||||
@@ -144,6 +144,11 @@ fn module_loader(root_id: &str, headless: bool) -> String {
|
||||
/// - [ ] Linux (deb)
|
||||
/// - [ ] iOS
|
||||
/// - [ ] Android
|
||||
#[allow(unreachable_code)]
|
||||
pub(crate) fn get_asset_root_or_default() -> PathBuf {
|
||||
get_asset_root().unwrap_or_else(|| Path::new(".").to_path_buf())
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn get_asset_root() -> Option<PathBuf> {
|
||||
// If running under cargo, there's no bundle!
|
||||
|
||||
Reference in new issue
Block a user