Skip to content

feat(ohos): ArkWeb surface-restore on resume + window-state/persisted-scope plugins - #67

Merged
Eulogizethesun merged 1 commit into
Eulogizethesun:ohdevfrom
ljy9812:ohdev
Jul 20, 2026
Merged

feat(ohos): ArkWeb surface-restore on resume + window-state/persisted-scope plugins#67
Eulogizethesun merged 1 commit into
Eulogizethesun:ohdevfrom
ljy9812:ohdev

Conversation

@ljy9812

@ljy9812 ljy9812 commented Jul 14, 2026

Copy link
Copy Markdown

Summary

Adds the OHOS window-state & persisted-scope plugin integration and the ArkWeb surface-restore fix, plus their related changes:

  • tauri-runtime-wry: reattach the ArkWeb surface on Event::Resumed via set_bounds (desktop minimize→restore no longer permanently loses bottom content). The handler is #[cfg(target_env = "ohos")] gated and uses a borrow-clone pattern (clone data out of the RefCell before calling set_bounds, mirroring the Resized handler).
  • examples/api: enable window-state and persisted-scope plugins + their test cases; add manual minimize/restore/window-state test buttons; remove a duplicate deep-link registration (upstream registers deep-link both all-platforms and in an OHOS-only block → double initialize() / duplicate onOpenUrl listeners).
  • openspec: add design docs (arkweb-surface-restore plan+change, ohos-window-ops plan+change).
  • doc/manual_tests.md: add Window Operations manual test cases.

Known limitation (1-cycle surface restore)

On the first minimize→restore, ArkWeb's render surface is recreated but the engine does not rebind/relayout, so the bottom content may still be cut off; a second minimize→restore cycle triggers a full surface rebind and recovers it. set_bounds (BuilderNode.update\)) only changes the ArkUI layout-tree size constraint — it does not force ArkWeb to rebind its render surface. A non-destructive 1-cycle fix requires an ArkWeb API that forces surface rebind (not yet available). Details in openspec/arkweb-surface-restore-plan.md`.

Test

  • OHOS desktop build + deploy: ✅ success (hvigor BUILD SUCCESSFUL, HAP signed/installed/launched).
  • Autotest: 243 pass / 2 fail (the 2 failures are pre-existing, unrelated to this change).
  • Windows cargo check -p tauri: ✅ passed (verifies the cfg(target_env = "ohos") isolation does not affect other platforms).

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Package Changes Through d579f1f

There are 11 changes which include tauri with minor, @tauri-apps/api with minor, tauri-build with minor, tauri-macos-sign with patch, tauri-bundler with minor, @tauri-apps/cli with minor, tauri-cli with minor, tauri-runtime with minor, tauri-runtime-wry with minor, tauri-utils with minor, tauri-plugin with minor

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
@tauri-apps/api 2.10.1 2.11.0
tauri-utils 2.8.3 2.9.0
tauri-macos-sign 2.3.3 2.3.4
tauri-bundler 2.8.1 2.9.0
tauri-runtime 2.10.1 2.11.0
tauri-runtime-wry 2.10.1 2.11.0
tauri-codegen 2.5.5 2.5.6
tauri-macros 2.5.5 2.5.6
tauri-plugin 2.5.4 2.6.0
tauri-build 2.5.6 2.6.0
tauri 2.10.3 2.11.0
@tauri-apps/cli 2.10.1 2.11.0
tauri-cli 2.10.1 2.11.0

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (ArkWeb surface-restore on resume + window-state/persisted-scope plugins)

🔴 🟡 🔵 ℹ️
0 1 1 0

🟡 F1 — ArkWeb surface-restore 特性部分失效,测试禁用(作者透明)

Event::Resumed → set_bounds 重 attach 是本 PR 主特性,但 core.ts 中 minimize/restore 测试被禁用,注释明说:set_bounds reattach on Event::Resumed does not recover [bottom content] once the layout is corrupted mid-suite,Suspected correlation with new-window/dialog operations,under manual investigation。即 minimize→restore 后 ArkWeb 底部内容仍消失,set_bounds 未完全修复(至少在测试套件上下文)。特性以已知未完全生效状态合入。

建议:定位 corruption 触发条件(是否与 dialog/new-window 操作相关)后再合入,或在 PR 描述/spec 明确标注已知限制 + 触发条件,避免误以为 surface-restore 已完全解决。作者已透明(禁用测试+注释),建议把该限制写入 design.md/spec.md。

🔵 F2 — openspec plan 文件散落 openspec/ 根(H8,第 4 次)

openspec/arkweb-surface-restore-plan.md 与 openspec/ohos-window-ops-plan.md 在 openspec/ 根,未归档到 openspec/changes/。H8 规范(已入 checklist)第 4 次出现(#62/#63/#64/#67)。建议移入 changes/ 或专门 plans/ 目录。

正面确认

  • H5✓:doc/manual_tests.md 新增 Window Operations + Persisted Scope 手动用例,统计更新(66/57/123)。
  • Event::Resumed handler 的 borrow 模式正确:先 clone 出 RefCell 数据再调 set_bounds,避免 NAPI 回调 re-entry 时持有不可变 borrow(镜像 Resized handler)。
  • 修复 deep-link 双注册:原在 line 105 无条件注册又在 OHOS 块重复注册(会 initialize() 两次→duplicate onOpenUrl/want listeners),现仅 line 105 注册。注释清晰。
  • 跨 PR:依赖 oa#40 的 window NAPI + tao#16 的 Event::Resumed。合并顺序:oa#40 + tao#16 先于/同批本 PR。

*F1 是主要关注点(特性部分失效),建议补限制文档或定位后再合入。F2 非阻塞归档规范。

@ljy9812 ljy9812 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67

🔴 🟡 🔵 ℹ️
0 1 0 0

🟡 F1: openspec spec.md contradicts implementation — set_maximized(false) is NOT a no-op

The p1-ohos-window-ops/specs/ohos-window-ops/spec.md contains this scenario:

Scenario: unmaximize via set_maximized(false) is a no-op (no public API)

  • WHEN set_maximized(false) is called on a maximized window
  • THEN it is a no-op + log::warn on all API versions (OHOS has no public unmaximize API; restore is minimize-only)

But the actual tao#16 implementation uses recover_window()win.recover() (API7+, public, switches MAXIMIZE/FULL_SCREEN → FLOATING). The design.md D4 also incorrectly states "无公共 unmaximize API(所有 API 版本)".

win.recover() IS a public unmaximize API. The implementation is correct; the spec and design docs are wrong. They must be updated to:

  • Replace the "no-op + log::warn" scenario with a "recover() unmaximizes" scenario
  • Update D4 to document recover() as the unmaximize API (API7+, public)
  • Remove the "无公共 unmaximize API" limitation note

Note: manual_tests.md already correctly says "unmaximize 由 set_maximized(false) → recover() 恢复" and the test name says "window.unmaximize (recover) then is_maximized reflects state" — so only the openspec docs are inconsistent.

Other checks — all pass

  • A1/B1 (cfg isolation): Event::Resumed match arm is #[cfg(target_env = "ohos")] gated. Non-OHOS builds unaffected. ✅
  • D1/D2 (thread model): No blocking patterns. Borrow pattern correctly clones data out of RefCell before calling set_bounds (mirrors Resized handler). ✅
  • G2 (error handling): Mutex::lock().unwrap() is allowed per G2. set_bounds errors are logged with log::warn!. ✅
  • G4 (cross-repo API consistency): All window ops in tao#16 call functions exported by ability#40 with matching signatures. ✅
  • H1 (no junk files): No Cargo.lock, .har, build artifacts. ✅
  • H5 (manual_tests.md): New "Window Operations" section with T0 cases, statistics updated (62→66 T0, 119→123 total). ✅
  • H6 (openspec): Both changes (p1-arkweb-surface-restore, p1-ohos-window-ops) archived in openspec/changes/. ✅
  • H7 (English comments): All code comments in English. Chinese only in openspec docs (documentation, not code comments). ✅
  • Known limitation (2-cycle restore): Documented in spec.md, design.md, plan.md, and PR body. Not treated as a bug. ✅
  • deep-link double-registration fix: Correctly removes the OHOS-specific tauri_plugin_deep_link::init() re-registration. Comment explains the duplicate listener issue. ✅

Comment thread openspec/changes/p1-ohos-window-ops/specs/ohos-window-ops/spec.md Outdated
@ljy9812
ljy9812 force-pushed the ohdev branch 5 times, most recently from d7406fd to bd17c1e Compare July 14, 2026 12:19

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (re-review 2026-07-14)

🔴 🟡 🔵 ℹ️
0 0 1 0

✅ F1(上轮 🟡 surface-restore 部分失效)已解决 — 根因 pivot

作者放弃了不完整的 surface-restore 方案(Event::Resumed → set_bounds reattach),改为根因修复:

  • tauri-runtime-wry 的 Event::Resumed → set_bounds handler 已移除(lib.rs 中该 match arm 不再存在)。
  • design.md 明确记录:set_bounds/BuilderNode.update 反而干扰 ArkWeb 自然 rebind,导致 2-cycle 底部缺失;minimize→restore 本不需要 Resumed。
  • 真正的修复在 oa#40:DefaultWebview.ets 的 Web 组件改用 .width(100%).height(100%) natural ArkUI layout,让 ArkWeb 在 resize 时自然 relayout(根因解决底部内容截断)。

这是比原补丁更好的方案(治本),F1 清除。

🔵 F2(上轮 H8)仍开 — openspec plan 散落根

openspec/arkweb-surface-restore-plan.md 与 openspec/ohos-window-ops-plan.md 仍在 openspec/ 根(H8 第 4 次)。非阻塞,建议移入 openspec/changes/。


F1 已解决(根因 pivot),仅余 H8 归档位置(🔵 非阻塞)。可合入(配合 oa#40 的 natural sizing + tao#16 window ops)。

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (re-review 2026-07-15)

🔴 🟡 🔵 ℹ️
0 0 0 0

✅ F2(上轮 🔵 H8)已解决

openspec/arkweb-surface-restore-plan.md 与 openspec/ohos-window-ops-plan.md 已移出 openspec/ 根(散落计数 2→0),归档规范(H8)满足。

全部 finding 已清除

  • F1(🟡 surface-restore 部分失效):上轮经 natural sizing 根因 pivot 解决(handler 移除)。
  • F2(🔵 H8 plan 散落):本轮解决(移入 changes/)。

无新增问题,可合入(配合 oa#40 natural sizing + tao#16 window ops)。

@ljy9812
ljy9812 force-pushed the ohdev branch 7 times, most recently from 9a19496 to 326bf10 Compare July 15, 2026 09:11

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (re-review 2026-07-15)

🔴 🟡 🔵 ℹ️
0 0 0 0

全部历轮 findings 维持已解决(F1 surface-restore 经 natural sizing pivot、F2 H8 plan 已移入 changes/),本轮无回归、无新问题。可合入(配合 oa#40 + tao#16)。

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (re-review 2026-07-15)

🔴 🟡 🔵 ℹ️
0 0 0 1

✅ 历轮 findings 维持并改进

  • F1(surface-restore):lib.rs 的 Event::Resumed set_bounds handler 已完全移除(该文件不再出现在 diff),natural sizing(oa#40)作为根因修复维持。
  • F2(H8):plan 文件不再散落 openspec/ 根,且已正确嵌套到 openspec/changes/p1-arkweb-surface-restore/plan.md 与 openspec/changes/p1-ohos-window-ops/plan.md(H8 改进)。

本轮新增(示例集成 + 测试命令)

  • examples/api/src-tauri/build.rs 注册 3 个测试命令(test_persisted_scope / clear_persisted_scope / clear_window_state)。
  • cmd.rs 新增对应 #[command] 测试函数(test_persisted_scope 检查 .persisted-scope 文件生成等)。注释英文(H7✓)。
  • lib.rs 注册 persisted_scope + window_state 插件。H5✓ manual_tests.md 更新(+14)。H6✓ openspec 归档完整。

ℹ️ I1 — lib.rs block 1 的 cfg 门控未能从 diff 独立确认

diff 显示 persisted_scope/window_state/deep_link 出现在两个注册块(block 1 ~line 104 与 OHOS 块)。作者注释明确两块互补(not(OHOS) vs OHOS,NOT duplicates,only one runs per platform),且标题含 deep-link dedup,显示作者有意识处理。但 block 1 的 cfg 门控在 diff hunk 上方(未变更行),我无法从 diff 独立确认其是否在 cfg(not(target_env=ohos)) 下。

建议:确认 block 1(line ~104)确实在 #[cfg(not(target_env = ohos))] 下。若 block 1 无条件,OHO 上 persisted_scope/window_state/deep_link 会双重注册(initialize() 两次 → 重复 onOpenUrl/listeners,正是注释所述 deep-link dedup 要避免的问题)。


整体干净(F1/F2 维持并改进,H5/H6/H7✓)。仅 I1 需快速确认 block 1 cfg 门控。可合入(确认 I1 后)。

@ljy9812 ljy9812 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

回复 I1 — block 1 cfg 门控已确认 ✓

examples/api/src-tauri/src/lib.rs:93 确实在 #[cfg(not(target_env = "ohos"))] 下(该门控是 diff hunk 上方的未变更行,故 diff 不可见):

93:  #[cfg(not(target_env = "ohos"))]   // ← block 1 门控
94:  {
95:    builder = builder
       ...
105:     .plugin(tauri_plugin_deep_link::init())
106:     .plugin(tauri_plugin_persisted_scope::init())
107:     .plugin(tauri_plugin_window_state::Builder::default().build());
111:  }

deep_link / persisted_scope / window_state 的两个注册点分别在互补的 cfg 块:

  • block 1(lib.rs:93) #[cfg(not(target_env = "ohos"))] → 非 OHOS 注册
  • OHOS 块(lib.rs:114 起) #[cfg(target_env = "ohos")] → OHOS 独立注册

每个平台只跑一块 → OHOS 上无双重注册,deep-link dedup 关注的 initialize() 两次 / 重复 onOpenUrl/want listeners 问题不存在。作者注释("complementary cfg blocks … NOT duplicates, only one runs per platform")准确。

I1 确认通过,可合入。


附:block 1 门控位于未变更行,GitHub diff 默认 context 不足导致无法从 diff 独立确认——这是 I1 的合理疑虑来源;查阅完整文件(lib.rs:93)即可证。

@MingyuChen1 MingyuChen1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (re-review 2026-07-16)

🔴 🟡 🔵 ℹ️
0 0 0 0

✅ I1(上轮 ℹ️ lib.rs block 1 cfg 门控)已解决

lib.rs 两个注册块(block 1 ~line 104 与 OHOS 块)都含 autostart + persisted_scope + window_state。autostart 在两块都出现本身就证明它们是平台互补块(若都无条件,autostart 会双重注册报错),故 persisted_scope/window_state/deep_link 也是互补——每平台只一块运行,无双重注册。作者注释(complementary cfg blocks, NOT duplicates, only one runs per platform)文档化清晰。cfg 门控是未变更的 context 行故不在 diff,但结构已确认。

✅ openspec 完整归档(H6/H8 完全满足)

window-ops/arkweb 的 openspec 已归档到 openspec/changes/archive/2026-07-16-p1-ohos-window-ops/ 与 ...-p1-arkweb-surface-restore/(含 plan.md 嵌套在归档子目录内),并同步到 openspec/specs/。H8(plan 不散落根)完全满足。

✅ 作者闭环应用 review 学习(checklist +10)

.claude/skills/tauri-ohos-code-review/references/review-checklist.md 新增两项,直接受 babysit review 启发:

  • H8: manual_tests.md 统计表合计须等于各模块行之和(防差一)。
  • H9: openspec tasks.md 须反映最终采用方案(若 plan 标注回退/Rejected,tasks 对应待办须同步标注;代码注释不得引用已删除代码如 Event::Resumed handler)——正是 surface-restore pivot 的经验提炼。

历轮 findings 维持

F1(surface-restore handler 完全移除)、F2(H8 plan 嵌套)维持。H5✓ manual_tests(+14)。H7✓ 英文注释。


作者显式 apply PR-babysit review fixes(I1 解决、openspec 归档、checklist 学习应用)。无阻塞,可合入。

@ljy9812 ljy9812 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review — tauri#67 (window-state/persisted-scope plugins + manual tests, squashed 1479c67)

🔴 🟡 🔵 ℹ️
0 0 1 0

Reviewed: squashed commit 1479c673b — examples/api 集成(Cargo.toml / build.rs / lib.rs / cmd.rs / core.ts / TestRunner.svelte)、manual_tests.md、openspec 归档(p1-ohos-window-ops / p1-arkweb-surface-restore)+ 主 specs、review-checklist.md (H8/H9)。

历轮 findings 状态(均已解决)

  • ✅ F1 minimize/restore 陈旧注释(引用已回退的 Event::Resumed handler)→ 已修 core.ts
  • ✅ F3 manual_tests.md 统计差一(62+5=67≠66)→ 已修 67/124
  • ✅ F4 arkweb tasks.md 残留已回退方案 → 已改写为回退说明 + 最终方案
  • ✅ F6 window-ops tasks.md 3.3(set_maximized(false) no-op)与代码/design(recover_window)矛盾 → 已修
  • ✅ I1 lib.rs block 1 cfg 门控 → 已确认在 #[cfg(not(target_env = "ohos"))](lib.rs:93),两块互补无双重注册

🔵 L1 — test_persisted_scope 阻塞 sleep

cmd.rs test_persisted_scopestd::thread::sleep(300ms) 等 persisted-scope 异步监听写文件。测试命令可接受,可用 retry/notify 替代。非阻塞。

正面确认

  • lib.rs 插件注册 cfg 块互补(not(OHOS) vs OHOS),无双重注册;deep-link dedup 正确。
  • openspec 两 change 已归档(archive/2026-07-16-*)+ 主 specs 生成;tasks.md 反映最终方案。
  • manual_tests.md persisted-scope 用例准确(Test 返回 5 字段无 count、Clear 返回 remaining_patterns_countallow_directory(recursive) 加 2 pattern、HashSet 幂等 → "不点 Test 直接 Clear" 逻辑正确);已设备验证 restore 生效(count=2,.persisted-scope 跨重启留存)。

结论

0 Blocker / 0 Major — clean,可合入(配合 oa#40 + tao#16)。

…nual tests, review fixes & openspec archival

- window-state/persisted-scope plugins + deep-link dedup + manual test buttons
- review fixes: manual_tests stats off-by-one (-> 68/125), stale minimize/restore
  test comment, openspec tasks.md staleness (set_maximized(false) -> recover_window)
- archive p1-ohos-window-ops & p1-arkweb-surface-restore openspec changes,
  regenerate main specs
- persisted-scope manual test: restore via Clear (not Test), expected count > 0
  (allow_directory recursive adds 2 patterns: path + path/**)
- test_persisted_scope: remove unnecessary 300ms sleep (persisted-scope listener
  runs synchronously via scope.emit before allow_directory returns) and fix comment
- review-checklist.md: add H8 (manual_tests stats sum) & H9 (openspec tasks.md
  must reflect final/reverted approach)

Co-Authored-By: Claude <noreply@anthropic.com>

@ljy9812 ljy9812 left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OHOS Code Review (round 2) — tauri#67

🔴 🟡 🔵 ℹ️
0 0 0 0

本轮 finding(已修复)

🟡→✅ manual_tests.md 统计合计差一合计 T0=67,但 27 行模块 T0 列求和=68(预存表行和=63 但旧合计写 62,本 PR +5 后应为 68)。违反本 PR 自身新增的 H8 checklist 项。修复:67→68,124→125(T1=57 不变)。

🟡→✅ test_persisted_scope 不必要的 sleep + 失实注释std::thread::sleep(300ms) 注释称"persisted-scope listens async, give it a moment"。核实 scope.allow_directoryscope.emit 在返回前同步内联调 listener(crates/tauri/src/scope/fs.rs:263),persisted-scope 监听器同步 save_scopes 写文件,故 allow_directory 返回时文件已落盘,无 race。修复:移除 sleep,改注释说明监听器经 emit 同步调用。

历轮 findings 状态(均已解决)

  • ✅ F1 minimize/restore 陈旧注释 → 修 core.ts
  • ✅ F3 统计差一 → 修(本轮进一步修正为 68)
  • ✅ F4 arkweb tasks.md 残留回退方案 → 修
  • ✅ F6 window-ops tasks.md 3.3 → recover_window
  • ✅ I1 lib.rs block 1 cfg 门控 → 确认 #[cfg(not(target_env = "ohos"))](lib.rs:93),无双重注册

已核实

  • lib.rs 插件注册 cfg 块互补;openspec 归档 + 主 specs 生成;build.rs 命令名 / run-app.json ACL 与 cmd.rs 一致;clear_window_state/test_persisted_scope 路径与插件保存路径一致。

结论

0 Blocker / 0 Major — clean,可合入(配合 oa#40 + tao#16)。

@Eulogizethesun
Eulogizethesun merged commit 2c5218f into Eulogizethesun:ohdev Jul 20, 2026
2 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants