mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-01-31 00:35:19 +01:00
feat: add OpenHarmony support
This commit is contained in:
316
Cargo.lock
generated
316
Cargo.lock
generated
@@ -229,6 +229,8 @@ name = "api"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"napi-derive-ohos",
|
||||
"napi-ohos",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
@@ -1055,13 +1057,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo-mobile2"
|
||||
version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f2e0347234eb5a7b47eb66d33dc18560a628f031dffe58c37a7efe44b53e6f9"
|
||||
version = "0.20.4"
|
||||
source = "git+https://github.com/tauri-apps/cargo-mobile2?branch=feat/ohos#fa4c50b5ffacc5caf0729512cdb8bc77b71c4412"
|
||||
dependencies = [
|
||||
"colored",
|
||||
"core-foundation 0.10.0",
|
||||
"deunicode",
|
||||
"dirs 6.0.0",
|
||||
"duct",
|
||||
"dunce",
|
||||
"embed-resource",
|
||||
@@ -1393,6 +1395,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
|
||||
dependencies = [
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.8.0"
|
||||
@@ -1720,8 +1731,18 @@ version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_macro",
|
||||
"darling_core 0.20.10",
|
||||
"darling_macro 0.20.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08440b3dd222c3d0433e63e097463969485f112baff337dfdaca043a0d760570"
|
||||
dependencies = [
|
||||
"darling_core 0.21.2",
|
||||
"darling_macro 0.21.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1738,13 +1759,38 @@ dependencies = [
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_core"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d25b7912bc28a04ab1b7715a68ea03aaa15662b43a1a4b2c480531fd19f8bf7e"
|
||||
dependencies = [
|
||||
"fnv",
|
||||
"ident_case",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"strsim",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.20.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806"
|
||||
dependencies = [
|
||||
"darling_core",
|
||||
"darling_core 0.20.10",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "darling_macro"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce154b9bea7fb0c8e8326e62d00354000c36e79770ff21b8c84e3aa267d9d531"
|
||||
dependencies = [
|
||||
"darling_core 0.21.2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
@@ -1831,7 +1877,7 @@ version = "0.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"darling 0.20.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
@@ -4665,6 +4711,12 @@ version = "2.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fff539e61c5e3dd4d7d283610662f5d672c2aea0f158df78af694f13dbb3287b"
|
||||
|
||||
[[package]]
|
||||
name = "napi-build-ohos"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "959f833e4ea8bec8f92b23b705b5558d42d8e63672c77b9b281b7228c5df6e88"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
version = "3.0.0"
|
||||
@@ -4692,6 +4744,48 @@ dependencies = [
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-backend-ohos"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b27250baa967a15214e57384dd6228c59afbccb15ab8f97207c9758917544bf5"
|
||||
dependencies = [
|
||||
"convert_case 0.8.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"semver",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-ohos"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c844efa85d53b5adc3b326520f3a108c3a737b7534ee10d406f81884e7e71b3c"
|
||||
dependencies = [
|
||||
"convert_case 0.8.0",
|
||||
"ctor 0.4.2",
|
||||
"napi-derive-backend-ohos",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-ohos"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44cd7f1a2b5b17e763d8fcc33f3a9f426c0303a1fcb9b89d7c553308c3a1db97"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"ctor 0.4.2",
|
||||
"napi-build-ohos",
|
||||
"napi-sys-ohos",
|
||||
"nohash-hasher",
|
||||
"rustc-hash",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-sys"
|
||||
version = "3.0.0"
|
||||
@@ -4701,6 +4795,15 @@ dependencies = [
|
||||
"libloading 0.8.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-sys-ohos"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff0b7e156bf62a778295ba4f130cde6c2fe07936ebf9448fab6ca0f7c7040682"
|
||||
dependencies = [
|
||||
"libloading 0.8.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.12"
|
||||
@@ -5281,6 +5384,144 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-arkui-binding"
|
||||
version = "0.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "731d879cf95234bbd12e525bdce7da6475a6786a86dd2362fac0f3cfca760373"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"napi-ohos",
|
||||
"napi-sys-ohos",
|
||||
"ohos-arkui-sys",
|
||||
"ohos-xcomponent-binding",
|
||||
"ohos-xcomponent-sys",
|
||||
"ohos_enum_macro 0.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-arkui-sys"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a19176486bbe46d33830aca4213b07bb46c745200118e57106639db4962e1c3"
|
||||
dependencies = [
|
||||
"napi-sys-ohos",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-display-binding"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "157fe09232fd0af55ed9207d30b47a5f5ff7f84a0673a3b47f65acb7bbc9b8a9"
|
||||
dependencies = [
|
||||
"ohos-display-sys",
|
||||
"ohos_enum_macro 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-display-soloist-binding"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b26e7a334db10af3d3b71cc0cddfd923030421e719031d8d75ca8ffb431614dd"
|
||||
dependencies = [
|
||||
"ohos-display-soloist-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-display-soloist-sys"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b6f9ced0cbe82574a06d95cf5ffa35eee07b13e0631c8abd421feb03aa16b0a"
|
||||
|
||||
[[package]]
|
||||
name = "ohos-display-sys"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe9e1bba4d94159d0a65f1b4e748c148d4bce7930912c424522693f1837dad77"
|
||||
|
||||
[[package]]
|
||||
name = "ohos-ime-binding"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bed52a087eacd3ea07de5258ca7574276431b17d4c0464ed7f7f57a5fa99bd48"
|
||||
dependencies = [
|
||||
"ohos-input-method-sys",
|
||||
"ohos_enum_macro 0.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-input-method-sys"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e95bb83d997b0d7f1d04e9b2ba8874a1bd8e89dc5e88d0852a4390f8b44b0703"
|
||||
|
||||
[[package]]
|
||||
name = "ohos-web-binding"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "390cbdbe97bddcb5dcd46d52654799525ef42962cf6f360c57b4bb72597ebd61"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"ohos-web-sys",
|
||||
"ohos_enum_macro 0.0.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-web-sys"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa646f3223c2bc90a400641c3a5cda4b350387ffda1a904b8bfb3db92b81ecbc"
|
||||
|
||||
[[package]]
|
||||
name = "ohos-xcomponent-binding"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f99c43b17408bb43ae53832a7b929dc6a359685f914624e82fec0a52e9d6ac"
|
||||
dependencies = [
|
||||
"napi-derive-ohos",
|
||||
"napi-ohos",
|
||||
"napi-sys-ohos",
|
||||
"ohos-display-binding",
|
||||
"ohos-xcomponent-sys",
|
||||
"ohos_enum_macro 0.0.2",
|
||||
"raw-window-handle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos-xcomponent-sys"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5613209329ff61bc8695871ef985d57fc59ea4d55263e2c2395d8810d063575e"
|
||||
dependencies = [
|
||||
"ohos-arkui-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos_enum_macro"
|
||||
version = "0.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0ee769776099c824423d1686e21b5fd13b464d374d60f7cc25c48c1c836ede1"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ohos_enum_macro"
|
||||
version = "0.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4bacd60b52be93024c446f27645d795ab71eb2243bb4c5d87b6238a35341fbd"
|
||||
dependencies = [
|
||||
"convert_case 0.6.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oid-registry"
|
||||
version = "0.6.1"
|
||||
@@ -5312,6 +5553,35 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openharmony-ability"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ef188801ee7d2356067f4d4d54eb1d1eaab58e9acce9a8f9cc9695f8327bc52"
|
||||
dependencies = [
|
||||
"http 1.3.1",
|
||||
"napi-derive-ohos",
|
||||
"napi-ohos",
|
||||
"ohos-arkui-binding",
|
||||
"ohos-display-binding",
|
||||
"ohos-display-soloist-binding",
|
||||
"ohos-ime-binding",
|
||||
"ohos-web-binding",
|
||||
"ohos-xcomponent-binding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openharmony-ability-derive"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ba6d923f6fc667cb9db25ff570deece3cdffb3fc4b58b8bc04f0419ca5de1d3"
|
||||
dependencies = [
|
||||
"darling 0.21.2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.72"
|
||||
@@ -7689,7 +7959,7 @@ version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"darling 0.20.10",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
@@ -8411,11 +8681,11 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tao"
|
||||
version = "0.34.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b65dc99ae111a3255027d1eca24a3833bb3267d4556a6defddb455f3ca4f5b6c"
|
||||
version = "0.34.2"
|
||||
source = "git+https://github.com/richerfu/tao?branch=feat-ohos-webview#efdfe5d002879fa51c0d6508cc2c295c1f3b31b6"
|
||||
dependencies = [
|
||||
"bitflags 2.7.0",
|
||||
"block2 0.6.0",
|
||||
"core-foundation 0.10.0",
|
||||
"core-graphics",
|
||||
"crossbeam-channel",
|
||||
@@ -8436,10 +8706,12 @@ dependencies = [
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation 0.3.0",
|
||||
"once_cell",
|
||||
"openharmony-ability",
|
||||
"openharmony-ability-derive",
|
||||
"parking_lot",
|
||||
"raw-window-handle",
|
||||
"scopeguard",
|
||||
"tao-macros",
|
||||
"tao-macros 0.1.3 (git+https://github.com/richerfu/tao?branch=feat-ohos-webview)",
|
||||
"unicode-segmentation",
|
||||
"url",
|
||||
"windows 0.61.1",
|
||||
@@ -8459,6 +8731,16 @@ dependencies = [
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tao-macros"
|
||||
version = "0.1.3"
|
||||
source = "git+https://github.com/richerfu/tao?branch=feat-ohos-webview#efdfe5d002879fa51c0d6508cc2c295c1f3b31b6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.95",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
@@ -8511,6 +8793,8 @@ dependencies = [
|
||||
"objc2-foundation 0.3.0",
|
||||
"objc2-ui-kit",
|
||||
"objc2-web-kit",
|
||||
"openharmony-ability",
|
||||
"openharmony-ability-derive",
|
||||
"percent-encoding",
|
||||
"plist",
|
||||
"proptest",
|
||||
@@ -8859,6 +9143,7 @@ dependencies = [
|
||||
"objc2 0.6.0",
|
||||
"objc2-ui-kit",
|
||||
"objc2-web-kit",
|
||||
"openharmony-ability",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -10944,8 +11229,7 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||
[[package]]
|
||||
name = "wry"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5698e50a589268aec06d2219f48b143222f7b5ad9aa690118b8dce0a8dcac574"
|
||||
source = "git+https://github.com/richerfu/wry#d5294c487d9c1080aa45473e6b0a4cbfed647612"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"block2 0.6.0",
|
||||
@@ -10970,11 +11254,13 @@ dependencies = [
|
||||
"objc2-ui-kit",
|
||||
"objc2-web-kit",
|
||||
"once_cell",
|
||||
"openharmony-ability",
|
||||
"openharmony-ability-derive",
|
||||
"percent-encoding",
|
||||
"raw-window-handle",
|
||||
"sha2",
|
||||
"soup3",
|
||||
"tao-macros",
|
||||
"tao-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"thiserror 2.0.12",
|
||||
"tracing",
|
||||
"url",
|
||||
|
||||
@@ -71,3 +71,6 @@ opt-level = "s"
|
||||
schemars_derive = { git = 'https://github.com/tauri-apps/schemars.git', branch = 'feat/preserve-description-newlines' }
|
||||
tauri = { path = "./crates/tauri" }
|
||||
tauri-plugin = { path = "./crates/tauri-plugin" }
|
||||
cargo-mobile2 = { git = "https://github.com/tauri-apps/cargo-mobile2", branch = "feat/ohos" }
|
||||
wry = { git = "https://github.com/richerfu/wry" }
|
||||
tao = { git = "https://github.com/richerfu/tao", branch = "feat-ohos-webview" }
|
||||
|
||||
@@ -462,8 +462,9 @@ pub fn try_build(attributes: Attributes) -> Result<()> {
|
||||
|
||||
println!("cargo:rerun-if-env-changed=TAURI_CONFIG");
|
||||
|
||||
let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
||||
let mobile = target_os == "ios" || target_os == "android" || target_env == "ohos";
|
||||
cfg_alias("desktop", !mobile);
|
||||
cfg_alias("mobile", mobile);
|
||||
|
||||
|
||||
@@ -141,13 +141,16 @@ pub fn copy_dir(from: &Path, to: &Path) -> crate::Result<()> {
|
||||
///
|
||||
/// Expects a HashMap of PathBuf entries, representing destination and source paths,
|
||||
/// and also a path of a directory. The files will be stored with respect to this directory.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn copy_custom_files(
|
||||
files_map: &std::collections::HashMap<std::path::PathBuf, std::path::PathBuf>,
|
||||
data_dir: &Path,
|
||||
|
||||
@@ -1578,6 +1578,13 @@
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "OpenHarmony.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"openHarmony"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -52,7 +52,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -65,7 +65,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -66,7 +66,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -31,7 +31,7 @@ mod plugin;
|
||||
mod remove;
|
||||
mod signer;
|
||||
|
||||
use clap::{ArgAction, CommandFactory, FromArgMatches, Parser, Subcommand, ValueEnum};
|
||||
use clap::{ArgAction, CommandFactory, FromArgMatches, Parser, Subcommand};
|
||||
use env_logger::fmt::style::{AnsiColor, Style};
|
||||
use env_logger::Builder;
|
||||
use log::Level;
|
||||
@@ -40,7 +40,6 @@ use std::io::{BufReader, Write};
|
||||
use std::process::{exit, Command, ExitStatus, Output, Stdio};
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
fmt::Display,
|
||||
fs::read_to_string,
|
||||
io::BufRead,
|
||||
path::PathBuf,
|
||||
@@ -86,29 +85,6 @@ impl FromStr for ConfigValue {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
|
||||
pub enum RunMode {
|
||||
Desktop,
|
||||
#[cfg(target_os = "macos")]
|
||||
Ios,
|
||||
Android,
|
||||
}
|
||||
|
||||
impl Display for RunMode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match self {
|
||||
Self::Desktop => "desktop",
|
||||
#[cfg(target_os = "macos")]
|
||||
Self::Ios => "iOS",
|
||||
Self::Android => "android",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct VersionMetadata {
|
||||
tauri: String,
|
||||
@@ -151,6 +127,8 @@ enum Commands {
|
||||
Build(build::Options),
|
||||
Bundle(bundle::Options),
|
||||
Android(mobile::android::Cli),
|
||||
#[clap(name("ohos"), alias("oh"), alias("open-harmony"), alias("openharmony"))]
|
||||
OpenHarmony(mobile::open_harmony::Cli),
|
||||
#[cfg(target_os = "macos")]
|
||||
Ios(mobile::ios::Cli),
|
||||
/// Migrate from v1 to v2
|
||||
@@ -232,7 +210,7 @@ where
|
||||
.ok()
|
||||
.and_then(|v| v.parse().ok())
|
||||
.unwrap_or(cli.verbose);
|
||||
// set the verbosity level so subsequent CLI calls (xcode-script, android-studio-script) refer to it
|
||||
// set the verbosity level so subsequent CLI calls (xcode-script, android-studio-script, dev-eco-studio-script) refer to it
|
||||
std::env::set_var("TAURI_CLI_VERBOSITY", verbosity_number.to_string());
|
||||
|
||||
let mut builder = Builder::from_default_env();
|
||||
@@ -297,6 +275,7 @@ where
|
||||
Commands::Permission(options) => acl::permission::command(options)?,
|
||||
Commands::Capability(options) => acl::capability::command(options)?,
|
||||
Commands::Android(c) => mobile::android::command(c, cli.verbose)?,
|
||||
Commands::OpenHarmony(c) => mobile::open_harmony::command(c, cli.verbose)?,
|
||||
#[cfg(target_os = "macos")]
|
||||
Commands::Ios(c) => mobile::ios::command(c, cli.verbose)?,
|
||||
Commands::Migrate => migrate::command()?,
|
||||
|
||||
@@ -54,7 +54,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -53,7 +53,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -69,7 +69,7 @@ pub struct InitOptions {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -168,6 +168,12 @@ pub fn exec(
|
||||
)?;
|
||||
app
|
||||
}
|
||||
Target::OpenHarmony => {
|
||||
let (config, _metadata) =
|
||||
super::open_harmony::get_config(&app, tauri_config_, None, &Default::default());
|
||||
super::open_harmony::project::gen(&app, &config, (handlebars, map))?;
|
||||
app
|
||||
}
|
||||
};
|
||||
|
||||
Report::victory(
|
||||
|
||||
@@ -65,7 +65,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -60,7 +60,7 @@ pub struct Options {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -82,7 +82,7 @@ pub struct InitOptions {
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json and tauri.ios.conf.json)
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
|
||||
@@ -51,6 +51,7 @@ pub mod android;
|
||||
mod init;
|
||||
#[cfg(target_os = "macos")]
|
||||
pub mod ios;
|
||||
pub mod open_harmony;
|
||||
|
||||
const MIN_DEVICE_MATCH_SCORE: isize = 0;
|
||||
|
||||
@@ -99,6 +100,7 @@ pub enum Target {
|
||||
Android,
|
||||
#[cfg(target_os = "macos")]
|
||||
Ios,
|
||||
OpenHarmony,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
@@ -107,6 +109,7 @@ impl Target {
|
||||
Self::Android => "Android Studio",
|
||||
#[cfg(target_os = "macos")]
|
||||
Self::Ios => "Xcode",
|
||||
Self::OpenHarmony => "Dev-Eco Studio",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +118,7 @@ impl Target {
|
||||
Self::Android => "android",
|
||||
#[cfg(target_os = "macos")]
|
||||
Self::Ios => "ios",
|
||||
Self::OpenHarmony => "open-harmony",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +127,7 @@ impl Target {
|
||||
Self::Android => "android-studio-script",
|
||||
#[cfg(target_os = "macos")]
|
||||
Self::Ios => "xcode-script",
|
||||
Self::OpenHarmony => "dev-eco-studio-script",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,6 +136,7 @@ impl Target {
|
||||
Self::Android => tauri_utils::platform::Target::Android,
|
||||
#[cfg(target_os = "macos")]
|
||||
Self::Ios => tauri_utils::platform::Target::Ios,
|
||||
Self::OpenHarmony => tauri_utils::platform::Target::OpenHarmony,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -437,6 +443,7 @@ pub fn get_app(target: Target, config: &TauriConfig, interface: &AppInterface) -
|
||||
Target::Android => config.identifier.replace('-', "_"),
|
||||
#[cfg(target_os = "macos")]
|
||||
Target::Ios => config.identifier.replace('_', "-"),
|
||||
Target::OpenHarmony => config.identifier.replace('-', "_"),
|
||||
};
|
||||
|
||||
if identifier.is_empty() {
|
||||
@@ -526,6 +533,16 @@ fn ensure_init(
|
||||
.push("you have modified your [lib.name] or [package.name] in the Cargo.toml file");
|
||||
}
|
||||
}
|
||||
Target::OpenHarmony => {
|
||||
let app_json = json5::from_str::<open_harmony::AppConfig>(
|
||||
&read_to_string(project_dir.join("AppScope").join("app.json5"))
|
||||
.context("missing app.json5 file in the OpenHarmony project directory")?,
|
||||
)?;
|
||||
if app_json.app.bundle_name != tauri_config_.identifier.replace('-', "_") {
|
||||
project_outdated_reasons
|
||||
.push("you have modified your \"identifier\" in the Tauri configuration");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !project_outdated_reasons.is_empty() {
|
||||
|
||||
258
crates/tauri-cli/src/mobile/open_harmony/build.rs
Normal file
258
crates/tauri-cli/src/mobile/open_harmony/build.rs
Normal file
@@ -0,0 +1,258 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::{
|
||||
delete_codegen_vars, ensure_init, env, get_app, get_config, inject_resources, log_finished,
|
||||
open_and_wait, MobileTarget, OptionsHandle,
|
||||
};
|
||||
use crate::{
|
||||
build::Options as BuildOptions,
|
||||
helpers::{
|
||||
app_paths::tauri_dir,
|
||||
config::{get as get_tauri_config, ConfigHandle},
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, Interface, Options as InterfaceOptions},
|
||||
mobile::{write_options, CliOptions},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
use clap::{ArgAction, Parser};
|
||||
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{
|
||||
open_harmony::{config::Config as OpenHarmonyConfig, env::Env, hap, target::Target},
|
||||
opts::{NoiseLevel, Profile},
|
||||
target::TargetTrait,
|
||||
};
|
||||
|
||||
use std::env::set_current_dir;
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[clap(
|
||||
about = "Build your app in release mode for OpenHarmony and generate HAPs",
|
||||
long_about = "Build your app in release mode for OpenHarmony and generate HAPs. It makes use of the `build.frontendDist` property from your `tauri.conf.json` file. It also runs your `build.beforeBuildCommand` which usually builds your frontend into `build.frontendDist`."
|
||||
)]
|
||||
pub struct Options {
|
||||
/// Builds with the debug flag
|
||||
#[clap(short, long)]
|
||||
pub debug: bool,
|
||||
/// Which targets to build (all by default).
|
||||
#[clap(
|
||||
short,
|
||||
long = "target",
|
||||
action = ArgAction::Append,
|
||||
num_args(0..),
|
||||
value_parser(clap::builder::PossibleValuesParser::new(Target::name_list()))
|
||||
)]
|
||||
pub targets: Option<Vec<String>>,
|
||||
/// List of cargo features to activate
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..))]
|
||||
pub features: Option<Vec<String>>,
|
||||
/// JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Whether to split the HAPs per ABIs.
|
||||
#[clap(long)]
|
||||
pub split_per_abi: bool,
|
||||
/// Open DevEco Studio
|
||||
#[clap(short, long)]
|
||||
pub open: bool,
|
||||
/// Skip prompting for values
|
||||
#[clap(long, env = "CI")]
|
||||
pub ci: bool,
|
||||
/// Command line arguments passed to the runner.
|
||||
/// Use `--` to explicitly mark the start of the arguments.
|
||||
/// e.g. `tauri ohos build -- [runnerArgs]`.
|
||||
#[clap(last(true))]
|
||||
pub args: Vec<String>,
|
||||
/// Do not error out if a version mismatch is detected on a Tauri package.
|
||||
///
|
||||
/// Only use this when you are sure the mismatch is incorrectly detected as version mismatched Tauri packages can lead to unknown behavior.
|
||||
#[clap(long)]
|
||||
pub ignore_version_mismatches: bool,
|
||||
}
|
||||
|
||||
impl From<Options> for BuildOptions {
|
||||
fn from(options: Options) -> Self {
|
||||
Self {
|
||||
runner: None,
|
||||
debug: options.debug,
|
||||
target: None,
|
||||
features: options.features,
|
||||
bundles: None,
|
||||
no_bundle: false,
|
||||
config: options.config,
|
||||
args: options.args,
|
||||
ci: options.ci,
|
||||
skip_stapling: false,
|
||||
ignore_version_mismatches: options.ignore_version_mismatches,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
crate::helpers::app_paths::resolve();
|
||||
|
||||
delete_codegen_vars();
|
||||
|
||||
let mut build_options: BuildOptions = options.clone().into();
|
||||
|
||||
let first_target = Target::all()
|
||||
.get(
|
||||
options
|
||||
.targets
|
||||
.as_ref()
|
||||
.and_then(|l| l.first().map(|t| t.as_str()))
|
||||
.unwrap_or(Target::DEFAULT_KEY),
|
||||
)
|
||||
.unwrap();
|
||||
build_options.target = Some(first_target.triple.into());
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::OpenHarmony,
|
||||
&options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
let (interface, config, metadata) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
|
||||
let interface = AppInterface::new(tauri_config_, build_options.target.clone())?;
|
||||
interface.build_options(&mut Vec::new(), &mut build_options.features, true);
|
||||
|
||||
let app = get_app(MobileTarget::OpenHarmony, tauri_config_, &interface);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
tauri_config_,
|
||||
build_options.features.as_ref(),
|
||||
&Default::default(),
|
||||
);
|
||||
(interface, config, metadata)
|
||||
};
|
||||
|
||||
let profile = if options.debug {
|
||||
Profile::Debug
|
||||
} else {
|
||||
Profile::Release
|
||||
};
|
||||
|
||||
let tauri_path = tauri_dir();
|
||||
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
|
||||
|
||||
ensure_init(
|
||||
&tauri_config,
|
||||
config.app(),
|
||||
config.project_dir(),
|
||||
MobileTarget::OpenHarmony,
|
||||
)?;
|
||||
|
||||
let mut env = env()?;
|
||||
|
||||
crate::build::setup(&interface, &mut build_options, tauri_config.clone(), true)?;
|
||||
|
||||
// run an initial build to initialize plugins
|
||||
first_target.build(&config, &metadata, &env, noise_level, true, profile)?;
|
||||
|
||||
let open = options.open;
|
||||
let _handle = run_build(
|
||||
interface,
|
||||
options,
|
||||
build_options,
|
||||
tauri_config,
|
||||
profile,
|
||||
&config,
|
||||
&mut env,
|
||||
noise_level,
|
||||
)?;
|
||||
|
||||
if open {
|
||||
open_and_wait(&config, &env);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn run_build(
|
||||
interface: AppInterface,
|
||||
options: Options,
|
||||
build_options: BuildOptions,
|
||||
tauri_config: ConfigHandle,
|
||||
profile: Profile,
|
||||
config: &OpenHarmonyConfig,
|
||||
env: &mut Env,
|
||||
noise_level: NoiseLevel,
|
||||
) -> Result<OptionsHandle> {
|
||||
let interface_options = InterfaceOptions {
|
||||
debug: build_options.debug,
|
||||
target: build_options.target.clone(),
|
||||
args: build_options.args.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("ohos"), "OpenHarmony")?;
|
||||
|
||||
let cli_options = CliOptions {
|
||||
dev: false,
|
||||
features: build_options.features.clone(),
|
||||
args: build_options.args.clone(),
|
||||
noise_level,
|
||||
vars: Default::default(),
|
||||
config: build_options.config,
|
||||
target_device: None,
|
||||
};
|
||||
let handle = write_options(tauri_config.lock().unwrap().as_ref().unwrap(), cli_options)?;
|
||||
|
||||
inject_resources(config, tauri_config.lock().unwrap().as_ref().unwrap())?;
|
||||
|
||||
let hap_outputs = hap::build(
|
||||
config,
|
||||
env,
|
||||
noise_level,
|
||||
profile,
|
||||
get_targets_or_all(options.targets.clone().unwrap_or_default())?,
|
||||
options.split_per_abi,
|
||||
)?;
|
||||
|
||||
log_finished(hap_outputs, "HAP");
|
||||
|
||||
Ok(handle)
|
||||
}
|
||||
|
||||
fn get_targets_or_all<'a>(targets: Vec<String>) -> Result<Vec<&'a Target<'a>>> {
|
||||
if targets.is_empty() {
|
||||
Ok(Target::all().iter().map(|t| t.1).collect())
|
||||
} else {
|
||||
let mut outs = Vec::new();
|
||||
|
||||
let possible_targets = Target::all()
|
||||
.keys()
|
||||
.map(|key| key.to_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(",");
|
||||
|
||||
for t in targets {
|
||||
let target = Target::for_name(&t).ok_or_else(|| {
|
||||
anyhow::anyhow!(
|
||||
"Target {} is invalid; the possible targets are {}",
|
||||
t,
|
||||
possible_targets
|
||||
)
|
||||
})?;
|
||||
outs.push(target);
|
||||
}
|
||||
Ok(outs)
|
||||
}
|
||||
}
|
||||
335
crates/tauri-cli/src/mobile/open_harmony/dev.rs
Normal file
335
crates/tauri-cli/src/mobile/open_harmony/dev.rs
Normal file
@@ -0,0 +1,335 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::{
|
||||
delete_codegen_vars, device_prompt, ensure_init, env, get_app, get_config, inject_resources,
|
||||
open_and_wait, MobileTarget,
|
||||
};
|
||||
use crate::{
|
||||
dev::Options as DevOptions,
|
||||
helpers::{
|
||||
app_paths::tauri_dir,
|
||||
config::{get as get_tauri_config, ConfigHandle},
|
||||
flock,
|
||||
},
|
||||
interface::{AppInterface, Interface, MobileOptions, Options as InterfaceOptions},
|
||||
mobile::{
|
||||
use_network_address_for_dev_url, write_options, CliOptions, DevChild, DevHost, DevProcess,
|
||||
TargetDevice,
|
||||
},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
use clap::{ArgAction, Parser};
|
||||
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{
|
||||
open_harmony::{
|
||||
config::{Config as OpenHarmonyConfig, Metadata as OpenHarmonyMetadata},
|
||||
device::Device,
|
||||
env::Env,
|
||||
target::Target,
|
||||
},
|
||||
opts::{NoiseLevel, Profile},
|
||||
target::TargetTrait,
|
||||
};
|
||||
|
||||
use std::{env::set_current_dir, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, Parser)]
|
||||
#[clap(
|
||||
about = "Run your app in development mode on OpenHarmony",
|
||||
long_about = "Run your app in development mode on OpenHarmony with hot-reloading for the Rust code. It makes use of the `build.devUrl` property from your `tauri.conf.json` file. It also runs your `build.beforeDevCommand` which usually starts your frontend devServer."
|
||||
)]
|
||||
pub struct Options {
|
||||
/// List of cargo features to activate
|
||||
#[clap(short, long, action = ArgAction::Append, num_args(0..))]
|
||||
pub features: Option<Vec<String>>,
|
||||
/// Exit on panic
|
||||
#[clap(short, long)]
|
||||
exit_on_panic: bool,
|
||||
/// JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
/// Run the code in release mode
|
||||
#[clap(long = "release")]
|
||||
pub release_mode: bool,
|
||||
/// Skip waiting for the frontend dev server to start before building the tauri application.
|
||||
#[clap(long, env = "TAURI_CLI_NO_DEV_SERVER_WAIT")]
|
||||
pub no_dev_server_wait: bool,
|
||||
/// Disable the file watcher
|
||||
#[clap(long)]
|
||||
pub no_watch: bool,
|
||||
/// Additional paths to watch for changes.
|
||||
#[clap(long)]
|
||||
pub additional_watch_folders: Vec<PathBuf>,
|
||||
/// Open DevEco Studio instead of trying to run on a connected device
|
||||
#[clap(short, long)]
|
||||
pub open: bool,
|
||||
/// Runs on the given device name
|
||||
pub device: Option<String>,
|
||||
/// Force prompting for an IP to use to connect to the dev server on mobile.
|
||||
#[clap(long)]
|
||||
pub force_ip_prompt: bool,
|
||||
/// Use the public network address for the development server.
|
||||
/// If an actual address it provided, it is used instead of prompting to pick one.
|
||||
///
|
||||
/// On Windows we use the public network address by default.
|
||||
///
|
||||
/// This option is particularly useful along the `--open` flag when you intend on running on a physical device.
|
||||
///
|
||||
/// This replaces the devUrl configuration value to match the public network address host,
|
||||
/// it is your responsibility to set up your development server to listen on this address
|
||||
/// by using 0.0.0.0 as host for instance.
|
||||
///
|
||||
/// When this is set or when running on an iOS device the CLI sets the `TAURI_DEV_HOST`
|
||||
/// environment variable so you can check this on your framework's configuration to expose the development server
|
||||
/// on the public network address.
|
||||
#[clap(long, default_value_t, default_missing_value(""), num_args(0..=1))]
|
||||
pub host: DevHost,
|
||||
/// Disable the built-in dev server for static files.
|
||||
#[clap(long)]
|
||||
pub no_dev_server: bool,
|
||||
/// Specify port for the built-in dev server for static files. Defaults to 1430.
|
||||
#[clap(long, env = "TAURI_CLI_PORT")]
|
||||
pub port: Option<u16>,
|
||||
/// Command line arguments passed to the runner.
|
||||
/// Use `--` to explicitly mark the start of the arguments.
|
||||
/// e.g. `tauri ohos dev -- [runnerArgs]`.
|
||||
#[clap(last(true))]
|
||||
pub args: Vec<String>,
|
||||
/// Path to the certificate file used by your dev server. Required for mobile dev when using HTTPS.
|
||||
#[clap(long, env = "TAURI_DEV_ROOT_CERTIFICATE_PATH")]
|
||||
pub root_certificate_path: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl From<Options> for DevOptions {
|
||||
fn from(options: Options) -> Self {
|
||||
Self {
|
||||
runner: None,
|
||||
target: None,
|
||||
features: options.features,
|
||||
exit_on_panic: options.exit_on_panic,
|
||||
config: options.config,
|
||||
args: options.args,
|
||||
no_watch: options.no_watch,
|
||||
additional_watch_folders: options.additional_watch_folders,
|
||||
no_dev_server_wait: options.no_dev_server_wait,
|
||||
no_dev_server: options.no_dev_server,
|
||||
port: options.port,
|
||||
release_mode: options.release_mode,
|
||||
host: options.host.0.unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
crate::helpers::app_paths::resolve();
|
||||
|
||||
let result = run_command(options, noise_level);
|
||||
if result.is_err() {
|
||||
crate::dev::kill_before_dev_process();
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
|
||||
delete_codegen_vars();
|
||||
// setup env additions before calling env()
|
||||
if let Some(root_certificate_path) = &options.root_certificate_path {
|
||||
std::env::set_var(
|
||||
"TAURI_DEV_ROOT_CERTIFICATE",
|
||||
std::fs::read_to_string(root_certificate_path).context("failed to read certificate file")?,
|
||||
);
|
||||
}
|
||||
|
||||
let tauri_config = get_tauri_config(
|
||||
tauri_utils::platform::Target::OpenHarmony,
|
||||
&options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
|
||||
let env = env()?;
|
||||
let device = if options.open {
|
||||
None
|
||||
} else {
|
||||
match device_prompt(&env, options.device.as_deref()) {
|
||||
Ok(d) => Some(d),
|
||||
Err(e) => {
|
||||
log::error!("{e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mut dev_options: DevOptions = options.clone().into();
|
||||
let target_triple = device
|
||||
.as_ref()
|
||||
.map(|d| d.target().triple.to_string())
|
||||
.unwrap_or_else(|| Target::all().values().next().unwrap().triple.into());
|
||||
dev_options.target = Some(target_triple);
|
||||
|
||||
let (interface, config, metadata) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
|
||||
let interface = AppInterface::new(tauri_config_, dev_options.target.clone())?;
|
||||
|
||||
let app = get_app(MobileTarget::OpenHarmony, tauri_config_, &interface);
|
||||
let (config, metadata) = get_config(
|
||||
&app,
|
||||
tauri_config_,
|
||||
dev_options.features.as_ref(),
|
||||
&Default::default(),
|
||||
);
|
||||
(interface, config, metadata)
|
||||
};
|
||||
|
||||
let tauri_path = tauri_dir();
|
||||
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;
|
||||
|
||||
ensure_init(
|
||||
&tauri_config,
|
||||
config.app(),
|
||||
config.project_dir(),
|
||||
MobileTarget::OpenHarmony,
|
||||
)?;
|
||||
run_dev(
|
||||
interface,
|
||||
options,
|
||||
dev_options,
|
||||
tauri_config,
|
||||
device,
|
||||
env,
|
||||
&config,
|
||||
&metadata,
|
||||
noise_level,
|
||||
)
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn run_dev(
|
||||
mut interface: AppInterface,
|
||||
options: Options,
|
||||
mut dev_options: DevOptions,
|
||||
tauri_config: ConfigHandle,
|
||||
device: Option<Device>,
|
||||
env: Env,
|
||||
config: &OpenHarmonyConfig,
|
||||
metadata: &OpenHarmonyMetadata,
|
||||
noise_level: NoiseLevel,
|
||||
) -> Result<()> {
|
||||
// when running on an actual device we must use the network IP
|
||||
if options.host.0.is_some()
|
||||
|| device
|
||||
.as_ref()
|
||||
.map(|device| !device.model().starts_with("emulator"))
|
||||
.unwrap_or(false)
|
||||
{
|
||||
use_network_address_for_dev_url(&tauri_config, &mut dev_options, options.force_ip_prompt)?;
|
||||
}
|
||||
|
||||
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;
|
||||
|
||||
let interface_options = InterfaceOptions {
|
||||
debug: !dev_options.release_mode,
|
||||
target: dev_options.target.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let app_settings = interface.app_settings();
|
||||
let out_dir = app_settings.out_dir(&interface_options)?;
|
||||
let _lock = flock::open_rw(out_dir.join("lock").with_extension("ohos"), "OpenHarmony")?;
|
||||
|
||||
// run an initial build to initialize plugins
|
||||
let target_triple = dev_options.target.as_ref().unwrap();
|
||||
let target = Target::all()
|
||||
.values()
|
||||
.find(|t| t.triple == target_triple)
|
||||
.unwrap_or_else(|| Target::all().values().next().unwrap());
|
||||
target.build(
|
||||
config,
|
||||
metadata,
|
||||
&env,
|
||||
noise_level,
|
||||
true,
|
||||
if options.release_mode {
|
||||
Profile::Release
|
||||
} else {
|
||||
Profile::Debug
|
||||
},
|
||||
)?;
|
||||
|
||||
let open = options.open;
|
||||
interface.mobile_dev(
|
||||
MobileOptions {
|
||||
debug: !options.release_mode,
|
||||
features: options.features,
|
||||
args: options.args,
|
||||
config: dev_options.config.clone(),
|
||||
no_watch: options.no_watch,
|
||||
additional_watch_folders: options.additional_watch_folders,
|
||||
},
|
||||
|options| {
|
||||
let cli_options = CliOptions {
|
||||
dev: true,
|
||||
features: options.features.clone(),
|
||||
args: options.args.clone(),
|
||||
noise_level,
|
||||
vars: Default::default(),
|
||||
config: dev_options.config.clone(),
|
||||
target_device: device.as_ref().map(|d| TargetDevice {
|
||||
id: d.id().to_string(),
|
||||
name: d.name().to_string(),
|
||||
}),
|
||||
};
|
||||
|
||||
let _handle = write_options(tauri_config.lock().unwrap().as_ref().unwrap(), cli_options)?;
|
||||
|
||||
inject_resources(config, tauri_config.lock().unwrap().as_ref().unwrap())?;
|
||||
|
||||
if open {
|
||||
open_and_wait(config, &env)
|
||||
} else if let Some(device) = &device {
|
||||
match run(device, options, config, &env, metadata, noise_level) {
|
||||
Ok(c) => Ok(Box::new(c) as Box<dyn DevProcess + Send>),
|
||||
Err(e) => {
|
||||
crate::dev::kill_before_dev_process();
|
||||
Err(e)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
open_and_wait(config, &env)
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn run(
|
||||
device: &Device<'_>,
|
||||
options: MobileOptions,
|
||||
config: &OpenHarmonyConfig,
|
||||
env: &Env,
|
||||
_metadata: &OpenHarmonyMetadata,
|
||||
noise_level: NoiseLevel,
|
||||
) -> crate::Result<DevChild> {
|
||||
let profile = if options.debug {
|
||||
Profile::Debug
|
||||
} else {
|
||||
Profile::Release
|
||||
};
|
||||
|
||||
device
|
||||
.run(config, env, noise_level, profile)
|
||||
.map(DevChild::new)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
@@ -0,0 +1,311 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use super::{detect_target_ok, ensure_init, env, get_app, get_config, read_options, MobileTarget};
|
||||
use crate::{
|
||||
helpers::config::{get as get_tauri_config, reload as reload_tauri_config},
|
||||
interface::{AppInterface, Interface},
|
||||
mobile::CliOptions,
|
||||
Result,
|
||||
};
|
||||
use clap::{ArgAction, Parser};
|
||||
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{
|
||||
open_harmony::{hdc, target::Target},
|
||||
opts::Profile,
|
||||
target::{call_for_targets_with_fallback, TargetTrait},
|
||||
};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct Options {
|
||||
/// Targets to build.
|
||||
#[clap(
|
||||
short,
|
||||
long = "target",
|
||||
action = ArgAction::Append,
|
||||
num_args(0..),
|
||||
default_value = Target::DEFAULT_KEY,
|
||||
value_parser(clap::builder::PossibleValuesParser::new(Target::name_list()))
|
||||
)]
|
||||
targets: Option<Vec<String>>,
|
||||
/// Builds with the release flag
|
||||
#[clap(short, long)]
|
||||
release: bool,
|
||||
}
|
||||
|
||||
pub fn command(options: Options) -> Result<()> {
|
||||
crate::helpers::app_paths::resolve();
|
||||
|
||||
let profile = if options.release {
|
||||
Profile::Release
|
||||
} else {
|
||||
Profile::Debug
|
||||
};
|
||||
|
||||
let (tauri_config, cli_options) = {
|
||||
let tauri_config = get_tauri_config(tauri_utils::platform::Target::OpenHarmony, &[])?;
|
||||
let cli_options = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
read_options(tauri_config_)
|
||||
};
|
||||
|
||||
let tauri_config = if cli_options.config.is_empty() {
|
||||
tauri_config
|
||||
} else {
|
||||
// reload config with merges from the ohos dev|build script
|
||||
reload_tauri_config(
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?
|
||||
};
|
||||
|
||||
(tauri_config, cli_options)
|
||||
};
|
||||
|
||||
let (config, metadata) = {
|
||||
let tauri_config_guard = tauri_config.lock().unwrap();
|
||||
let tauri_config_ = tauri_config_guard.as_ref().unwrap();
|
||||
let (config, metadata) = get_config(
|
||||
&get_app(
|
||||
MobileTarget::OpenHarmony,
|
||||
tauri_config_,
|
||||
&AppInterface::new(tauri_config_, None)?,
|
||||
),
|
||||
tauri_config_,
|
||||
None,
|
||||
&cli_options,
|
||||
);
|
||||
(config, metadata)
|
||||
};
|
||||
|
||||
ensure_init(
|
||||
&tauri_config,
|
||||
config.app(),
|
||||
config.project_dir(),
|
||||
MobileTarget::OpenHarmony,
|
||||
)?;
|
||||
|
||||
if !cli_options.config.is_empty() {
|
||||
crate::helpers::config::merge_with(
|
||||
&cli_options
|
||||
.config
|
||||
.iter()
|
||||
.map(|conf| &conf.0)
|
||||
.collect::<Vec<_>>(),
|
||||
)?;
|
||||
}
|
||||
|
||||
let env = env()?;
|
||||
|
||||
if cli_options.dev {
|
||||
let dev_url = tauri_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.build
|
||||
.dev_url
|
||||
.clone();
|
||||
|
||||
if let Some(url) = dev_url {
|
||||
let localhost = match url.host() {
|
||||
Some(url::Host::Domain(d)) => d == "localhost",
|
||||
Some(url::Host::Ipv4(i)) => i == std::net::Ipv4Addr::LOCALHOST,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if localhost {
|
||||
if let Some(port) = url.port_or_known_default() {
|
||||
hdc_forward_port(port, &env, &cli_options)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut validated_lib = false;
|
||||
|
||||
call_for_targets_with_fallback(
|
||||
options.targets.unwrap_or_default().iter(),
|
||||
&detect_target_ok,
|
||||
&env,
|
||||
|target: &Target| {
|
||||
target.build(
|
||||
&config,
|
||||
&metadata,
|
||||
&env,
|
||||
cli_options.noise_level,
|
||||
true,
|
||||
profile,
|
||||
)?;
|
||||
|
||||
if !validated_lib {
|
||||
validated_lib = true;
|
||||
|
||||
let lib_path = config
|
||||
.app()
|
||||
.target_dir(target.triple, profile)
|
||||
.join(config.so_name());
|
||||
|
||||
validate_lib(&lib_path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)
|
||||
.map_err(|e| anyhow::anyhow!(e.to_string()))?
|
||||
}
|
||||
|
||||
fn validate_lib(path: &Path) -> Result<()> {
|
||||
let so_bytes = std::fs::read(path)?;
|
||||
let elf = elf::ElfBytes::<elf::endian::AnyEndian>::minimal_parse(&so_bytes)
|
||||
.context("failed to parse ELF")?;
|
||||
let (symbol_table, string_table) = elf
|
||||
.dynamic_symbol_table()
|
||||
.context("failed to read dynsym section")?
|
||||
.context("missing dynsym tables")?;
|
||||
|
||||
let mut symbols = Vec::new();
|
||||
for s in symbol_table.iter() {
|
||||
if let Ok(symbol) = string_table.get(s.st_name as usize) {
|
||||
symbols.push(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: implement check
|
||||
if false {
|
||||
anyhow::bail!(
|
||||
"Library from {} does not include required runtime symbols. This means you are likely missing the tauri::mobile_entry_point macro usage, see the documentation for more information: https://v2.tauri.app/start/migrate/from-tauri-1",
|
||||
path.display()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hdc_forward_port(
|
||||
port: u16,
|
||||
env: &cargo_mobile2::open_harmony::env::Env,
|
||||
cli_options: &CliOptions,
|
||||
) -> Result<()> {
|
||||
let forward = format!("tcp:{port}");
|
||||
log::info!("Forwarding port {port} with hdc");
|
||||
|
||||
let mut devices = hdc::device_list(env).unwrap_or_default();
|
||||
// if we could not detect any running device, let's wait a few seconds, it might be booting up
|
||||
if devices.is_empty() {
|
||||
log::warn!(
|
||||
"HDC device list is empty, waiting a few seconds to see if there's any booting device..."
|
||||
);
|
||||
|
||||
let max = 5;
|
||||
let mut count = 0;
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
|
||||
devices = hdc::device_list(env).unwrap_or_default();
|
||||
if !devices.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
count += 1;
|
||||
if count == max {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let target_device = if let Some(target_device) = &cli_options.target_device {
|
||||
Some((target_device.id.clone(), target_device.name.clone()))
|
||||
} else if devices.len() == 1 {
|
||||
let device = devices.first().unwrap();
|
||||
Some((device.id().to_string(), device.name().to_string()))
|
||||
} else if devices.len() > 1 {
|
||||
anyhow::bail!("Multiple OpenHarmony devices are connected ({}), please disconnect devices you do not intend to use so Tauri can determine which to use",
|
||||
devices.iter().map(|d| d.name()).collect::<Vec<_>>().join(", "));
|
||||
} else {
|
||||
// when building the app without running to a device, we might have an empty devices list
|
||||
None
|
||||
};
|
||||
|
||||
if let Some((target_device_serial_no, target_device_name)) = target_device {
|
||||
let mut already_forwarded = false;
|
||||
|
||||
// clear port forwarding for all devices
|
||||
for device in &devices {
|
||||
let reverse_list_output = hdc_reverse_list(env, device.id())?;
|
||||
|
||||
// check if the device has the port forwarded
|
||||
if String::from_utf8_lossy(&reverse_list_output.stdout).contains(&forward) {
|
||||
// device matches our target, we can skip forwarding
|
||||
if device.id() == target_device_serial_no {
|
||||
log::debug!(
|
||||
"device {} already has the forward for {}",
|
||||
device.name(),
|
||||
forward
|
||||
);
|
||||
already_forwarded = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// if there's a known target, we should forward the port to it
|
||||
if already_forwarded {
|
||||
log::info!("{forward} already forwarded to {target_device_name}");
|
||||
} else {
|
||||
loop {
|
||||
run_hdc_reverse(env, &target_device_serial_no, &forward, &forward).with_context(|| {
|
||||
format!("failed to forward port with hdc, is the {target_device_name} device connected?",)
|
||||
})?;
|
||||
|
||||
let reverse_list_output = hdc_reverse_list(env, &target_device_serial_no)?;
|
||||
// wait and retry until the port has actually been forwarded
|
||||
if String::from_utf8_lossy(&reverse_list_output.stdout).contains(&forward) {
|
||||
break;
|
||||
} else {
|
||||
log::warn!(
|
||||
"waiting for the port to be forwarded to {}...",
|
||||
target_device_name
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("no running devices detected with HDC; skipping port forwarding");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_hdc_reverse(
|
||||
env: &cargo_mobile2::open_harmony::env::Env,
|
||||
device_serial_no: &str,
|
||||
remote: &str,
|
||||
local: &str,
|
||||
) -> std::io::Result<std::process::Output> {
|
||||
hdc::hdc(env, ["-t", device_serial_no, "rport", remote, local])
|
||||
.stdin_file(os_pipe::dup_stdin().unwrap())
|
||||
.stdout_file(os_pipe::dup_stdout().unwrap())
|
||||
.stderr_file(os_pipe::dup_stdout().unwrap())
|
||||
.run()
|
||||
}
|
||||
|
||||
fn hdc_reverse_list(
|
||||
env: &cargo_mobile2::open_harmony::env::Env,
|
||||
device_serial_no: &str,
|
||||
) -> std::io::Result<std::process::Output> {
|
||||
hdc::hdc(env, ["-t", device_serial_no, "fport", "ls"])
|
||||
.stdin_file(os_pipe::dup_stdin().unwrap())
|
||||
.stdout_capture()
|
||||
.stderr_capture()
|
||||
.run()
|
||||
}
|
||||
335
crates/tauri-cli/src/mobile/open_harmony/mod.rs
Normal file
335
crates/tauri-cli/src/mobile/open_harmony/mod.rs
Normal file
@@ -0,0 +1,335 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use serde::Deserialize;
|
||||
|
||||
use cargo_mobile2::{
|
||||
config::app::{App, DEFAULT_ASSET_DIR},
|
||||
open_harmony::{
|
||||
config::{
|
||||
Config as OpenHarmonyConfig, Metadata as OpenHarmonyMetadata, Raw as RawOpenHarmonyConfig,
|
||||
},
|
||||
device::Device,
|
||||
emulator,
|
||||
env::Env,
|
||||
hdc,
|
||||
target::Target,
|
||||
},
|
||||
opts::{FilterLevel, NoiseLevel},
|
||||
os,
|
||||
util::prompt,
|
||||
};
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::{
|
||||
env::set_var,
|
||||
fs::{create_dir_all, write},
|
||||
thread::sleep,
|
||||
time::Duration,
|
||||
};
|
||||
use sublime_fuzzy::best_match;
|
||||
use tauri_utils::resources::ResourcePaths;
|
||||
|
||||
use super::{
|
||||
ensure_init, get_app, init::command as init_command, log_finished, read_options, CliOptions,
|
||||
OptionsHandle, Target as MobileTarget, MIN_DEVICE_MATCH_SCORE,
|
||||
};
|
||||
use crate::{
|
||||
helpers::config::{BundleResources, Config as TauriConfig},
|
||||
ConfigValue, Result,
|
||||
};
|
||||
|
||||
mod build;
|
||||
mod dev;
|
||||
mod dev_eco_studio_script;
|
||||
pub(crate) mod project;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct AppConfig {
|
||||
pub app: AppConfigObject,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct AppConfigObject {
|
||||
pub bundle_name: String,
|
||||
// TODO: impl versioning
|
||||
//pub version_code: u32,
|
||||
//pub version_name: String,
|
||||
}
|
||||
|
||||
#[derive(Parser)]
|
||||
#[clap(
|
||||
author,
|
||||
version,
|
||||
about = "OpenHarmony commands",
|
||||
subcommand_required(true),
|
||||
arg_required_else_help(true)
|
||||
)]
|
||||
pub struct Cli {
|
||||
#[clap(subcommand)]
|
||||
command: Commands,
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
#[clap(about = "Initialize OpenHarmony target in the project")]
|
||||
pub struct InitOptions {
|
||||
/// Skip prompting for values
|
||||
#[clap(long, env = "CI")]
|
||||
ci: bool,
|
||||
/// Skips installing rust toolchains via rustup
|
||||
#[clap(long)]
|
||||
skip_targets_install: bool,
|
||||
/// JSON strings or paths to JSON, JSON5 or TOML files to merge with the default configuration file
|
||||
///
|
||||
/// Configurations are merged in the order they are provided, which means a particular value overwrites previous values when a config key-value pair conflicts.
|
||||
///
|
||||
/// Note that a platform-specific file is looked up and merged with the default file by default
|
||||
/// (tauri.macos.conf.json, tauri.linux.conf.json, tauri.windows.conf.json, tauri.android.conf.json, tauri.ios.conf.json and tauri.ohos.conf.json)
|
||||
/// but you can use this for more specific use cases such as different build flavors.
|
||||
#[clap(short, long)]
|
||||
pub config: Vec<ConfigValue>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Commands {
|
||||
Init(InitOptions),
|
||||
Dev(dev::Options),
|
||||
Build(build::Options),
|
||||
#[clap(hide(true))]
|
||||
DevEcoStudioScript(dev_eco_studio_script::Options),
|
||||
}
|
||||
|
||||
pub fn command(cli: Cli, verbosity: u8) -> Result<()> {
|
||||
let noise_level = NoiseLevel::from_occurrences(verbosity as u64);
|
||||
match cli.command {
|
||||
Commands::Init(options) => {
|
||||
crate::helpers::app_paths::resolve();
|
||||
init_command(
|
||||
MobileTarget::OpenHarmony,
|
||||
options.ci,
|
||||
false,
|
||||
options.skip_targets_install,
|
||||
options.config,
|
||||
)?
|
||||
}
|
||||
Commands::Dev(options) => dev::command(options, noise_level)?,
|
||||
Commands::Build(options) => build::command(options, noise_level)?,
|
||||
Commands::DevEcoStudioScript(options) => dev_eco_studio_script::command(options)?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_config(
|
||||
app: &App,
|
||||
_config: &TauriConfig,
|
||||
features: Option<&Vec<String>>,
|
||||
cli_options: &CliOptions,
|
||||
) -> (OpenHarmonyConfig, OpenHarmonyMetadata) {
|
||||
let mut open_harmony_options = cli_options.clone();
|
||||
if let Some(features) = features {
|
||||
open_harmony_options
|
||||
.features
|
||||
.get_or_insert(Vec::new())
|
||||
.extend_from_slice(features);
|
||||
}
|
||||
|
||||
let raw = RawOpenHarmonyConfig {
|
||||
features: open_harmony_options.features.clone(),
|
||||
logcat_filter_specs: vec![
|
||||
"RustStdoutStderr".into(),
|
||||
format!(
|
||||
"*:{}",
|
||||
match cli_options.noise_level {
|
||||
NoiseLevel::Polite => FilterLevel::Info,
|
||||
NoiseLevel::LoudAndProud => FilterLevel::Debug,
|
||||
NoiseLevel::FranklyQuitePedantic => FilterLevel::Verbose,
|
||||
}
|
||||
.logcat()
|
||||
),
|
||||
],
|
||||
..Default::default()
|
||||
};
|
||||
let config = OpenHarmonyConfig::from_raw(app.clone(), Some(raw)).unwrap();
|
||||
|
||||
let metadata = OpenHarmonyMetadata {
|
||||
supported: true,
|
||||
cargo_args: Some(open_harmony_options.args),
|
||||
features: open_harmony_options.features,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
set_var(
|
||||
"WRY_OHOS_PACKAGE",
|
||||
app.android_identifier_escape_kotlin_keyword(),
|
||||
);
|
||||
set_var("TAURI_OHOS_PACKAGE_UNESCAPED", app.identifier());
|
||||
set_var("WRY_OHOS_LIBRARY", app.lib_name());
|
||||
set_var("TAURI_OHOS_PROJECT_PATH", config.project_dir());
|
||||
|
||||
(config, metadata)
|
||||
}
|
||||
|
||||
fn env() -> Result<Env> {
|
||||
let env = super::env()?;
|
||||
cargo_mobile2::open_harmony::env::Env::from_env(env).map_err(Into::into)
|
||||
}
|
||||
|
||||
fn delete_codegen_vars() {
|
||||
for (k, _) in std::env::vars() {
|
||||
if k.starts_with("WRY_") && (k.ends_with("CLASS_EXTENSION") || k.ends_with("CLASS_INIT")) {
|
||||
std::env::remove_var(k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn adb_device_prompt<'a>(env: &'_ Env, target: Option<&str>) -> Result<Device<'a>> {
|
||||
let device_list = hdc::device_list(env)
|
||||
.map_err(|cause| anyhow::anyhow!("Failed to detect connected OpenHarmony devices: {cause}"))?;
|
||||
if !device_list.is_empty() {
|
||||
let device = if let Some(t) = target {
|
||||
let (device, score) = device_list
|
||||
.into_iter()
|
||||
.rev()
|
||||
.map(|d| {
|
||||
let score = best_match(t, d.name()).map_or(0, |m| m.score());
|
||||
(d, score)
|
||||
})
|
||||
.max_by_key(|(_, score)| *score)
|
||||
// we already checked the list is not empty
|
||||
.unwrap();
|
||||
if score > MIN_DEVICE_MATCH_SCORE {
|
||||
device
|
||||
} else {
|
||||
anyhow::bail!("Could not find an OpenHarmony device matching {t}")
|
||||
}
|
||||
} else if device_list.len() > 1 {
|
||||
let index = prompt::list(
|
||||
concat!("Detected ", "OpenHarmony", " devices"),
|
||||
device_list.iter(),
|
||||
"device",
|
||||
None,
|
||||
"Device",
|
||||
)
|
||||
.map_err(|cause| anyhow::anyhow!("Failed to prompt for OpenHarmony device: {cause}"))?;
|
||||
device_list.into_iter().nth(index).unwrap()
|
||||
} else {
|
||||
device_list.into_iter().next().unwrap()
|
||||
};
|
||||
|
||||
log::info!(
|
||||
"Detected connected device: {} with target {:?}",
|
||||
device,
|
||||
device.target().triple,
|
||||
);
|
||||
Ok(device)
|
||||
} else {
|
||||
Err(anyhow::anyhow!("No connected OpenHarmony devices detected"))
|
||||
}
|
||||
}
|
||||
|
||||
fn emulator_prompt(_env: &'_ Env, target: Option<&str>) -> Result<emulator::Emulator> {
|
||||
let emulator_list = emulator::hvd_list().unwrap_or_default();
|
||||
if !emulator_list.is_empty() {
|
||||
let emulator = if let Some(t) = target {
|
||||
let (device, score) = emulator_list
|
||||
.into_iter()
|
||||
.rev()
|
||||
.map(|d| {
|
||||
let score = best_match(t, d.name()).map_or(0, |m| m.score());
|
||||
(d, score)
|
||||
})
|
||||
.max_by_key(|(_, score)| *score)
|
||||
// we already checked the list is not empty
|
||||
.unwrap();
|
||||
if score > MIN_DEVICE_MATCH_SCORE {
|
||||
device
|
||||
} else {
|
||||
anyhow::bail!("Could not find an OpenHarmony Emulator matching {t}")
|
||||
}
|
||||
} else if emulator_list.len() > 1 {
|
||||
let index = prompt::list(
|
||||
concat!("Detected ", "OpenHarmony", " emulators"),
|
||||
emulator_list.iter(),
|
||||
"emulator",
|
||||
None,
|
||||
"Emulator",
|
||||
)
|
||||
.map_err(|cause| {
|
||||
anyhow::anyhow!("Failed to prompt for OpenHarmony Emulator device: {cause}")
|
||||
})?;
|
||||
emulator_list.into_iter().nth(index).unwrap()
|
||||
} else {
|
||||
emulator_list.into_iter().next().unwrap()
|
||||
};
|
||||
|
||||
Ok(emulator)
|
||||
} else {
|
||||
Err(anyhow::anyhow!(
|
||||
"No available OpenHarmony Emulator detected"
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn device_prompt<'a>(env: &'_ Env, target: Option<&str>) -> Result<Device<'a>> {
|
||||
if let Ok(device) = adb_device_prompt(env, target) {
|
||||
Ok(device)
|
||||
} else {
|
||||
let emulator = emulator_prompt(env, target)?;
|
||||
log::info!("Starting emulator {}", emulator.name());
|
||||
emulator.start_detached(env)?;
|
||||
let mut tries = 0;
|
||||
loop {
|
||||
sleep(Duration::from_secs(2));
|
||||
if let Ok(device) = adb_device_prompt(env, Some(emulator.name())) {
|
||||
return Ok(device);
|
||||
}
|
||||
if tries >= 3 {
|
||||
log::info!("Waiting for emulator to start... (maybe the emulator is unauthorized or offline, run `adb devices` to check)");
|
||||
} else {
|
||||
log::info!("Waiting for emulator to start...");
|
||||
}
|
||||
tries += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn detect_target_ok<'a>(env: &Env) -> Option<&'a Target<'a>> {
|
||||
device_prompt(env, None).map(|device| device.target()).ok()
|
||||
}
|
||||
|
||||
fn open_and_wait(config: &OpenHarmonyConfig, env: &Env) -> ! {
|
||||
log::info!("Opening DevEco Studio");
|
||||
if let Err(e) = os::open_file_with("DevEco Studio", config.project_dir(), &env.base) {
|
||||
log::error!("{e}");
|
||||
}
|
||||
loop {
|
||||
sleep(Duration::from_secs(24 * 60 * 60));
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_resources(config: &OpenHarmonyConfig, tauri_config: &TauriConfig) -> Result<()> {
|
||||
let asset_dir = config.project_dir().join(DEFAULT_ASSET_DIR);
|
||||
create_dir_all(&asset_dir)?;
|
||||
|
||||
write(
|
||||
asset_dir.join("tauri.conf.json"),
|
||||
serde_json::to_string(&tauri_config)?,
|
||||
)?;
|
||||
|
||||
let resources = match &tauri_config.bundle.resources {
|
||||
Some(BundleResources::List(paths)) => Some(ResourcePaths::new(paths.as_slice(), true)),
|
||||
Some(BundleResources::Map(map)) => Some(ResourcePaths::from_map(map, true)),
|
||||
None => None,
|
||||
};
|
||||
if let Some(resources) = resources {
|
||||
for resource in resources.iter() {
|
||||
let resource = resource?;
|
||||
let dest = asset_dir.join(resource.target());
|
||||
crate::helpers::fs::copy_file(resource.path(), dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
36
crates/tauri-cli/src/mobile/open_harmony/project.rs
Normal file
36
crates/tauri-cli/src/mobile/open_harmony/project.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use crate::{helpers::template, Result};
|
||||
use anyhow::Context;
|
||||
use cargo_mobile2::{config::app::App, open_harmony::config::Config, os, util};
|
||||
use handlebars::Handlebars;
|
||||
use include_dir::{include_dir, Dir};
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
const TEMPLATE_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/templates/mobile/open-harmony");
|
||||
|
||||
pub fn gen(
|
||||
app: &App,
|
||||
config: &Config,
|
||||
(handlebars, mut map): (Handlebars, template::JsonMap),
|
||||
) -> Result<()> {
|
||||
println!("Generating DevEco Studio project...");
|
||||
let dest = config.project_dir();
|
||||
|
||||
map.insert(
|
||||
"root-dir-rel",
|
||||
Path::new(&os::replace_path_separator(
|
||||
util::relativize_path(app.root_dir(), dest.join(app.name_snake())).into_os_string(),
|
||||
)),
|
||||
);
|
||||
map.insert("root-dir", app.root_dir());
|
||||
map.insert("windows", cfg!(windows));
|
||||
|
||||
template::render(&handlebars, map.inner(), &TEMPLATE_DIR, &dest)
|
||||
.with_context(|| "failed to process template")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
12
crates/tauri-cli/templates/mobile/open-harmony/.gitignore
vendored
Normal file
12
crates/tauri-cli/templates/mobile/open-harmony/.gitignore
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/local.properties
|
||||
/.idea
|
||||
**/build
|
||||
/.hvigor
|
||||
.cxx
|
||||
/.clangd
|
||||
/.clang-format
|
||||
/.clang-tidy
|
||||
**/.test
|
||||
/.appanalyzer
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"app": {
|
||||
"bundleName": "{{app.identifier}}",
|
||||
"vendor": "{{app.publisher}}",
|
||||
"versionCode": 1,
|
||||
"versionName": "1.0.0",
|
||||
"icon": "$media:layered_image",
|
||||
"label": "$string:app_name"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "app_name",
|
||||
"value": "{{app.stylized-name}}"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"layered-image":
|
||||
{
|
||||
"background" : "$media:background",
|
||||
"foreground" : "$media:foreground"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"app": {
|
||||
"signingConfigs": [],
|
||||
"products": [
|
||||
{
|
||||
"name": "default",
|
||||
"signingConfig": "default",
|
||||
"compatibleSdkVersion": "5.0.0(12)",
|
||||
"runtimeOS": "HarmonyOS",
|
||||
"buildOption": {
|
||||
"strictMode": {
|
||||
"caseSensitiveCheck": true,
|
||||
"useNormalizedOHMUrl": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"buildModeSet": [
|
||||
{
|
||||
"name": "debug",
|
||||
},
|
||||
{
|
||||
"name": "release"
|
||||
}
|
||||
]
|
||||
},
|
||||
"modules": [
|
||||
{
|
||||
"name": "entry",
|
||||
"srcPath": "./entry",
|
||||
"targets": [
|
||||
{
|
||||
"name": "default",
|
||||
"applyToProducts": [
|
||||
"default"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"files": [
|
||||
"**/*.ets"
|
||||
],
|
||||
"ignore": [
|
||||
"**/src/ohosTest/**/*",
|
||||
"**/src/test/**/*",
|
||||
"**/src/mock/**/*",
|
||||
"**/node_modules/**/*",
|
||||
"**/oh_modules/**/*",
|
||||
"**/build/**/*",
|
||||
"**/.preview/**/*"
|
||||
],
|
||||
"ruleSet": [
|
||||
"plugin:@performance/recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
"rules": {
|
||||
"@security/no-unsafe-aes": "error",
|
||||
"@security/no-unsafe-hash": "error",
|
||||
"@security/no-unsafe-mac": "warn",
|
||||
"@security/no-unsafe-dh": "error",
|
||||
"@security/no-unsafe-dsa": "error",
|
||||
"@security/no-unsafe-ecdsa": "error",
|
||||
"@security/no-unsafe-rsa-encrypt": "error",
|
||||
"@security/no-unsafe-rsa-sign": "error",
|
||||
"@security/no-unsafe-rsa-key": "error",
|
||||
"@security/no-unsafe-dsa-key": "error",
|
||||
"@security/no-unsafe-dh-key": "error",
|
||||
"@security/no-unsafe-3des": "error"
|
||||
}
|
||||
}
|
||||
7
crates/tauri-cli/templates/mobile/open-harmony/entry/.gitignore
vendored
Normal file
7
crates/tauri-cli/templates/mobile/open-harmony/entry/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/node_modules
|
||||
/oh_modules
|
||||
/.preview
|
||||
/build
|
||||
/.cxx
|
||||
/.test
|
||||
/libs
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"apiType": "stageMode",
|
||||
"buildOption": {
|
||||
"externalNativeOptions": {
|
||||
"path": "./src/main/cpp/CMakeLists.txt",
|
||||
"arguments": "",
|
||||
"cppFlags": "",
|
||||
}
|
||||
},
|
||||
"buildOptionSet": [
|
||||
{
|
||||
"name": "release",
|
||||
"arkOptions": {
|
||||
"obfuscation": {
|
||||
"ruleOptions": {
|
||||
"enable": false,
|
||||
"files": [
|
||||
"./obfuscation-rules.txt"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"nativeLib": {
|
||||
"debugSymbol": {
|
||||
"strip": true,
|
||||
"exclude": []
|
||||
}
|
||||
}
|
||||
},
|
||||
],
|
||||
"targets": [
|
||||
{
|
||||
"name": "default"
|
||||
},
|
||||
{
|
||||
"name": "ohosTest",
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { appTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
import { hvigor, HvigorPlugin, HvigorNode } from '@ohos/hvigor';
|
||||
import { execSync } from 'child_process';
|
||||
import { resolve } from 'path';
|
||||
|
||||
export default {
|
||||
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||
plugins:[tauriPlugin()] /* Custom plugin to extend the functionality of Hvigor. */
|
||||
}
|
||||
|
||||
function tauriPlugin(): HvigorPlugin {
|
||||
return {
|
||||
pluginId: 'tauri',
|
||||
apply(node: HvigorNode) {
|
||||
const properties = hvigor.getParameter().getProperties();
|
||||
const target = properties.target || "aarch64";
|
||||
execSync(`{{tauri-binary}}`, [`{{quote-and-join tauri-binary-args}}`, "--target", target], {
|
||||
cwd: resolve(__dirname, "{{root-dir-rel}}"),
|
||||
stdio: "inherit",
|
||||
shell: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Define project specific obfuscation rules here.
|
||||
# You can include the obfuscation configuration files in the current module's build-profile.json5.
|
||||
#
|
||||
# For more details, see
|
||||
# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
|
||||
|
||||
# Obfuscation options:
|
||||
# -disable-obfuscation: disable all obfuscations
|
||||
# -enable-property-obfuscation: obfuscate the property names
|
||||
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
|
||||
# -compact: remove unnecessary blank spaces and all line feeds
|
||||
# -remove-log: remove all console.* statements
|
||||
# -print-namecache: print the name cache that contains the mapping from the old names to new names
|
||||
# -apply-namecache: reuse the given cache file
|
||||
|
||||
# Keep options:
|
||||
# -keep-property-name: specifies property names that you want to keep
|
||||
# -keep-global-name: specifies names that you want to keep in the global scope
|
||||
|
||||
-enable-property-obfuscation
|
||||
-enable-toplevel-obfuscation
|
||||
-enable-filename-obfuscation
|
||||
-enable-export-obfuscation
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"meta": {
|
||||
"stableOrder": true,
|
||||
"enableUnifiedLockfile": false
|
||||
},
|
||||
"lockfileVersion": 3,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {
|
||||
"@ohos-rs/ability@0.2.1": "@ohos-rs/ability@0.2.1",
|
||||
"libentry.so@src/main/cpp/types/libentry": "libentry.so@src/main/cpp/types/libentry"
|
||||
},
|
||||
"packages": {
|
||||
"@ohos-rs/ability@0.2.1": {
|
||||
"name": "@ohos-rs/ability",
|
||||
"version": "0.2.1",
|
||||
"integrity": "sha512-/IYR/8+TgAn5ij3OT/gRk4e71eQ/+WBFQuADqMRyIUhIEVg/9MhDyWZJmITvm50ay5cMbGtry14b+TN0vwlOBg==",
|
||||
"resolved": "https://repo.harmonyos.com/ohpm/@ohos-rs/ability/-/ability-0.2.1.har",
|
||||
"registryType": "ohpm"
|
||||
},
|
||||
"libentry.so@src/main/cpp/types/libentry": {
|
||||
"name": "libentry.so",
|
||||
"version": "1.0.0",
|
||||
"resolved": "src/main/cpp/types/libentry",
|
||||
"registryType": "local"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "entry",
|
||||
"version": "1.0.0",
|
||||
"description": "Please describe the basic information.",
|
||||
"main": "",
|
||||
"author": "",
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
"libentry.so": "file:./src/main/cpp/types/libentry",
|
||||
"@ohos-rs/ability": "0.2.1"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# the minimum version of CMake.
|
||||
cmake_minimum_required(VERSION 3.5.0)
|
||||
project(webview_example)
|
||||
|
||||
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
if(DEFINED PACKAGE_FIND_FILE)
|
||||
include(${PACKAGE_FIND_FILE})
|
||||
endif()
|
||||
|
||||
include_directories(${NATIVERENDER_ROOT_PATH}
|
||||
${NATIVERENDER_ROOT_PATH}/include)
|
||||
|
||||
add_library(entry SHARED napi_init.cpp)
|
||||
target_link_libraries(entry PUBLIC libace_napi.z.so)
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "napi/native_api.h"
|
||||
|
||||
static napi_value Add(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 2;
|
||||
napi_value args[2] = {nullptr};
|
||||
|
||||
napi_get_cb_info(env, info, &argc, args , nullptr, nullptr);
|
||||
|
||||
napi_valuetype valuetype0;
|
||||
napi_typeof(env, args[0], &valuetype0);
|
||||
|
||||
napi_valuetype valuetype1;
|
||||
napi_typeof(env, args[1], &valuetype1);
|
||||
|
||||
double value0;
|
||||
napi_get_value_double(env, args[0], &value0);
|
||||
|
||||
double value1;
|
||||
napi_get_value_double(env, args[1], &value1);
|
||||
|
||||
napi_value sum;
|
||||
napi_create_double(env, value0 + value1, &sum);
|
||||
|
||||
return sum;
|
||||
|
||||
}
|
||||
|
||||
EXTERN_C_START
|
||||
static napi_value Init(napi_env env, napi_value exports)
|
||||
{
|
||||
napi_property_descriptor desc[] = {
|
||||
{ "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
|
||||
};
|
||||
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
|
||||
return exports;
|
||||
}
|
||||
EXTERN_C_END
|
||||
|
||||
static napi_module demoModule = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Init,
|
||||
.nm_modname = "entry",
|
||||
.nm_priv = ((void*)0),
|
||||
.reserved = { 0 },
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)
|
||||
{
|
||||
napi_module_register(&demoModule);
|
||||
}
|
||||
1
crates/tauri-cli/templates/mobile/open-harmony/entry/src/main/cpp/types/libentry/Index.d.ts
vendored
Normal file
1
crates/tauri-cli/templates/mobile/open-harmony/entry/src/main/cpp/types/libentry/Index.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
export const add: (a: number, b: number) => number;
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "libentry.so",
|
||||
"types": "./Index.d.ts",
|
||||
"version": "1.0.0",
|
||||
"description": "Please describe the basic information."
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
import { RustAbility } from '@ohos-rs/ability'
|
||||
import Want from '@ohos.app.ability.Want'
|
||||
import { AbilityConstant } from '@kit.AbilityKit';
|
||||
import window from '@ohos.window';
|
||||
|
||||
export default class EntryAbility extends RustAbility {
|
||||
// change to dynamic library name
|
||||
public moduleName: string = "{{app.name}}"
|
||||
public defaultPage: boolean = true;
|
||||
public mode: 'xcomponent' | 'webview' = 'webview'
|
||||
|
||||
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
|
||||
super.onCreate(want, launchParam);
|
||||
}
|
||||
|
||||
async onWindowStageCreate(windowStage: window.WindowStage): Promise<void> {
|
||||
const window = windowStage.getMainWindowSync();
|
||||
await window.setWindowLayoutFullScreen(false);
|
||||
super.onWindowStageCreate(windowStage);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
|
||||
|
||||
const DOMAIN = 0x0000;
|
||||
|
||||
export default class EntryBackupAbility extends BackupExtensionAbility {
|
||||
async onBackup() {
|
||||
hilog.info(DOMAIN, 'testTag', 'onBackup ok');
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
async onRestore(bundleVersion: BundleVersion) {
|
||||
hilog.info(DOMAIN, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
|
||||
await Promise.resolve();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import testNapi from 'libentry.so';
|
||||
|
||||
const DOMAIN = 0x0000;
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct Index {
|
||||
@State message: string = 'Hello World';
|
||||
|
||||
build() {
|
||||
Row() {
|
||||
Column() {
|
||||
Text(this.message)
|
||||
.fontSize($r('app.float.page_text_font_size'))
|
||||
.fontWeight(FontWeight.Bold)
|
||||
.onClick(() => {
|
||||
this.message = 'Welcome';
|
||||
hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', testNapi.add(2, 3));
|
||||
})
|
||||
}
|
||||
.width('100%')
|
||||
}
|
||||
.height('100%')
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"module": {
|
||||
"name": "entry",
|
||||
"type": "entry",
|
||||
"description": "$string:module_desc",
|
||||
"mainElement": "EntryAbility",
|
||||
"deviceTypes": [
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false,
|
||||
"pages": "$profile:main_pages",
|
||||
"abilities": [
|
||||
{
|
||||
"name": "EntryAbility",
|
||||
"srcEntry": "./ets/entryability/EntryAbility.ets",
|
||||
"description": "$string:EntryAbility_desc",
|
||||
"icon": "$media:layered_image",
|
||||
"label": "$string:EntryAbility_label",
|
||||
"startWindowIcon": "$media:startIcon",
|
||||
"startWindowBackground": "$color:start_window_background",
|
||||
"exported": true,
|
||||
"skills": [
|
||||
{
|
||||
"entities": [
|
||||
"entity.system.home"
|
||||
],
|
||||
"actions": [
|
||||
"action.system.home"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"extensionAbilities": [
|
||||
{
|
||||
"name": "EntryBackupAbility",
|
||||
"srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
|
||||
"type": "backup",
|
||||
"exported": false,
|
||||
"metadata": [
|
||||
{
|
||||
"name": "ohos.extension.backup",
|
||||
"resource": "$profile:backup_config"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"requestPermissions": [
|
||||
{
|
||||
"name": "ohos.permission.INTERNET"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#FFFFFF"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"float": [
|
||||
{
|
||||
"name": "page_text_font_size",
|
||||
"value": "50fp"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "module_desc",
|
||||
"value": "module description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_desc",
|
||||
"value": "description"
|
||||
},
|
||||
{
|
||||
"name": "EntryAbility_label",
|
||||
"value": "label"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"layered-image":
|
||||
{
|
||||
"background" : "$media:background",
|
||||
"foreground" : "$media:foreground"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"allowToBackupRestore": true
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"src": [
|
||||
"pages/Index"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"color": [
|
||||
{
|
||||
"name": "start_window_background",
|
||||
"value": "#000000"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
const NativeMock: Record<string, Object> = {
|
||||
'add': (a: number, b: number) => {
|
||||
return a + b;
|
||||
},
|
||||
};
|
||||
|
||||
export default NativeMock;
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"libentry.so": {
|
||||
"source": "src/mock/Libentry.mock.ets"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function abilityTest() {
|
||||
describe('ActsAbilityTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
})
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
})
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import abilityTest from './Ability.test';
|
||||
|
||||
export default function testsuite() {
|
||||
abilityTest();
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"module": {
|
||||
"name": "entry_test",
|
||||
"type": "feature",
|
||||
"deviceTypes": [
|
||||
"phone",
|
||||
"tablet",
|
||||
"2in1"
|
||||
],
|
||||
"deliveryWithInstall": true,
|
||||
"installationFree": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import localUnitTest from './LocalUnit.test';
|
||||
|
||||
export default function testsuite() {
|
||||
localUnitTest();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
|
||||
|
||||
export default function localUnitTest() {
|
||||
describe('localUnitTest', () => {
|
||||
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
|
||||
beforeAll(() => {
|
||||
// Presets an action, which is performed only once before all test cases of the test suite start.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
beforeEach(() => {
|
||||
// Presets an action, which is performed before each unit test case starts.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: preset action function.
|
||||
});
|
||||
afterEach(() => {
|
||||
// Presets a clear action, which is performed after each unit test case ends.
|
||||
// The number of execution times is the same as the number of test cases defined by **it**.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
afterAll(() => {
|
||||
// Presets a clear action, which is performed after all test cases of the test suite end.
|
||||
// This API supports only one parameter: clear action function.
|
||||
});
|
||||
it('assertContain', 0, () => {
|
||||
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
|
||||
let a = 'abc';
|
||||
let b = 'b';
|
||||
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
|
||||
expect(a).assertContain(b);
|
||||
expect(a).assertEqual(a);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"modelVersion": "5.0.3",
|
||||
"dependencies": {
|
||||
},
|
||||
"execution": {
|
||||
// "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */
|
||||
// "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
|
||||
// "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
|
||||
// "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
|
||||
// "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
|
||||
},
|
||||
"logging": {
|
||||
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
|
||||
},
|
||||
"debugging": {
|
||||
// "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
|
||||
},
|
||||
"nodeOptions": {
|
||||
// "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
|
||||
// "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
import { appTasks } from '@ohos/hvigor-ohos-plugin';
|
||||
|
||||
export default {
|
||||
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
|
||||
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
{
|
||||
"meta": {
|
||||
"stableOrder": true,
|
||||
"enableUnifiedLockfile": false
|
||||
},
|
||||
"lockfileVersion": 3,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {
|
||||
"@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0",
|
||||
"@ohos/hypium@1.0.21": "@ohos/hypium@1.0.21"
|
||||
},
|
||||
"packages": {
|
||||
"@ohos/hamock@1.0.0": {
|
||||
"name": "@ohos/hamock",
|
||||
"version": "1.0.0",
|
||||
"integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==",
|
||||
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hamock/-/hamock-1.0.0.har",
|
||||
"registryType": "ohpm"
|
||||
},
|
||||
"@ohos/hypium@1.0.21": {
|
||||
"name": "@ohos/hypium",
|
||||
"version": "1.0.21",
|
||||
"integrity": "sha512-iyKGMXxE+9PpCkqEwu0VykN/7hNpb+QOeIuHwkmZnxOpI+dFZt6yhPB7k89EgV1MiSK/ieV/hMjr5Z2mWwRfMQ==",
|
||||
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.21.har",
|
||||
"registryType": "ohpm"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"modelVersion": "5.0.3",
|
||||
"description": "Please describe the basic information.",
|
||||
"dependencies": {
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ohos/hypium": "1.0.21",
|
||||
"@ohos/hamock": "1.0.0"
|
||||
}
|
||||
}
|
||||
@@ -89,6 +89,16 @@ pub fn entry_point(_attributes: TokenStream, item: TokenStream) -> TokenStream {
|
||||
pub extern "C" fn start_app() {
|
||||
_start_app()
|
||||
}
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
use ::tauri::ohos::*;
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
#[::tauri::ohos::openharmony_ability_derive::ability(webview)]
|
||||
pub fn openharmony(app: ::tauri::ohos::openharmony_ability::OpenHarmonyApp) {
|
||||
::tauri::ohos::APP.lock().unwrap().replace(app);
|
||||
_start_app()
|
||||
}
|
||||
)
|
||||
.into()
|
||||
}
|
||||
|
||||
@@ -64,10 +64,11 @@ pub(crate) fn setup(
|
||||
android_path: Option<PathBuf>,
|
||||
#[allow(unused_variables)] ios_path: Option<PathBuf>,
|
||||
) -> Result<()> {
|
||||
let target_os = build_var("CARGO_CFG_TARGET_OS")?;
|
||||
let mobile = target_os == "android" || target_os == "ios";
|
||||
cfg_alias("mobile", mobile);
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
||||
let mobile = target_os == "ios" || target_os == "android" || target_env == "ohos";
|
||||
cfg_alias("desktop", !mobile);
|
||||
cfg_alias("mobile", mobile);
|
||||
|
||||
match target_os.as_str() {
|
||||
"android" => {
|
||||
|
||||
@@ -41,7 +41,7 @@ once_cell = "1.20"
|
||||
version = "0.61"
|
||||
features = ["Win32_Foundation", "Win32_Graphics_Dwm"]
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
[target.'cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"), not(target_env = "ohos")))'.dependencies]
|
||||
gtk = { version = "0.18", features = ["v3_24"] }
|
||||
webkit2gtk = { version = "=2.0", features = ["v2_40"] }
|
||||
percent-encoding = "2"
|
||||
|
||||
@@ -13,7 +13,8 @@ fn alias(alias: &str, has_feature: bool) {
|
||||
|
||||
fn main() {
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
||||
let mobile = target_os == "ios" || target_os == "android" || target_env == "ohos";
|
||||
alias("desktop", !mobile);
|
||||
alias("mobile", mobile);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ use tauri_runtime::{
|
||||
use objc2::rc::Retained;
|
||||
#[cfg(target_os = "macos")]
|
||||
use tao::platform::macos::{EventLoopWindowTargetExtMacOS, WindowBuilderExtMacOS};
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
use tao::platform::unix::{WindowBuilderExtUnix, WindowExtUnix};
|
||||
#[cfg(windows)]
|
||||
use tao::platform::windows::{WindowBuilderExtWindows, WindowExtWindows};
|
||||
@@ -100,7 +100,8 @@ use wry::{
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
target_os = "android",
|
||||
target_env = "ohos",
|
||||
)))]
|
||||
use wry::{WebViewBuilderExtUnix, WebViewExtUnix};
|
||||
|
||||
@@ -110,6 +111,8 @@ pub use tao::platform::ios::WindowExtIOS;
|
||||
pub use tao::platform::macos::{
|
||||
ActivationPolicy as TaoActivationPolicy, EventLoopExtMacOS, WindowExtMacOS,
|
||||
};
|
||||
#[cfg(target_env = "ohos")]
|
||||
pub use tao::platform::ohos::EventLoopBuilderExtOpenHarmony;
|
||||
#[cfg(target_os = "macos")]
|
||||
use tauri_runtime::ActivationPolicy;
|
||||
|
||||
@@ -858,7 +861,7 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
");
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
{
|
||||
// Mouse event is disabled on Linux since sudden event bursts could block event loop.
|
||||
window.inner = window.inner.with_cursor_moved_event(false);
|
||||
@@ -1114,12 +1117,15 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn transient_for(mut self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
|
||||
self.inner = self.inner.with_transient_for(parent);
|
||||
@@ -1190,13 +1196,18 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
#[cfg(all(any(windows, target_os = "linux"), not(target_env = "ohos")))]
|
||||
fn skip_taskbar(mut self, skip: bool) -> Self {
|
||||
self.inner = self.inner.with_skip_taskbar(skip);
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))]
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android",
|
||||
target_env = "ohos"
|
||||
))]
|
||||
fn skip_taskbar(self, _skip: bool) -> Self {
|
||||
self
|
||||
}
|
||||
@@ -1236,38 +1247,50 @@ impl WindowBuilder for WindowBuilderWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub struct GtkWindow(pub gtk::ApplicationWindow);
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Send for GtkWindow {}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub struct GtkBox(pub gtk::Box);
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||
unsafe impl Send for GtkBox {}
|
||||
@@ -1309,20 +1332,26 @@ pub enum WindowMessage {
|
||||
PrimaryMonitor(Sender<Option<MonitorHandle>>),
|
||||
MonitorFromPoint(Sender<Option<MonitorHandle>>, (f64, f64)),
|
||||
AvailableMonitors(Sender<Vec<MonitorHandle>>),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
GtkWindow(Sender<GtkWindow>),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
GtkBox(Sender<GtkBox>),
|
||||
RawWindowHandle(Sender<std::result::Result<SendRawWindowHandle, raw_window_handle::HandleError>>),
|
||||
@@ -1964,23 +1993,29 @@ impl<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
|
||||
window_getter!(self, WindowMessage::IsAlwaysOnTop)
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn gtk_window(&self) -> Result<gtk::ApplicationWindow> {
|
||||
window_getter!(self, WindowMessage::GtkWindow).map(|w| w.0)
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn default_vbox(&self) -> Result<gtk::Box> {
|
||||
window_getter!(self, WindowMessage::GtkBox).map(|w| w.0)
|
||||
@@ -2742,12 +2777,20 @@ impl<T: UserEvent> Wry<T> {
|
||||
event_loop_builder.with_msg_hook(hook);
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(target_env = "ohos")]
|
||||
{
|
||||
event_loop_builder.with_openharmony_app(args.app);
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
if let Some(app_id) = args.app_id {
|
||||
use tao::platform::unix::EventLoopBuilderExtUnix;
|
||||
@@ -2799,12 +2842,15 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
fn new(args: RuntimeInitArgs) -> Result<Self> {
|
||||
Self::init_with_builder(EventLoopBuilder::<Message<T>>::with_user_event(), args)
|
||||
}
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn new_any_thread(args: RuntimeInitArgs) -> Result<Self> {
|
||||
use tao::platform::unix::EventLoopBuilderExtUnix;
|
||||
@@ -2821,6 +2867,11 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
|
||||
Self::init_with_builder(event_loop_builder, args)
|
||||
}
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
fn new_any_thread(args: RuntimeInitArgs) -> Result<Self> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn create_proxy(&self) -> EventProxy<T> {
|
||||
EventProxy(self.event_loop.create_proxy())
|
||||
}
|
||||
@@ -3264,20 +3315,26 @@ fn handle_user_message<T: UserEvent>(
|
||||
WindowMessage::AvailableMonitors(tx) => {
|
||||
tx.send(window.available_monitors().collect()).unwrap()
|
||||
}
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
WindowMessage::GtkWindow(tx) => tx.send(GtkWindow(window.gtk_window().clone())).unwrap(),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
WindowMessage::GtkBox(tx) => tx
|
||||
.send(GtkBox(window.default_vbox().unwrap().clone()))
|
||||
@@ -3401,7 +3458,7 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
#[allow(unused_variables)]
|
||||
WindowMessage::SetSkipTaskbar(skip) => {
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
#[cfg(all(any(windows, target_os = "linux"), not(target_env = "ohos")))]
|
||||
let _ = window.set_skip_taskbar(skip);
|
||||
}
|
||||
WindowMessage::SetCursorGrab(grab) => {
|
||||
@@ -3446,12 +3503,15 @@ fn handle_user_message<T: UserEvent>(
|
||||
#[cfg(target_os = "macos")]
|
||||
window.set_badge_label(_count.map(|x| x.to_string()));
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
window.set_badge_count(_count, _desktop_filename);
|
||||
}
|
||||
@@ -3504,14 +3564,17 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
}
|
||||
Message::Webview(window_id, webview_id, webview_message) => {
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "macos",
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
if let WebviewMessage::Reparent(new_parent_window_id, tx) = webview_message {
|
||||
let webview_handle = windows.0.borrow_mut().get_mut(&window_id).and_then(|w| {
|
||||
@@ -3536,12 +3599,15 @@ fn handle_user_message<T: UserEvent>(
|
||||
#[cfg(windows)]
|
||||
let reparent_result = { webview.inner.reparent(new_parent_window.hwnd()) };
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
let reparent_result = {
|
||||
if let Some(container) = new_parent_window.default_vbox() {
|
||||
@@ -3804,12 +3870,15 @@ fn handle_user_message<T: UserEvent>(
|
||||
}
|
||||
},
|
||||
WebviewMessage::WithWebview(f) => {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
f(webview.webview());
|
||||
@@ -4361,6 +4430,7 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_env = "ohos"))]
|
||||
if let Some(margin) = window_builder.prevent_overflow {
|
||||
let work_area = monitor.work_area();
|
||||
let margin = margin.to_physical::<u32>(scale_factor);
|
||||
@@ -4420,20 +4490,26 @@ fn create_window<T: UserEvent, F: Fn(RawWindow) + Send + 'static>(
|
||||
let raw = RawWindow {
|
||||
#[cfg(windows)]
|
||||
hwnd: window.hwnd(),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
gtk_window: window.gtk_window(),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
default_vbox: window.default_vbox(),
|
||||
_marker: &std::marker::PhantomData,
|
||||
@@ -4708,12 +4784,15 @@ You may have it installed on another user account, but it is not available for t
|
||||
wry::NewWindowResponse::Create {
|
||||
#[cfg(target_os = "macos")]
|
||||
webview: wry::WebViewExtMacOS::webview(&*webview).as_super().into(),
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
webview: webview.webview(),
|
||||
#[cfg(windows)]
|
||||
@@ -4838,13 +4917,16 @@ You may have it installed on another user account, but it is not available for t
|
||||
.with_browser_extensions_enabled(webview_attributes.browser_extensions_enabled);
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
if let Some(path) = &webview_attributes.extensions_path {
|
||||
@@ -4852,12 +4934,15 @@ You may have it installed on another user account, but it is not available for t
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
if let Some(related_view) = webview_attributes.related_view {
|
||||
@@ -4907,12 +4992,15 @@ You may have it installed on another user account, but it is not available for t
|
||||
for (scheme, protocol) in uri_scheme_protocols {
|
||||
// on Linux the custom protocols are associated with the web context
|
||||
// and you cannot register a scheme more than once
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
if web_context.registered_custom_protocols.contains(&scheme) {
|
||||
@@ -4959,7 +5047,8 @@ You may have it installed on another user account, but it is not available for t
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
target_os = "android",
|
||||
target_env = "ohos"
|
||||
)))]
|
||||
WebviewKind::WindowChild => {
|
||||
// only way to account for menu bar height, and also works for multiwebviews :)
|
||||
@@ -4970,7 +5059,8 @@ You may have it installed on another user account, but it is not available for t
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
target_os = "android",
|
||||
target_env = "ohos"
|
||||
))]
|
||||
WebviewKind::WindowChild => webview_builder.build_as_child(&window),
|
||||
WebviewKind::WindowContent => {
|
||||
@@ -4978,14 +5068,16 @@ You may have it installed on another user account, but it is not available for t
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
target_os = "android",
|
||||
target_env = "ohos"
|
||||
))]
|
||||
let builder = webview_builder.build(&window);
|
||||
#[cfg(not(any(
|
||||
target_os = "windows",
|
||||
target_os = "macos",
|
||||
target_os = "ios",
|
||||
target_os = "android"
|
||||
target_os = "android",
|
||||
target_env = "ohos"
|
||||
)))]
|
||||
let builder = {
|
||||
let vbox = window.default_vbox().unwrap();
|
||||
@@ -4997,12 +5089,15 @@ You may have it installed on another user account, but it is not available for t
|
||||
.map_err(|e| Error::CreateWebview(Box::new(e)))?;
|
||||
|
||||
if kind == WebviewKind::WindowContent {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
undecorated_resizing::attach_resize_handler(&webview);
|
||||
#[cfg(windows)]
|
||||
|
||||
@@ -4,12 +4,15 @@
|
||||
|
||||
use tauri_runtime::dpi::PhysicalRect;
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
mod linux;
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#![cfg(any(
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#![cfg(all(
|
||||
any(
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
|
||||
const CLIENT: isize = 0b0000;
|
||||
|
||||
@@ -2,17 +2,25 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
mod imp {
|
||||
pub type Webview = webkit2gtk::WebView;
|
||||
}
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
mod imp {
|
||||
pub type Webview = ();
|
||||
}
|
||||
|
||||
#[cfg(target_vendor = "apple")]
|
||||
mod imp {
|
||||
use std::ffi::c_void;
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use gtk::prelude::*;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
use tao::platform::unix::WindowExtUnix;
|
||||
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
mod linux;
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
@@ -44,13 +44,16 @@ features = ["Win32_Foundation", "Win32_System_WinRT"]
|
||||
[target."cfg(windows)".dependencies]
|
||||
webview2-com = "0.38"
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
[target.'cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"), not(target_env = "ohos")))'.dependencies]
|
||||
gtk = { version = "0.18", features = ["v3_24"] }
|
||||
webkit2gtk = { version = "=2.0", features = ["v2_40"] }
|
||||
|
||||
[target."cfg(target_os = \"android\")".dependencies]
|
||||
jni = "0.21"
|
||||
|
||||
[target.'cfg(target_env = "ohos")'.dependencies]
|
||||
openharmony-ability = { version = "0.2" }
|
||||
|
||||
[target.'cfg(all(target_vendor = "apple", not(target_os = "macos")))'.dependencies]
|
||||
objc2 = "0.6"
|
||||
objc2-ui-kit = { version = "0.3.0", default-features = false, features = [
|
||||
|
||||
@@ -13,7 +13,8 @@ fn alias(alias: &str, has_feature: bool) {
|
||||
|
||||
fn main() {
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
||||
let mobile = target_os == "ios" || target_os == "android" || target_env == "ohos";
|
||||
alias("desktop", !mobile);
|
||||
alias("mobile", mobile);
|
||||
}
|
||||
|
||||
@@ -375,18 +375,22 @@ pub trait EventLoopProxy<T: UserEvent>: Debug + Clone + Send + Sync {
|
||||
fn send_event(&self, event: T) -> Result<()>;
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RuntimeInitArgs {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub app_id: Option<String>,
|
||||
#[cfg(windows)]
|
||||
pub msg_hook: Option<Box<dyn FnMut(*const std::ffi::c_void) -> bool + 'static>>,
|
||||
#[cfg(target_env = "ohos")]
|
||||
pub app: openharmony_ability::OpenHarmonyApp,
|
||||
}
|
||||
|
||||
/// The webview runtime interface.
|
||||
@@ -716,22 +720,28 @@ pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 's
|
||||
fn available_monitors(&self) -> Result<Vec<Monitor>>;
|
||||
|
||||
/// Returns the `ApplicationWindow` from gtk crate that is used by this window.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn gtk_window(&self) -> Result<gtk::ApplicationWindow>;
|
||||
|
||||
/// Returns the vertical [`gtk::Box`] that is added by default as the sole child of this window.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn default_vbox(&self) -> Result<gtk::Box>;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
//! A layer between raw [`Runtime`] webviews and Tauri.
|
||||
//!
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
|
||||
use crate::window::WindowId;
|
||||
use crate::{window::is_label_valid, Rect, Runtime, UserEvent};
|
||||
|
||||
@@ -90,12 +90,15 @@ pub struct NewWindowOpener {
|
||||
/// The instance of the webview that initiated the new window request.
|
||||
///
|
||||
/// This must be set as the related view of the new webview. See [`WebviewAttributes::related_view`].
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub webview: webkit2gtk::WebView,
|
||||
/// The instance of the webview that initiated the new window request.
|
||||
@@ -164,7 +167,7 @@ pub enum NewWindowResponse {
|
||||
///
|
||||
/// **Linux**: The webview must be related to the caller webview. See [`WebviewAttributes::related_view`].
|
||||
/// **Windows**: The webview must use the same environment as the caller webview. See [`WebviewAttributes::environment`].
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios", target_env = "ohos")))]
|
||||
Create { window_id: WindowId },
|
||||
/// Deny the window from being opened.
|
||||
Deny,
|
||||
@@ -361,12 +364,15 @@ pub struct WebviewAttributes {
|
||||
|
||||
/// Creates a new webview sharing the same web process with the provided webview.
|
||||
/// Useful if you need to link a webview to another, for instance when using the [`PendingWebview::new_window_handler`].
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub related_view: Option<webkit2gtk::WebView>,
|
||||
|
||||
@@ -482,12 +488,15 @@ impl WebviewAttributes {
|
||||
input_accessory_view_builder: None,
|
||||
#[cfg(windows)]
|
||||
environment: None,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
related_view: None,
|
||||
#[cfg(target_os = "macos")]
|
||||
|
||||
@@ -425,12 +425,15 @@ pub trait WindowBuilder: WindowBuilderBase {
|
||||
/// Sets the window to be created transient for parent.
|
||||
///
|
||||
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn transient_for(self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self;
|
||||
|
||||
@@ -601,20 +604,26 @@ impl<T: UserEvent, R: Runtime<T>> PartialEq for DetachedWindow<T, R> {
|
||||
pub struct RawWindow<'a> {
|
||||
#[cfg(windows)]
|
||||
pub hwnd: isize,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub gtk_window: &'a gtk::ApplicationWindow,
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub default_vbox: Option<&'a gtk::Box>,
|
||||
pub _marker: &'a PhantomData<()>,
|
||||
|
||||
@@ -227,6 +227,13 @@
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "OpenHarmony.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"openHarmony"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1578,6 +1578,13 @@
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "OpenHarmony.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"openHarmony"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -198,6 +198,13 @@
|
||||
"enum": [
|
||||
"iOS"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "OpenHarmony.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"openHarmony"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ impl ConfigFormat {
|
||||
Target::Linux => "tauri.linux.conf.json",
|
||||
Target::Android => "tauri.android.conf.json",
|
||||
Target::Ios => "tauri.ios.conf.json",
|
||||
Target::OpenHarmony => "tauri.ohos.conf.json",
|
||||
},
|
||||
Self::Json5 => match target {
|
||||
Target::MacOS => "tauri.macos.conf.json5",
|
||||
@@ -63,6 +64,7 @@ impl ConfigFormat {
|
||||
Target::Linux => "tauri.linux.conf.json5",
|
||||
Target::Android => "tauri.android.conf.json5",
|
||||
Target::Ios => "tauri.ios.conf.json5",
|
||||
Target::OpenHarmony => "tauri.ohos.conf.json5",
|
||||
},
|
||||
Self::Toml => match target {
|
||||
Target::MacOS => "Tauri.macos.toml",
|
||||
@@ -70,6 +72,7 @@ impl ConfigFormat {
|
||||
Target::Linux => "Tauri.linux.toml",
|
||||
Target::Android => "Tauri.android.toml",
|
||||
Target::Ios => "Tauri.ios.toml",
|
||||
Target::OpenHarmony => "Tauri.ohos.toml",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -172,6 +175,7 @@ pub fn is_configuration_file(target: Target, path: &Path) -> bool {
|
||||
/// - `tauri.windows.conf.json[5]` or `Tauri.windows.toml` on Windows
|
||||
/// - `tauri.android.conf.json[5]` or `Tauri.android.toml` on Android
|
||||
/// - `tauri.ios.conf.json[5]` or `Tauri.ios.toml` on iOS
|
||||
/// - `tauri.ohos.conf.json[5]` or `Tauri.ohos.toml` on OpenHarmony
|
||||
/// Merging the configurations using [JSON Merge Patch (RFC 7396)].
|
||||
///
|
||||
/// Returns the raw configuration and used config paths.
|
||||
|
||||
@@ -270,10 +270,10 @@ impl Display for Theme {
|
||||
#[non_exhaustive]
|
||||
pub struct Env {
|
||||
/// The APPIMAGE environment variable.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
pub appimage: Option<std::ffi::OsString>,
|
||||
/// The APPDIR environment variable.
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
pub appdir: Option<std::ffi::OsString>,
|
||||
/// The command line arguments of the current process.
|
||||
pub args_os: Vec<OsString>,
|
||||
@@ -283,12 +283,12 @@ pub struct Env {
|
||||
impl Default for Env {
|
||||
fn default() -> Self {
|
||||
let args_os = std::env::args_os().collect();
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
{
|
||||
let env = Self {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
appimage: std::env::var_os("APPIMAGE"),
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
appdir: std::env::var_os("APPDIR"),
|
||||
args_os,
|
||||
};
|
||||
@@ -311,7 +311,7 @@ impl Default for Env {
|
||||
}
|
||||
env
|
||||
}
|
||||
#[cfg(not(target_os = "linux"))]
|
||||
#[cfg(any(target_env = "ohos", not(target_os = "linux")))]
|
||||
{
|
||||
Self { args_os }
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ pub enum Target {
|
||||
/// iOS.
|
||||
#[serde(rename = "iOS")]
|
||||
Ios,
|
||||
/// OpenHarmony.
|
||||
OpenHarmony,
|
||||
}
|
||||
|
||||
impl Display for Target {
|
||||
@@ -50,6 +52,7 @@ impl Display for Target {
|
||||
Self::Linux => "linux",
|
||||
Self::Android => "android",
|
||||
Self::Ios => "iOS",
|
||||
Self::OpenHarmony => "open-harmony",
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -308,7 +311,7 @@ fn resource_dir_from<P: AsRef<std::path::Path>>(
|
||||
#[allow(unused_mut, unused_assignments)]
|
||||
let mut res = Err(crate::Error::UnsupportedPlatform);
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
{
|
||||
// (canonicalize checks for existence, so there's no need for an extra check)
|
||||
res = if let Ok(bundle_dir) = exe_dir
|
||||
@@ -393,6 +396,7 @@ mod build {
|
||||
Self::Windows => quote! { #prefix::Windows },
|
||||
Self::Android => quote! { #prefix::Android },
|
||||
Self::Ios => quote! { #prefix::Ios },
|
||||
Self::OpenHarmony => quote! { #prefix::OpenHarmony },
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -432,7 +436,7 @@ mod tests {
|
||||
let resource_dir = super::resource_dir_from(&path, &package_info, &env);
|
||||
#[cfg(target_os = "macos")]
|
||||
assert!(resource_dir.is_err());
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
assert_eq!(resource_dir.unwrap(), PathBuf::from("/usr/lib/MyApp"));
|
||||
#[cfg(windows)]
|
||||
assert_eq!(resource_dir.unwrap(), path.parent().unwrap());
|
||||
|
||||
@@ -87,7 +87,7 @@ specta = { version = "^2.0.0-rc.16", optional = true, default-features = false,
|
||||
cookie = "0.18"
|
||||
|
||||
# desktop
|
||||
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "windows", target_os = "macos"))'.dependencies]
|
||||
[target.'cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd", target_os = "windows", target_os = "macos"), not(target_env = "ohos")))'.dependencies]
|
||||
muda = { version = "0.17", default-features = false, features = [
|
||||
"serde",
|
||||
"gtk",
|
||||
@@ -97,7 +97,7 @@ tray-icon = { version = "0.21", default-features = false, features = [
|
||||
], optional = true }
|
||||
|
||||
# linux
|
||||
[target.'cfg(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"))'.dependencies]
|
||||
[target.'cfg(all(any(target_os = "linux", target_os = "dragonfly", target_os = "freebsd", target_os = "openbsd", target_os = "netbsd"), not(target_env = "ohos")))'.dependencies]
|
||||
gtk = { version = "0.18", features = ["v3_24"] }
|
||||
webkit2gtk = { version = "=2.0.1", features = ["v2_40"], optional = true }
|
||||
|
||||
@@ -141,7 +141,7 @@ windows = { version = "0.61", features = [
|
||||
] }
|
||||
|
||||
# mobile
|
||||
[target.'cfg(any(target_os = "android", all(target_vendor = "apple", not(target_os = "macos"))))'.dependencies]
|
||||
[target.'cfg(any(target_os = "android", target_env = "ohos", all(target_vendor = "apple", not(target_os = "macos"))))'.dependencies]
|
||||
bytes = { version = "1", features = ["serde"] }
|
||||
reqwest = { version = "0.12", default-features = false, features = [
|
||||
"json",
|
||||
@@ -149,6 +149,11 @@ reqwest = { version = "0.12", default-features = false, features = [
|
||||
|
||||
] }
|
||||
|
||||
[target.'cfg(target_env = "ohos")'.dependencies]
|
||||
openharmony-ability = { version = "0.2" }
|
||||
openharmony-ability-derive = { version = "0.2" }
|
||||
|
||||
|
||||
# android
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
jni = "0.21"
|
||||
|
||||
@@ -255,7 +255,8 @@ fn main() {
|
||||
println!("cargo:dev={dev}");
|
||||
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let mobile = target_os == "ios" || target_os == "android";
|
||||
let target_env = std::env::var("CARGO_CFG_TARGET_ENV").unwrap_or_default();
|
||||
let mobile = target_os == "ios" || target_os == "android" || target_env == "ohos";
|
||||
alias("desktop", !mobile);
|
||||
alias("mobile", mobile);
|
||||
|
||||
|
||||
@@ -2121,12 +2121,15 @@ tauri::Builder::default()
|
||||
self.invoke_key,
|
||||
));
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
let app_id = if manager.config.app.enable_gtk_app_id {
|
||||
Some(manager.config.identifier.clone())
|
||||
@@ -2135,12 +2138,15 @@ tauri::Builder::default()
|
||||
};
|
||||
|
||||
let runtime_args = RuntimeInitArgs {
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
app_id,
|
||||
|
||||
@@ -2163,6 +2169,13 @@ tauri::Builder::default()
|
||||
}
|
||||
}))
|
||||
},
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
app: crate::ohos::APP
|
||||
.lock()
|
||||
.unwrap()
|
||||
.take()
|
||||
.expect("OpenHarmony app instance not initialized"),
|
||||
};
|
||||
|
||||
#[cfg(any(windows, target_os = "linux"))]
|
||||
|
||||
@@ -83,6 +83,9 @@ pub use url::Url;
|
||||
|
||||
pub(crate) mod app;
|
||||
pub mod async_runtime;
|
||||
#[doc(hidden)]
|
||||
#[cfg(target_env = "ohos")]
|
||||
pub mod ohos;
|
||||
mod error;
|
||||
mod event;
|
||||
pub mod ipc;
|
||||
|
||||
@@ -56,12 +56,15 @@ impl<R: Runtime> ContextMenuBase for Menu<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
if let Ok(w) = window.gtk_window() {
|
||||
self_
|
||||
|
||||
@@ -49,12 +49,15 @@ impl<R: Runtime> ContextMenuBase for Submenu<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
if let Ok(w) = window.gtk_window() {
|
||||
self_
|
||||
|
||||
6
crates/tauri/src/ohos.rs
Normal file
6
crates/tauri/src/ohos.rs
Normal file
@@ -0,0 +1,6 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
pub use openharmony_ability;
|
||||
pub use openharmony_ability_derive;
|
||||
|
||||
pub static APP: Mutex<Option<openharmony_ability::OpenHarmonyApp>> = Mutex::new(None);
|
||||
@@ -342,6 +342,17 @@ impl<R: Runtime> PluginHandle<R> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_env = "ohos")]
|
||||
pub(crate) fn run_command<R: Runtime, C: AsRef<str>, F: FnOnce(PluginResponse) + Send + 'static>(
|
||||
_name: &str,
|
||||
_handle: &AppHandle<R>,
|
||||
_command: C,
|
||||
_payload: serde_json::Value,
|
||||
_handler: F,
|
||||
) -> Result<(), PluginInvokeError> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
pub(crate) fn run_command<R: Runtime, C: AsRef<str>, F: FnOnce(PluginResponse) + Send + 'static>(
|
||||
name: &str,
|
||||
|
||||
@@ -47,7 +47,7 @@ use std::path::PathBuf;
|
||||
/// [AppImage]: https://appimage.org/
|
||||
pub fn current_binary(_env: &Env) -> std::io::Result<PathBuf> {
|
||||
// if we are running from an AppImage, we ONLY want the set AppImage path
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
if let Some(app_image_path) = &_env.appimage {
|
||||
return Ok(PathBuf::from(app_image_path));
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ impl<T: UserEvent> RuntimeHandle<T> for MockRuntimeHandle {
|
||||
fn display_handle(
|
||||
&self,
|
||||
) -> std::result::Result<raw_window_handle::DisplayHandle<'_>, raw_window_handle::HandleError> {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
return Ok(unsafe {
|
||||
raw_window_handle::DisplayHandle::borrow_raw(raw_window_handle::RawDisplayHandle::Xlib(
|
||||
raw_window_handle::XlibDisplayHandle::new(None, 0),
|
||||
@@ -483,12 +483,15 @@ impl WindowBuilder for MockWindowBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn transient_for(self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
|
||||
self
|
||||
@@ -774,23 +777,29 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
|
||||
Ok(Theme::Light)
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn gtk_window(&self) -> Result<gtk::ApplicationWindow> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
fn default_vbox(&self) -> Result<gtk::Box> {
|
||||
unimplemented!()
|
||||
@@ -799,7 +808,7 @@ impl<T: UserEvent> WindowDispatch<T> for MockWindowDispatcher {
|
||||
fn window_handle(
|
||||
&self,
|
||||
) -> std::result::Result<raw_window_handle::WindowHandle<'_>, raw_window_handle::HandleError> {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
return unsafe {
|
||||
Ok(raw_window_handle::WindowHandle::borrow_raw(
|
||||
raw_window_handle::RawWindowHandle::Xlib(raw_window_handle::XlibWindowHandle::new(0)),
|
||||
|
||||
@@ -562,7 +562,7 @@ impl<R: Runtime> TrayIcon<R> {
|
||||
pub fn set_temp_dir_path<P: AsRef<Path>>(&self, path: Option<P>) -> crate::Result<()> {
|
||||
#[allow(unused)]
|
||||
let p = path.map(|p| p.as_ref().to_path_buf());
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
run_item_main_thread!(self, |self_: Self| self_.inner.set_temp_dir_path(p))?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -153,12 +153,15 @@ pub struct PlatformWebview(tauri_runtime_wry::Webview);
|
||||
#[cfg(feature = "wry")]
|
||||
impl PlatformWebview {
|
||||
/// Returns [`webkit2gtk::WebView`] handle.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
#[cfg_attr(
|
||||
docsrs,
|
||||
@@ -1195,7 +1198,8 @@ fn main() {
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
)
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn with_related_view(mut self, related_view: webkit2gtk::WebView) -> Self {
|
||||
self.webview_attributes.related_view.replace(related_view);
|
||||
@@ -1548,7 +1552,7 @@ tauri::Builder::default()
|
||||
.setup(|app| {
|
||||
let main_webview = app.get_webview("main").unwrap();
|
||||
main_webview.with_webview(|webview| {
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
{
|
||||
// see <https://docs.rs/webkit2gtk/2.0.0/webkit2gtk/struct.WebView.html>
|
||||
// and <https://docs.rs/webkit2gtk/2.0.0/webkit2gtk/trait.WebViewExt.html>
|
||||
|
||||
@@ -788,12 +788,15 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
|
||||
/// Sets the window to be created transient for parent.
|
||||
///
|
||||
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn transient_for(mut self, parent: &WebviewWindow<R>) -> crate::Result<Self> {
|
||||
self.window_builder = self.window_builder.transient_for(&parent.window)?;
|
||||
@@ -803,12 +806,15 @@ impl<'a, R: Runtime, M: Manager<R>> WebviewWindowBuilder<'a, R, M> {
|
||||
/// Sets the window to be created transient for parent.
|
||||
///
|
||||
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
#[must_use]
|
||||
pub fn transient_for_raw(mut self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
|
||||
@@ -1284,7 +1290,8 @@ impl<R: Runtime, M: Manager<R>> WebviewWindowBuilder<'_, R, M> {
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
)
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn with_related_view(mut self, related_view: webkit2gtk::WebView) -> Self {
|
||||
self.webview_builder = self.webview_builder.with_related_view(related_view);
|
||||
@@ -1306,14 +1313,17 @@ impl<R: Runtime, M: Manager<R>> WebviewWindowBuilder<'_, R, M> {
|
||||
|
||||
/// Set the window features.
|
||||
/// Useful if you need to share the same window features, for instance when using the [`Self::on_new_window`].
|
||||
#[cfg(any(
|
||||
target_os = "macos",
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "macos",
|
||||
windows,
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn window_features(mut self, features: NewWindowFeatures) -> Self {
|
||||
if let Some(position) = features.position() {
|
||||
@@ -1346,7 +1356,8 @@ impl<R: Runtime, M: Manager<R>> WebviewWindowBuilder<'_, R, M> {
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
)
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
self.webview_builder = self
|
||||
@@ -1761,12 +1772,15 @@ impl<R: Runtime> WebviewWindow<R> {
|
||||
/// Returns the `ApplicationWindow` from gtk crate that is used by this window.
|
||||
///
|
||||
/// Note that this type can only be used on the main thread.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn gtk_window(&self) -> crate::Result<gtk::ApplicationWindow> {
|
||||
self.window.gtk_window()
|
||||
@@ -1775,12 +1789,15 @@ impl<R: Runtime> WebviewWindow<R> {
|
||||
/// Returns the vertical [`gtk::Box`] that is added by default as the sole child of this window.
|
||||
///
|
||||
/// Note that this type can only be used on the main thread.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn default_vbox(&self) -> crate::Result<gtk::Box> {
|
||||
self.window.default_vbox()
|
||||
@@ -2214,7 +2231,7 @@ impl<R: Runtime> WebviewWindow<R> {
|
||||
/// .setup(|app| {
|
||||
/// let main_webview = app.get_webview_window("main").unwrap();
|
||||
/// main_webview.with_webview(|webview| {
|
||||
/// #[cfg(target_os = "linux")]
|
||||
/// #[cfg(all(target_os = "linux", not(target_env = "ohos")))]
|
||||
/// {
|
||||
/// // see <https://docs.rs/webkit2gtk/2.0.0/webkit2gtk/struct.WebView.html>
|
||||
/// // and <https://docs.rs/webkit2gtk/2.0.0/webkit2gtk/trait.WebViewExt.html>
|
||||
|
||||
@@ -730,12 +730,15 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
|
||||
self.window_builder = self.window_builder.owner(parent.hwnd()?);
|
||||
}
|
||||
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
{
|
||||
self.window_builder = self.window_builder.transient_for(&parent.gtk_window()?);
|
||||
@@ -811,12 +814,15 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
|
||||
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
|
||||
///
|
||||
/// **Note:** This is a low level API. See [`Self::parent`] for a higher level wrapper for Tauri windows.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn transient_for(mut self, parent: &Window<R>) -> crate::Result<Self> {
|
||||
self.window_builder = self.window_builder.transient_for(&parent.gtk_window()?);
|
||||
@@ -828,12 +834,15 @@ impl<'a, R: Runtime, M: Manager<R>> WindowBuilder<'a, R, M> {
|
||||
/// See <https://docs.gtk.org/gtk3/method.Window.set_transient_for.html>
|
||||
///
|
||||
/// **Note:** This is a low level API. See [`Self::parent`] and [`Self::transient_for`] for higher level wrappers for Tauri windows.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
#[must_use]
|
||||
pub fn transient_for_raw(mut self, parent: &impl gtk::glib::IsA<gtk::Window>) -> Self {
|
||||
@@ -1213,12 +1222,15 @@ tauri::Builder::default()
|
||||
|
||||
let _ = unsafe { menu_.inner().init_for_hwnd_with_theme(hwnd.0 as _, theme) };
|
||||
}
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
if let (Ok(gtk_window), Ok(gtk_box)) = (window.gtk_window(), window.default_vbox()) {
|
||||
let _ = menu_
|
||||
@@ -1594,12 +1606,15 @@ impl<R: Runtime> Window<R> {
|
||||
/// Returns the `ApplicationWindow` from gtk crate that is used by this window.
|
||||
///
|
||||
/// Note that this type can only be used on the main thread.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn gtk_window(&self) -> crate::Result<gtk::ApplicationWindow> {
|
||||
self.window.dispatcher.gtk_window().map_err(Into::into)
|
||||
@@ -1608,12 +1623,15 @@ impl<R: Runtime> Window<R> {
|
||||
/// Returns the vertical [`gtk::Box`] that is added by default as the sole child of this window.
|
||||
///
|
||||
/// Note that this type can only be used on the main thread.
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
#[cfg(all(
|
||||
any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd",
|
||||
),
|
||||
not(target_env = "ohos")
|
||||
))]
|
||||
pub fn default_vbox(&self) -> crate::Result<gtk::Box> {
|
||||
self.window.dispatcher.default_vbox().map_err(Into::into)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user