Repository navigation
Conversation
… version detection, autostart, and WebView transparency
This commit brings a comprehensive set of new features and improvements
to openharmony-ability, transforming it from a basic single-window
ability framework into a feature-rich platform for OpenHarmony/HarmonyOS
native applications.
74 files changed, ~8,500 lines added, ~875 lines removed.
New Features:
1. Menu System (crates/ability/src/menu/ — 6 new files, ~1,640 lines)
Complete menu system with menubar and context popup support:
- mod.rs: Channel-based architecture using crossbeam_channel for
bidirectional Rust (muda) <-> ArkTS communication. Background
forwarder thread dispatches via TSFN callback. Per-window menubar
visibility state in RwLock<HashMap>. Buffered menubar JSON per
window for late ArkTS callback registration.
- types.rs: MenuRequest/MenuRequestData (NAPI object), MenuItemData
(recursive submenu), AboutMetadataData, NAPI classes Menu,
MenuItem, Submenu.
- event.rs: MenuEvent struct with MenuEventDispatcher and global
GLOBAL_DISPATCHER (LazyLock<Mutex>).
- predefined.rs: PredefinedType enum (Copy, Cut, Paste, SelectAll,
Undo, Redo, Minimize, Maximize, Quit, etc.) with factory methods
and default accelerators (Ctrl+C, Ctrl+V, etc.).
- state.rs: MenuStateController NAPI class for create/append/destroy.
- popup.rs: MenuPopup NAPI class for context menu show/hide.
2. System Tray / StatusBar (crates/ability/src/statusbar/ — 5 new files, ~855 lines)
Full system tray integration:
- types.rs: StatusBarItem, StatusBarIcon (RGBA pixel data),
QuickOperation, StatusBarMenuItem/SubMenuItem, StatusBarMenuAction,
StatusBarClickEvent enum.
- event.rs: Dual crossbeam_channel pairs for icon click and menu
click events with register/unregister handlers.
- manager.rs: 6 TSFNs (Add, Remove, UpdateIcon, UpdateMenu,
UpdateTips, PredefinedAction) with thread-safe main-thread dispatch.
- validate.rs: Input validation (max 20 menu items, max 20 sub-items,
hover tips 1-128 chars, height > 0).
3. Clipboard (crates/ability/src/clipboard/mod.rs — 178 lines)
clipboard_write_image(rgba, width, height) async function writing
RGBA image data to system clipboard via TSFN bridge to ArkTS
writeImageToClipboard (Promise-based with 10-second timeout).
4. App Updater / AppGallery Integration (crates/ability/src/updater.rs + helper/updater.rs — ~420 lines)
- Updater::check() queries AppGallery for available updates, returns
CheckResult with version, body, and date.
- Updater::download_and_install() shows update dialog and drives
download+install flow.
- 3 TSFNs for check, show dialog, and download/install operations.
5. Version Detection (crates/ability/src/version.rs — 316 lines)
- sdk_api_version(): OpenHarmony base API Level (e.g., 12, 14, 20).
- distribution_api_version(): HarmonyOS distribution version
(M*10000 + S*100 + F).
- can_i_use(syscap): queries device system capabilities via ArkTS
canIUse().
- Includes device tests for worker thread safety.
6. Multi-Window Support (crates/ability/src/window/mod.rs — 200+ lines)
- create_os_window(name, window_type) creates OS-level sub-windows
with global atomic NEXT_WINDOW_ID for unique ID generation.
- Window decorations support (title bar, border, etc.).
- WindowManager with destroyWindow() for proper resource cleanup.
7. Float Window (native_ability/.../FloatPage.ets — 300 lines)
Floating window page component with drag and resize functionality
using createSubWindow API.
8. Autostart Support (crates/ability/src/autostart.rs + helper/autostart.rs — 412 lines)
- AutostartManager for managing app auto-start on device boot.
- TSFN bridge for ArkTS autostart registration/unregistration.
- Integration with HarmonyOS AbilityManagerService.
9. WebView Transparency (native_ability/.../DefaultWebview.ets — 71+ lines)
- Transparent background support for WebView.
- Window transparency synchronization.
- TransparencyTest demo page for validation.
Improvements & Refactoring:
App Enhancements (app.rs):
- restart(): hard process restart via TSFN with 3-second cooldown.
- set_color_mode(mode: ColorMode): dark/light/system theme switching.
- updater(): get updater handle for AppGallery integration.
- AbilityInitContext now includes sdk_api_version and
distribution_api_version.
- New NAPI export: is_desktop_device() for compile-time device type
detection.
Helper Infrastructure (helper/):
- Refactored from thread_local to global Mutex for HELPER storage,
enables cross-thread access via SendableHelper wrapper.
- New helper/restart.rs: restart TSFN with LazyLock<RwLock> pattern.
- New helper/updater.rs: three TSFN pairs for updater operations.
- New helper/autostart.rs: autostart TSFN management.
WebView Enhancements (webview/):
- window_id field on WebViewInitData and WebViewBuilder for per-window
webview creation.
- on_page_begin / on_page_end lifecycle callbacks.
- Fixed callback argument indexing (off-by-one in NAPI extraction).
- Added 'static bound to custom protocol callback closures.
- Fixed closure invocation to avoid holding lock during callback.
- Full URL matching for close-window intercept.
Lifecycle & Events:
- onWindowStageDestroy lifecycle hook.
- NewWant event support.
- runJavaScript error handling.
ArkTS Side (Native Layer — ~2,500+ lines, 18 new files):
- ArkHelper.ets (650+ lines): Full ArkHelper interface covering exit,
restart, updater, permissions, window, webview, statusbar, clipboard,
autostart.
- MenuBarComponent.ets (451 lines): Per-window menubar UI with click
handlers and keyboard accelerator support.
- FloatPage.ets (300 lines): Floating window page component.
- menu.ets (239 lines): MenuManager and PredefinedActionExecutor.
- WindowManager.ets (350+ lines): Multi-window management singleton
with proper destroyWindow() cleanup.
- StatusBarUtils.ets (182 lines): Status bar pixel map creation.
- accelerator_matcher.ets (142 lines): Keyboard shortcut matching.
- Utils.ets (140+ lines): JsHelper and ProxyJsHelper for deferred
webview init.
- updater.ets (115 lines): AppGallery updater using AppGalleryKit.
- predefined.ets (109 lines): Predefined menu action implementations.
- menu_state.ets (85 lines): Menu state management.
- MenuPopup.ets (80 lines): Context popup menu component.
- menu_types.ets (74 lines): Type definitions for menu system.
- autostart.ets (63 lines): Autostart registration helper.
- os.ets (37 lines): OS-level utility functions.
- ClipboardHelper.ets (33 lines): Clipboard write image implementation.
- TransparencyTest.ets (167 lines): Demo page for transparency testing.
Bug Fixes:
- fix(statusbar): re-register click handlers after addToStatusBar to
survive receiver rebuilds.
- fix(statusbar): prevent FloatPage from overwriting main window
helperRef.
- fix(ohos): tray icon click events — abilityName null check and
one-time on() guard, support relaunch.
- fix(tray): close/fullscreen behavior, menubar startup timing.
- fix(webview): callback argument off-by-one in NAPI extraction.
- fix(webview): closure lock held during callback (potential deadlock).
- fix(webview): use full URL for close-window intercept.
- fix(NativeAbility): duplicate onWindowStageDestroy method.
- fix(WindowManager): proper destroyWindow() cleanup on sub-window close.
- refactor: renamed TAURI_OHOS_DEVICE_TYPE to OHOS_DEVICE_TYPE for
framework-agnostic naming.
- docs: changed Chinese doc comments to English in helper/mod.rs.
Design Patterns:
- TSFN Bridge Pattern for safe ArkTS calls from Rust worker threads.
- Channel-based Event Distribution via crossbeam_channel.
- OnceLock/LazyLock for thread-safe lazy initialization.
- Per-Window State Maps (HashMap<String, bool>) for menubar state.
- Promise-to-Future Bridge via oneshot::channel + PromiseRaw + timeout.
Testing:
- Added device tests for the version module.
- Added TransparencyTest demo page for WebView transparency validation.
…dedWebBuilder Call ctrl.setCustomUserAgent(data.userAgent) in onControllerAttached callback when userAgent is provided. Enables OHOS WebView custom User-Agent via WebviewController API.
Round 1: - Extract shared DOMAIN constant into helper/constants.ets (10 files) - Use system icon for FloatPage close button - Replace eprintln! with crate::error! in xcomponent.rs and app.rs Round 2: - Add feature flags for modular compilation (statusbar, updater, version, window, clipboard, webview, menu) - Define cfg-gated crate::error!/info!/warn!/debug! macros replacing direct log::*/hilog_*! usage - Make log/hilog dependencies optional behind 'log' feature flag - Add cfg gates for version-dependent and module-dependent code paths Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fix: address upstream PR harmony-contrib#63 review feedback and code quality cleanups
…-user-agent feat(webview): add setCustomUserAgent support in WebBuilder and EmbeddedWebBuilder
…ialog and code review fixes
feat(ohos): add window close lifecycle mechanism via NAPI queue
- Extend onNewWant ArkTS callback to extract and serialize want.parameters - Log parametersJson.length in NativeAbility for debugging - Define NewWantData interface in type.ets for type-safe parameter passing - Update NAPI bridge from Function<String> to Function<Object> - Add #[cfg(target_env = "ohos")] gate on WANT_PARAMETERS static and functions - Add static Mutex storage with store/take semantics and poison-safe error logging - Use ? for property extraction (consistent with other lifecycle callbacks) - Document concurrency contract: store on ArkTS main thread, take on tauri event loop - Update index.d.ts to match new onNewWant signature - Add single combined unit test for store/take/clear/overwrite (avoids parallel races)
feat(ohos): forward want.parameters through onNewWant event chain
- Add SnapshotData interface and JsHelper.webPageSnapshot method (ArkTS) - Implement webPageSnapshot with PixelMap to RGBA conversion and resource cleanup - Add Rust web_page_snapshot() callback API on Webview struct - Add unsafe impl Send for Webview (main thread only access)
feat(webview): add webPageSnapshot support for WebView content capture
- Restore PdfConfig struct with to_napi_map() for NAPI transport - Add scale field to PdfConfig (SDK PdfConfiguration.scale support) - Restore config parameter in ArkTS createPdf with merge logic - Update JsHelper/ProxyJsHelper interface to include config - Revert pdfArrayBuffer().buffer removal (Uint8Array -> ArrayBuffer) - Revert async fileIo.write back to fileIo.writeSync - Restore explanatory NAPI callback behavior comments
feat: add PdfConfig, createPdf NAPI + ArkTS implementation
- Add predefined menu actions: hide, close, minimize, showAll, bringAllToFront - Add clipboard ops (copy, cut, paste, selectAll, undo, redo) using target window webview - Align predefined menu actions with macOS Key Window semantics - Add MAIN_WINDOW_ID constant for main window identification - Centralize resetUserInteractionTracking in WindowManager wrapper methods - Add getPrimaryWebviewController for clipboard operations on primary webview - Fix FloatPage aboutToAppear async declaration - Remove Bug 6 references from comments
feat(menu): predefined multi-window clipboard ops and WindowManager fixes
…lper pending path fix, setBounds in controllers
feat(ohos): add WebViewStyle width/height, set_bounds NAPI, ProxyJsHelper pending path fix
Add Webview::set_cookie NAPI method and ArkTS setCookie (JsHelper interface, ProxyJsHelper pending-replay, DefaultWebview buildJsHelper) delegating to WebCookieManager.configCookieSync.
Add comprehensive mouse input handling for OHOS 2in1 desktop devices: - MouseEventData struct wrapping OH_NativeXComponent_MouseEvent FFI - MouseAction enum with Press/Release/Move/HoverEnter/HoverLeave variants - dispatch_mouse_event: NDK DispatchMouseEvent callback - dispatch_hover_event: NDK DispatchHoverEvent callback for cursor enter/leave - AxisEventData struct for scroll wheel delta (delta_x, delta_y) - dispatch_axis_event: ArkUI UIInputEvent AXIS callback for scroll wheel - register_mouse_callbacks: registers all three callbacks with NDK - InputEvent::MouseEvent and InputEvent::AxisEvent variants - Added ohos-xcomponent-sys and ohos-arkui-sys as direct dependencies Co-Authored-By: Claude <noreply@anthropic.com>
- Add InputSourceType enum (Mouse/TouchScreen/Touchpad/Joystick/Keyboard) - Add pinch_scale and source_type fields to AxisEventData - Extract pinch scale via OH_ArkUI_AxisEvent_GetPinchAxisScaleValue - Extract source type via OH_ArkUI_UIInputEvent_GetSourceType - Skip axis events with no scroll delta AND no pinch data Co-Authored-By: Claude <noreply@anthropic.com>
feat(ohos): add setCookie NAPI bridge for webview cookie management
OHOS NDK DispatchMouseEvent doesn't fire when cursor is over WebView, so we track cursor position from ArkTS onMouse events instead. - Add CURSOR_POSITION_X/Y atomic statics in app.rs - Add update_cursor_position() NAPI function for ArkTS to call - Add .onMouse() handler in MainPage.ets that calls NAPI on Move/Press - Export CURSOR_POSITION_X/Y for tao to read Co-Authored-By: Claude <noreply@anthropic.com>
Add a native ArkTS overlay for testing key repeat detection: - Floating '⌨ Key Test' button (bottom-right corner) - Focusable overlay panel with HashSet-based repeat tracking - .onKeyEvent() captures keys at ArkUI level (bypasses WebView) - ESC or ✕ to close overlay - repeat=true shown in green bold when key hold is detected Co-Authored-By: Claude <noreply@anthropic.com>
Add Webview::set_web_debugging_access(bool) and is_web_debugging_access() NAPI methods. ArkTS side (Utils.ets) tracks webDebuggingEnabled state (setWebDebuggingAccess const calls the static API first then updates the var; isWebDebuggingAccess returns the var). DefaultWebview.ets init routes through the const to keep state in sync. Uses domain socket (setWebDebuggingAccess(true), no port) — connect Chrome DevTools via examples/api/devtools.bat which auto-discovers the socket and forwards via hdc fport.
feat(ohos): add setWebDebuggingAccess NAPI bridge for devtools toggle
…ents feat(ohos): add mouse event, hover event, and scroll wheel support
…mer API - Forwarder thread + crossbeam channel + run_on_main_thread architecture - inputConsumer API (API 14+) for hotkey registration - 60+ key code mapping (Rust/ArkTS consistent) - Error code handling (801/4200002/4200003) - Duplicate modifier dedup, blocking send in unregister_all - Documented fire-and-forget design and synthetic Released event - SAFETY comments, dispatch_to_main_thread returns Result Co-Authored-By: Claude <noreply@anthropic.com>
feat(global_shortcut): add OHOS global shortcut bridge via inputConsumer API
- Phase 6/7: on_window_new Create + window focus NAPI bridge - Fix crash from napi_reference_unref on tokio worker threads: napi_ohos::Error's Drop calls napi_reference_unref which must run on main thread. Convert Error to String before sending through oneshot channels (clipboard, autostart, updater). Wrap ObjectRef in ManuallyDrop in thread-local cache.
feat(ohos): add window focus NAPI and fix napi_reference_unref crash
feat(ohos): expand Ability windowing and desktop plugin support
Co-Authored-By: Claude <noreply@anthropic.com>
dispose_render/dispose_all_renders dropped the RootNode before calling release_render. RootNode::drop unmounts and disposes the XComponent ArkUI node, so release_render then removed gestures and unregistered callbacks on freed memory, crashing with SIGSEGV in GestureEventHub::RemoveGesture (via NDK RemoveGestureFromNode) during DefaultXComponent teardown. Reproduced deterministically (2/2 builds) on HAD-W24 by switching tabs away from a DefaultXComponent page in the demo app: aboutToDisappear runs inside the ArkUI subtree destruction, so the disposed node is touched while it is being torn down. Swap the order in all four dispose sites (main window + sub window, single + all) so release_render runs while the node is still alive; the RootNode drop then unmounts and disposes it cleanly. Pre-existing since the adaptation line (verified identical at e5220ce); surfaced now because the demo tab UI is the first consumer that destroys a live DefaultXComponent with registered gestures. Verified on device: tab switch no longer crashes (pid survives, no new faultlog) and the native sub-window render path still works. Co-Authored-By: Claude <noreply@anthropic.com>
Match the established annotation on the neighboring Arc<RefCell> fields (ime, back_press_interceptor); the lint fires on the current clippy toolchain. Co-Authored-By: Claude <noreply@anthropic.com>
Every other module ships its hvigor-generated BuildProfile.ets; the accessibility module (added to the demo build in the PR #3 merge) was missing its generated file from tracking. Co-Authored-By: Claude <noreply@anthropic.com>
The file was committed before being run through the repo formatter; the format gate formats it on every check. Co-Authored-By: Claude <noreply@anthropic.com>
Expose per-window continuous or on-demand frame delivery while keeping existing consumers continuous by default. Control only the native frame callback, preserving input and surface callbacks. Frame handlers retain weak runtime references, validate the render owner, and active delivery changes enforce the render UI thread. Cache policy tests and ARM64 integration builds cover the new API. (cherry picked from commit 23047cc)
Upstream already releases native consumers before dropping each RootNode. Preserve that ordering and drain the sub-window registry before invoking teardown callbacks, so callbacks can re-enter the registry without a RefCell borrow panic. (cherry picked from commit 4493821)
(cherry picked from commit ab1d6c2)
(cherry picked from commit 2a5d247)
Remove the device-type and legacy SysCap precheck for folder selection, while retaining the independent save-filter-index capability guard. Preserve picker error codes with device/API context and reject calls before launch or after completion when the Ability is inactive. Update the Rust and ArkTS plugin documentation without changing the ABI. Validation: oxk format and lint, six production-ETS boundary checks, and source parity with the NearSend 1.2.2 Release package. API 24 tablet folder selection and nested-file enumeration passed in the simulator; the original MatePad Edge-specific failure still needs device confirmation. (cherry picked from commit 9e003b6)
Remove the separately cached render thread ID and validate native render operations against the current bridge session main thread. Preserve pre-surface frame configuration and keep repeated applied-mode calls on a read-only fast path.
Use the API version and declared system capability for getSelectedIndex so capable tablets are not excluded. Rename the capability constant to distinguish this save-result query from folder selection, which is already delegated to the system picker.
Require WindowManager 0.1.1 to unify image bindings, remove the unused libloading dependency, and delete obsolete patch instructions.
ArkUI 0.4.1 handles API-14 keyboard callbacks without the API-20 discriminator. Remove six redundant package.workspace paths and inherit the workspace automatically.
Gate ArkUI keyboard snapshots, reply types, and callbacks behind the keyboard feature, which enables API 14. Preserve raw XComponent input as the default and keep drag independent.
Preserve clipboard record order and harden URL scheme checks, prompt placement and cancellation, failed window creation rollback, serialized restore operations, inactive colors, blur cleanup and thermal subscriptions. Require business-owned clipboard metadata MIME and notification scheme options. Preserve menu-open window identity, reject excess notification actions, align system-state wire names and include the new plugins and configured factories in the aggregate HAR. Update demos and documentation, and add host runtime regression coverage. BREAKING CHANGE: ClipboardPlugin and NotificationPlugin require constructor options. The aggregate exports createAllBridgePlugins(options) instead of allBridgePlugins. Menu-open channels carry MenuOpenEvent, and system-state wire types now use the ohos.system-state prefix.
feat: ohos adaptation runtime fixes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概述
为 openharmony-ability 带来完整的 OpenHarmony(OHOS)支持,覆盖 desktop(二合一) 与 mobile 两种形态。取代 #63(分支内容相同——即维护在
ohdev上的适配线——新开 PR 以获得最新的描述;#63 的 review 历史保留作参考)。本分支持续与
main引入的插件化架构保持同步(crates/plugin-*插件 crate、native_ability/下的 ArkTS 桥接、plugins/下的逐插件 ArkTS 包),并在此之上扩展 OHOS 适配线。180 个文件变更,+22,936 / −535(合并
main后的当前口径)——内部开发产物(agent skill、内部规划文档、Windows 打包辅助脚本、legacy 归档说明)已从 PR 剔除,只携带适配内容。内容
新增插件 crate(
crates/plugin-*)——在既有集合之外新增 10 个插件:plugin-menu——菜单栏 / 弹出菜单 / 预定义项 / 加速键触发链plugin-statusbar——系统托盘(图标、菜单、快捷操作面板)plugin-accessibility——fontScale / 屏幕朗读器查询plugin-screenshot——webview 截图 + 像素取色plugin-continuation——应用接续(源端保存 / 恢复)plugin-clipboard、plugin-deep-link、plugin-global-shortcut、plugin-autostart,以及plugin-app-control扩展ArkTS 桥接(
native_ability/+plugins/)Rust 核心(
crates/ability)冲突状态(与 main 重构系列)——已解决
本分支自
main的6c52bb4分出;此后main前进了 13 个提交(插件化 / node-surface / 生命周期序列化系列,#64–#80),与两侧的适配改动重叠,产生 84 处冲突路径:version字段、BuildProfile.ets/CHANGELOG.md戳记crates/plugin-webview/src/lib.rs、crates/ability/src/app.rs、native_ability/src/main/ets/ability/NativeAbility.ets(两侧演进了相同区域)两条分支架构本就同构(均已插件化、桥接布局一致),冲突是文本级分叉而非架构对撞。
对齐已完成:
main(282425ae)已合入本分支(d88bee7,后续edac3a8/1af3adc),84 处冲突全部解决,分支与main完全同步、PR 不删除任何 main 文件。裁决原则、逐块说明与验证矩阵见下方评论。测试
examples/api自动化套件:296 例真机运行——295 通过、2 例按设计跳过(剪贴板读权限、设备无振动马达);与同一套件的 Windows 运行逐例对齐openharmony-ability83 + 16 个插件 crate 86,含非默认特性门控测试;明细见下方评论)🤖 Generated with Claude Code