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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions .claude/skills/ohos-build/scripts/build-ohos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ source "$SCRIPT_DIR/env.sh"
API_DIR="$PROJECT_ROOT/examples/api"
SRC_TAURI="$API_DIR/src-tauri"
OHOS_PROJECT="$SRC_TAURI/gen/ohos"
# PR #59: entry module is now entry_desktop or entry_mobile based on OHOS_DEVICE_TYPE
ENTRY_MODULE="entry_${OHOS_DEVICE_TYPE:-desktop}"
SIGNED_HAP="$OHOS_PROJECT/${ENTRY_MODULE}/build/default/outputs/default/${ENTRY_MODULE}-default-signed.hap"
if [ "$OHOS_DEVICE_TYPE" = "desktop" ]; then
ENTRY_DIR="entry_desktop"
else
ENTRY_DIR="entry_mobile"
fi
SIGNED_HAP="$OHOS_PROJECT/$ENTRY_DIR/build/default/outputs/default/$ENTRY_DIR-default-signed.hap"
SO_FILE="$PROJECT_ROOT/target/aarch64-unknown-linux-ohos/release/libapi_lib.so"
HVIGORFILE="$OHOS_PROJECT/${ENTRY_MODULE}/hvigorfile.ts"
HVIGORFILE="$OHOS_PROJECT/$ENTRY_DIR/hvigorfile.ts"

echo "=== Tauri OpenHarmony Build ==="
echo "DEVECO_HOME=$DEVECO_HOME"
Expand All @@ -24,7 +27,7 @@ echo ""

# ─── Step 0: Detect template changes and re-run `tauri ohos init` ───
TEMPLATE_DIR="$PROJECT_ROOT/crates/tauri-cli/templates/mobile/open-harmony"
ENTRY_ETS="$OHOS_PROJECT/${ENTRY_MODULE}/src/main/ets/entryability/EntryAbility.ets"
ENTRY_ETS="$OHOS_PROJECT/$ENTRY_DIR/src/main/ets/entryability/EntryAbility.ets"
NEED_INIT=false

if [ ! -f "$ENTRY_ETS" ]; then
Expand Down Expand Up @@ -100,8 +103,8 @@ echo " Generated: $SO_FILE"
# ─── Step 5: 拷贝 .so 到 ohos 项目 ───
echo ""
echo ">>> Step 5: Copying .so to ohos project..."
mkdir -p "$OHOS_PROJECT/${ENTRY_MODULE}/libs/arm64-v8a"
cp "$SO_FILE" "$OHOS_PROJECT/${ENTRY_MODULE}/libs/arm64-v8a/libapi_lib.so"
mkdir -p "$OHOS_PROJECT/$ENTRY_DIR/libs/arm64-v8a"
cp "$SO_FILE" "$OHOS_PROJECT/$ENTRY_DIR/libs/arm64-v8a/libapi_lib.so"

# ─── Step 6: hvigorw 打包(自动禁用/恢复 tauriPlugin)───
echo ""
Expand All @@ -116,7 +119,7 @@ else
fi

rm -f "$SIGNED_HAP"
(cd "$OHOS_PROJECT" && hvigorw --no-daemon -p product=default -p module=${ENTRY_MODULE}@default assembleHap --analyze=normal --parallel --incremental) || HVIGOR_EXIT=$?
(cd "$OHOS_PROJECT" && hvigorw --no-daemon -p product=default -p module=$ENTRY_DIR@default assembleHap --analyze=normal --parallel --incremental) || HVIGOR_EXIT=$?
HVIGOR_EXIT=${HVIGOR_EXIT:-0}

# 恢复 tauriPlugin
Expand Down
7 changes: 6 additions & 1 deletion .claude/skills/ohos-build/scripts/sign-and-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/env.sh"

OHOS_PROJECT="$PROJECT_ROOT/examples/api/src-tauri/gen/ohos"
SIGNED_HAP="$OHOS_PROJECT/entry/build/default/outputs/default/entry-default-signed.hap"
if [ "$OHOS_DEVICE_TYPE" = "desktop" ]; then
ENTRY_DIR="entry_desktop"
else
ENTRY_DIR="entry_mobile"
fi
SIGNED_HAP="$OHOS_PROJECT/$ENTRY_DIR/build/default/outputs/default/$ENTRY_DIR-default-signed.hap"

# ─── 检查已签名 HAP ───
if [ ! -f "$SIGNED_HAP" ]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
| TSFN 回调必须返回 **参数元组**, 不是 `Result<()>` | 返回 `()` = 空 JS 参数 (全部 `undefined`)。返回 `FnArgs { data: (arg1, arg2) }` |
| **禁止** 使用 `callee_handled::<true>()` | napi-ohos 在 `CalleeHandled=true` 时自动在首位插入 `null`, 导致参数偏移。必须用 `callee_handled::<false>()` |
| 裸 tuple 类型会序列化为 JS Array | 必须用 `FnArgs<>` 包装 tuple, 否则 JS 函数收到数组而非展开参数 |
| **`Function::call` 也有同样 bug** | `func.call((arg1, arg2))` 裸 tuple 走通用 impl 只传 1 个参数。必须 `Function<'_, FnArgs<(T1,T2)>, R>` + `func.call(FnArgs { data: (arg1, arg2) })`。p1-window-vibrancy 的 set_window_blur 因此从未工作过 |
| TSFN 数据必须通过泛型参数携带, 不是全局 Mutex | 全局 `Mutex<Option<Data>>` 中转模式在快速连续调用时产生数据竞态, 导致 freeze。每个 TSFN 调用独立 Box 入队, 天然隔离 |

### 2.3 NAPI 上下文限制
Expand All @@ -70,6 +71,7 @@
| `statusBarManager.on()` 必须在 `addToStatusBar` 之后 200ms 注册 | OHOS 内部 `ScbServerReceiver` 在 `addToStatusBar` 后异步初始化。提前注册的 handler 被静默丢弃 |
| NAPI `Env` 只在获取它的线程有效 | `MAIN_THREAD_ENV` 存储在 `thread_local!` 中, 其他线程调用 `get_main_thread_env()` 返回 `None` |
| `ObjectRef` (napi_ref) 不是 Send/Sync | 必须通过 `Mutex<SendableHelper>` + `ptr::read` 跨线程共享, `unsafe impl Send/Sync` |
| **hilog 在 NAPI 回调上下文抛 Argc mismatch** | 被 Rust NAPI `func.call` 调的 ArkTS 函数内部用 `hilog.info`/`hilog.error` 会抛 `"assertion (false) failed: Argc mismatch"`(疑 NAPI 重入限制)。异常被 catch 吞成 `failed: {}`。被 NAPI 调的函数内部禁用 hilog;纯 ArkTS 调用链(如 registerController)里 hilog 正常 |

---

Expand Down Expand Up @@ -122,6 +124,7 @@
| 模块级 `@Builder function` 没有 `this` 上下文 | 全局 `@Builder` 无法访问组件实例属性和方法。只有 `@Component` 内的 `private @Builder` 方法才有 `this` |
| 递归 `@Builder`(如子菜单渲染)必须在 `@Component` 内 | 模块级 `@Builder` 调用其他 `@Builder` 时, `this` 为 `undefined`, 导致 `TypeError`。这是 menu Phase 4→6→9 三次方案演进的根本原因 |
| WebView 事件必须在 `@Builder` 内 pre-build 注册 | ArkUI 约束: 事件回调不能在 `@Builder` 外部动态绑定。所有 `onLoadIntercept`、`onPageBegin` 等必须在构建时注册 |
| **`BuilderNode.update` 不刷新组件属性** | `.backdropBlur(data.style.blurRadius)` 等属性在 update 时不重新求值。build 时通过 `addWebview` 注入值;**运行时刷新用 `AttributeUpdater`**:`modifier.attribute?.backdropBlur(radius)` 立即触发组件更新(不需 @State, 适合 @Builder/BuilderNode)。vibrancy BlurModifier 用此机制刷新 backdropBlur/backgroundColor |

### 4.2 语义反转

Expand Down
165 changes: 83 additions & 82 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,82 +1,83 @@
[workspace]
members = [
"crates/tauri",
"crates/tauri-runtime",
"crates/tauri-runtime-wry",
"crates/tauri-macros",
"crates/tauri-utils",
"crates/tauri-build",
"crates/tauri-codegen",
"crates/tauri-plugin",
"crates/tauri-schema-generator",
"crates/tauri-schema-worker",
"crates/tauri-cli",
"crates/tauri-bundler",
"crates/tauri-macos-sign",
"crates/tauri-driver",

# @tauri-apps/cli rust project
"packages/cli",

# integration tests
"crates/tests/restart",
"crates/tests/acl",

# bench
"bench",
"bench/tests/cpu_intensive/src-tauri",
"bench/tests/files_transfer/src-tauri",
"bench/tests/helloworld/src-tauri",

# examples
"examples/file-associations/src-tauri",
"examples/resources/src-tauri",
"examples/api/src-tauri",
"examples/api/src-tauri/tauri-plugin-sample",
]
resolver = "2"

[workspace.package]
authors = ["Tauri Programme within The Commons Conservancy"]
homepage = "https://tauri.app/"
repository = "https://github.com/tauri-apps/tauri"
categories = ["gui", "web-programming"]
license = "Apache-2.0 OR MIT"
edition = "2021"
rust-version = "1.77.2"

# default to small, optimized workspace release binaries
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
incremental = false
opt-level = "s"
strip = true

# profiles for tauri-cli
[profile.dev.package.miniz_oxide]
opt-level = 3

[profile.release-size-optimized]
inherits = "release"
codegen-units = 1
lto = true
incremental = false
opt-level = "s"

# Temporary patch to schemars to preserve newlines in docstrings for our reference docs schemas
# See https://github.com/GREsau/schemars/issues/120 for reference
[patch.crates-io]
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" }
tauri-utils = { path = "./crates/tauri-utils" }
cargo-mobile2 = { path = "../cargo-mobile2", default-features = false }
wry = { path = "../wry" }
#tao = { git = "https://github.com/richerfu/tao", branch = "feat-ohos-webview" }
tao = { path = "../tao" }
muda = { path = "../muda" }
tray-icon = { path = "../tray-icon" }
openharmony-ability = { path = "../openharmony-ability/crates/ability" }
openharmony-ability-derive = { path = "../openharmony-ability/crates/derive" }
[workspace]
members = [
"crates/tauri",
"crates/tauri-runtime",
"crates/tauri-runtime-wry",
"crates/tauri-macros",
"crates/tauri-utils",
"crates/tauri-build",
"crates/tauri-codegen",
"crates/tauri-plugin",
"crates/tauri-schema-generator",
"crates/tauri-schema-worker",
"crates/tauri-cli",
"crates/tauri-bundler",
"crates/tauri-macos-sign",
"crates/tauri-driver",

# @tauri-apps/cli rust project
"packages/cli",

# integration tests
"crates/tests/restart",
"crates/tests/acl",

# bench
"bench",
"bench/tests/cpu_intensive/src-tauri",
"bench/tests/files_transfer/src-tauri",
"bench/tests/helloworld/src-tauri",

# examples
"examples/file-associations/src-tauri",
"examples/resources/src-tauri",
"examples/api/src-tauri",
"examples/api/src-tauri/tauri-plugin-sample",
]
resolver = "2"

[workspace.package]
authors = ["Tauri Programme within The Commons Conservancy"]
homepage = "https://tauri.app/"
repository = "https://github.com/tauri-apps/tauri"
categories = ["gui", "web-programming"]
license = "Apache-2.0 OR MIT"
edition = "2021"
rust-version = "1.77.2"

# default to small, optimized workspace release binaries
[profile.release]
panic = "abort"
codegen-units = 1
lto = true
incremental = false
opt-level = "s"
strip = true

# profiles for tauri-cli
[profile.dev.package.miniz_oxide]
opt-level = 3

[profile.release-size-optimized]
inherits = "release"
codegen-units = 1
lto = true
incremental = false
opt-level = "s"

# Temporary patch to schemars to preserve newlines in docstrings for our reference docs schemas
# See https://github.com/GREsau/schemars/issues/120 for reference
[patch.crates-io]
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" }
tauri-utils = { path = "./crates/tauri-utils" }
cargo-mobile2 = { path = "../cargo-mobile2", default-features = false }
wry = { path = "../wry" }
#tao = { git = "https://github.com/richerfu/tao", branch = "feat-ohos-webview" }
tao = { path = "../tao" }
muda = { path = "../muda" }
tray-icon = { path = "../tray-icon" }
openharmony-ability = { path = "../openharmony-ability/crates/ability" }
openharmony-ability-derive = { path = "../openharmony-ability/crates/derive" }
window-vibrancy = { path = "../window-vibrancy" }
12 changes: 12 additions & 0 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1554,6 +1554,8 @@ pub enum WindowMessage {
DragWindow,
ResizeDragWindow(tauri_runtime::ResizeDirection),
RequestRedraw,
#[cfg(target_env = "ohos")]
OhosWindowId(Sender<Option<i64>>),
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -2705,6 +2707,11 @@ impl<T: UserEvent> WindowDispatch<T> for WryWindowDispatcher<T> {
Message::Window(self.window_id, WindowMessage::SetBackgroundColor(color)),
)
}

#[cfg(target_env = "ohos")]
fn ohos_window_id(&self) -> Result<Option<i64>> {
window_getter!(self, WindowMessage::OhosWindowId)
}
}

#[derive(Clone)]
Expand Down Expand Up @@ -3901,6 +3908,11 @@ fn handle_user_message<T: UserEvent>(
WindowMessage::SetBackgroundColor(color) => {
window.set_background_color(color.map(Into::into))
}
#[cfg(target_env = "ohos")]
WindowMessage::OhosWindowId(tx) => {
use tao::platform::ohos::WindowExtOpenHarmony;
let _ = tx.send(window.window_id());
}
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions crates/tauri-runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,6 +926,10 @@ pub trait WindowDispatch<T: UserEvent>: Debug + Clone + Send + Sync + Sized + 's
/// Set the window background.
fn set_background_color(&self, color: Option<Color>) -> Result<()>;

/// Returns the OHOS OS-level window ID (0 = main window, positive = sub-window).
#[cfg(target_env = "ohos")]
fn ohos_window_id(&self) -> Result<Option<i64>>;

/// Prevents the window contents from being captured by other apps.
fn set_content_protected(&self, protected: bool) -> Result<()>;

Expand Down
Loading
Loading