cj-tauri 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/README.md +113 -99
  2. package/bin/cj-tauri.js +287 -287
  3. package/cjpm.toml +63 -52
  4. package/cli/cjpm.toml +22 -22
  5. package/cli/src/doctor.cj +308 -306
  6. package/cli/src/main.cj +129 -129
  7. package/cli/src/manifest.cj +632 -558
  8. package/cli/src/manifest_test.cj +87 -0
  9. package/cli/src/project.cj +770 -770
  10. package/cli/src/resolve.cj +348 -348
  11. package/cli/src/scaffold.cj +369 -369
  12. package/cli/src/sync.cj +526 -526
  13. package/cli/src/util.cj +168 -168
  14. package/cli/templates/app/README.md +51 -48
  15. package/cli/templates/app/assets/capabilities/default.json +7 -7
  16. package/cli/templates/app/assets/ui/index.html +120 -118
  17. package/cli/templates/app/cj-tauri.toml +32 -22
  18. package/cli/templates/app/cjpm.toml +34 -34
  19. package/cli/templates/app/src/main.cj +101 -90
  20. package/cli/templates/app-react/README.md +56 -56
  21. package/cli/templates/app-react/assets/capabilities/default.json +7 -7
  22. package/cli/templates/app-react/assets/ui/index.html +25 -25
  23. package/cli/templates/app-react/assets/ui/package.json +19 -19
  24. package/cli/templates/app-react/assets/ui/src/App.css +67 -67
  25. package/cli/templates/app-react/assets/ui/src/App.jsx +124 -124
  26. package/cli/templates/app-react/assets/ui/src/main.jsx +6 -6
  27. package/cli/templates/app-react/assets/ui/vite.config.js +24 -24
  28. package/cli/templates/app-react/cj-tauri.toml +33 -23
  29. package/cli/templates/app-react/cjpm.toml +34 -34
  30. package/cli/templates/app-react/src/main.cj +91 -91
  31. package/cli/templates/app-vue/README.md +56 -56
  32. package/cli/templates/app-vue/assets/capabilities/default.json +7 -7
  33. package/cli/templates/app-vue/assets/ui/index.html +25 -25
  34. package/cli/templates/app-vue/assets/ui/package.json +18 -18
  35. package/cli/templates/app-vue/assets/ui/src/App.vue +176 -176
  36. package/cli/templates/app-vue/assets/ui/src/main.js +4 -4
  37. package/cli/templates/app-vue/assets/ui/vite.config.js +24 -24
  38. package/cli/templates/app-vue/cj-tauri.toml +33 -23
  39. package/cli/templates/app-vue/cjpm.toml +34 -34
  40. package/cli/templates/app-vue/src/main.cj +91 -91
  41. package/cli/templates/ohos-skeleton/AppScope/app.json5 +13 -13
  42. package/cli/templates/ohos-skeleton/AppScope/resources/base/element/string.json +8 -8
  43. package/cli/templates/ohos-skeleton/AppScope/resources/base/media/layered_image.json +6 -6
  44. package/cli/templates/ohos-skeleton/README.md +84 -79
  45. package/cli/templates/ohos-skeleton/build-hap.sh +15 -0
  46. package/cli/templates/ohos-skeleton/build-profile.json5 +46 -46
  47. package/cli/templates/ohos-skeleton/entry/build-profile.json5 +26 -26
  48. package/cli/templates/ohos-skeleton/entry/cjpm.toml +51 -43
  49. package/cli/templates/ohos-skeleton/entry/hvigorfile.ts +6 -6
  50. package/cli/templates/ohos-skeleton/entry/oh-package.json5 +9 -9
  51. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/ability_stage.cj +17 -17
  52. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/app_host.cj +94 -94
  53. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/dialog_host.cj +217 -0
  54. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/index.cj +527 -167
  55. package/cli/templates/ohos-skeleton/entry/src/main/cangjie/main_ability.cj +139 -139
  56. package/cli/templates/ohos-skeleton/entry/src/main/module.json5 +57 -49
  57. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/color.json +8 -8
  58. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/string.json +16 -16
  59. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/media/layered_image.json +6 -6
  60. package/cli/templates/ohos-skeleton/entry/src/main/resources/base/profile/main_pages.json +2 -2
  61. package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/capabilities.json +6 -6
  62. package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/index.html +92 -92
  63. package/cli/templates/ohos-skeleton/hvigor/hvigor-config.json5 +5 -5
  64. package/cli/templates/ohos-skeleton/hvigorfile.ts +6 -6
  65. package/cli/templates/ohos-skeleton/oh-package.json5 +10 -10
  66. package/native/build_win.bat +62 -62
  67. package/native/core/bridge_core.c +1681 -1626
  68. package/native/core/bridge_core.h +675 -618
  69. package/native/core/bridge_js.h +108 -108
  70. package/native/platforms/harmonyos/README.md +115 -6
  71. package/native/platforms/linux/bridge_linux.c +2787 -2485
  72. package/native/platforms/windows/bridge_win.c +3740 -3248
  73. package/native/tests/gtk_threading_probe.c +143 -143
  74. package/native/tests/test_bridge_core.c +1339 -1228
  75. package/package.json +53 -53
  76. package/prebuilt/linux-x64/cj-tauri +0 -0
  77. package/src/api_system.cj +67 -67
  78. package/src/app.cj +325 -969
  79. package/src/app_events.cj +166 -0
  80. package/src/app_host_ops.cj +287 -0
  81. package/src/app_run.cj +283 -0
  82. package/src/app_spec.cj +76 -76
  83. package/src/arkweb_menu.cj +216 -0
  84. package/src/arkweb_script.cj +142 -142
  85. package/src/capability.cj +409 -409
  86. package/src/clipboard_bridge.cj +178 -0
  87. package/src/dialog_spec.cj +79 -0
  88. package/src/dragdrop.cj +26 -26
  89. package/src/embedded_assets.cj +98 -98
  90. package/src/host.cj +752 -607
  91. package/src/host_arkweb.cj +924 -778
  92. package/src/host_webkit.cj +663 -570
  93. package/src/host_webview2.cj +663 -570
  94. package/src/hotkey.cj +66 -66
  95. package/src/ipc_hub.cj +337 -337
  96. package/src/ipc_message.cj +286 -286
  97. package/src/launch.cj +62 -62
  98. package/src/logging.cj +127 -127
  99. package/src/menu.cj +197 -197
  100. package/src/platform/platform_app_context.cj +77 -77
  101. package/src/platform/platform_assets.cj +33 -33
  102. package/src/platform/platform_discover.cj +176 -176
  103. package/src/platform/platform_env.cj +29 -29
  104. package/src/platform/platform_feature.cj +31 -31
  105. package/src/platform/platform_page_source.cj +87 -87
  106. package/src/platform/platform_target_info.cj +32 -32
  107. package/src/platform_host_provider.cj +87 -87
  108. package/src/plugin.cj +333 -333
  109. package/src/plugins/clipboard/plugin_clipboard.cj +152 -152
  110. package/src/plugins/dialog/plugin_dialog.cj +209 -209
  111. package/src/plugins/fs/plugin_fs.cj +105 -1
  112. package/src/plugins/http/http_backend.cj +131 -0
  113. package/src/plugins/http/http_desktop.cj +195 -0
  114. package/src/plugins/http/http_ohos.cj +204 -0
  115. package/src/plugins/http/plugin_http.cj +310 -459
  116. package/src/plugins/log/plugin_log.cj +105 -105
  117. package/src/plugins/menu/plugin_menu.cj +158 -158
  118. package/src/plugins/notification/plugin_notification.cj +154 -154
  119. package/src/plugins/serial/plugin_serial.cj +458 -454
  120. package/src/plugins/serial/serial_bridge.cj +194 -194
  121. package/src/plugins/serial/serial_manager_ohos.cj +92 -0
  122. package/src/plugins/serial/serial_ohos.cj +529 -0
  123. package/src/plugins/shell/plugin_shell.cj +258 -258
  124. package/src/plugins/sqlite/plugin_sqlite.cj +705 -710
  125. package/src/plugins/sqlite/sqlite_ffi.cj +206 -211
  126. package/src/plugins/ws/plugin_ws.cj +488 -470
  127. package/src/process_hidden.cj +174 -174
  128. package/src/scope.cj +391 -391
  129. package/src/shell_event.cj +69 -69
  130. package/src/tests/app_spec_test.cj +126 -127
  131. package/src/tests/capability_test.cj +243 -243
  132. package/src/tests/dialog_spec_test.cj +73 -0
  133. package/src/tests/fake_host.cj +201 -201
  134. package/src/tests/ipc_hub_test.cj +487 -487
  135. package/src/tests/logging_test.cj +62 -62
  136. package/src/tests/platform_contract_test.cj +251 -251
  137. package/src/tests/plugin_clipboard_test.cj +222 -222
  138. package/src/tests/plugin_dialog_test.cj +237 -237
  139. package/src/tests/plugin_fs_test.cj +207 -0
  140. package/src/tests/plugin_http_test.cj +124 -124
  141. package/src/tests/plugin_notification_test.cj +205 -205
  142. package/src/tests/plugin_serial_test.cj +48 -0
  143. package/src/tests/plugin_test.cj +605 -585
  144. package/src/tests/plugin_ws_test.cj +40 -40
  145. package/src/tests/process_hidden_test.cj +129 -129
  146. package/src/tests/scope_test.cj +350 -350
  147. package/src/tests/system_host_test.cj +99 -81
  148. package/src/tests/urlutil_test.cj +53 -53
  149. package/src/tests/version_test.cj +75 -75
  150. package/src/tests/window_registry_test.cj +123 -123
  151. package/src/tray.cj +90 -90
  152. package/src/urlutil.cj +159 -159
  153. package/src/version.cj +44 -44
  154. package/src/window.cj +51 -51
  155. package/src/window_registry.cj +116 -116
  156. package/prebuilt/win32-x64/cj-tauri.exe +0 -0
  157. package/src/plugins/serial/serial_ohos_stub.cj +0 -61
  158. package/src/plugins/sqlite/sqlite_ohos_stub.cj +0 -91
@@ -1,139 +1,139 @@
1
- package ohos_app_cangjie_entry
2
-
3
- import kit.PerformanceAnalysisKit.Hilog
4
- import kit.AbilityKit.Want
5
- import kit.AbilityKit.UIAbility
6
- import kit.AbilityKit.LaunchParam
7
- import kit.AbilityKit.LaunchReason
8
- import kit.ArkUI.WindowStage
9
- import ohos.display.getDefaultDisplaySync
10
- import ohos.resource_manager.*
11
- import cjTauri.*
12
-
13
- /*
14
- * {{PROJECT_NAME}} 的 UIAbility
15
- *
16
- * 鸿蒙应用没有「自己起进程跑一个 main」这回事:窗口属于 ArkUI、页面由 ArkWeb 组件承载。
17
- * 所以桌面的 `main()` 在这里被拆成三段:
18
- * ① 把沙箱目录告诉框架(`run(html)` 要把页面落到沙箱再以 file:// 加载);
19
- * ② 在**非 UI 线程**上装配并跑框架应用(`run()` 阻塞到 quit(),UI 线程要留给 ArkUI 建树);
20
- * ③ 等框架把默认窗口的宿主登记好,再 `loadContent`。
21
- *
22
- * 页面与能力清单都是 hap 里的 `resources/rawfile/` 真文件,运行期读成字符串:
23
- * rawfile/index.html ← 就是桌面工程的 ui/index.html(改了重建即可)
24
- * rawfile/capabilities.json ← 就是桌面的 capabilities 目录下那份 default.json
25
- * 好处是 DevEco 里直接点 Build 也能编过(不需要先跑一次生成脚本)。
26
- */
27
- class MainAbility <: UIAbility {
28
- public init() {
29
- super()
30
- registerSelf()
31
- }
32
-
33
- public override func onCreate(want: Want, launchParam: LaunchParam): Unit {
34
- Hilog.info(1, "CjTauri", "MainAbility OnCreated.${want.abilityName}")
35
-
36
- // 1) 沙箱目录要在 run() 之前给定:run(html) 把页面写成文件再以 file:// 加载
37
- // (ArkWeb 的仓颉绑定没有 loadData)。
38
- let filesDir = "${this.context.filesDir}"
39
- ArkWebRuntime.configure(filesDir)
40
-
41
- // 2) 页面与能力清单:从 hap 的 rawfile 读(读不到就是构建期没打进去,如实报一行)
42
- let pageHtml = this.readRawText("index.html")
43
- let capsJson = this.readRawText("capabilities.json")
44
- if (pageHtml.size == 0) {
45
- Hilog.info(1, "CjTauri", "rawfile/index.html 读不到,页面将只显示一句提示")
46
- }
47
-
48
- // 3) run() 会阻塞到 quit(),只能在非 UI 线程上跑——UI 线程要留给 ArkUI 建树。
49
- let _ = spawn { startTauriApp("{{APP_LABEL}}", pageHtml, capsJson) }
50
-
51
- match (launchParam.launchReason) {
52
- case LaunchReason.StartAbility => Hilog.info(1, "CjTauri", "START_ABILITY")
53
- case _ => ()
54
- }
55
- }
56
-
57
- public override func onWindowStageCreate(windowStage: WindowStage): Unit {
58
- Hilog.info(1, "CjTauri", "MainAbility onWindowStageCreate.")
59
- this.logDefaultWindowRect(windowStage)
60
- // 等框架把宿主登记上再建树:组件的 build() 只有在该 label 有宿主、页面地址非空时
61
- // 才渲染 `Web`。等不到也照常 loadContent——页面会自己报桥缺失,比静默白屏好排查。
62
- this.waitAndLogHost(DEFAULT_WINDOW_LABEL)
63
- windowStage.loadContent("EntryView")
64
- }
65
-
66
- /**
67
- * 读 hap 里的 rawfile(路径相对 `resources/rawfile/`)
68
- *
69
- * 读失败返回空串并把原因打进 hilog:调用方按「空 = 没有」降级,不让异常冒到生命周期里
70
- * (生命周期里抛异常,应用直接退,页面上看到的是「点了图标没反应」)。
71
- */
72
- private func readRawText(path: String): String {
73
- try {
74
- let bytes = this.context.resourceManager.getRawFileContent(path)
75
- Hilog.info(1, "CjTauri", "rawfile ${path} bytes=${bytes.size}")
76
- return String.fromUtf8(bytes)
77
- } catch (e: Exception) {
78
- Hilog.info(1, "CjTauri", "rawfile ${path} 读取失败: ${e}")
79
- return ""
80
- }
81
- }
82
-
83
- /**
84
- * 不干预窗口尺寸:**鸿蒙 PC 上系统给的默认窗口就是答案**
85
- *
86
- * 早先这里自己 `resize()` 定尺寸(先按屏幕比例 86%×84% = 2683×1747、后按逻辑 1000×700 vp),
87
- * 两版都是在跟平台的默认窗口抢方向盘:实测系统本来就按桌面形态给一扇约 2/3 屏宽的窗
88
- * (3120×2080 的屏上初始矩形 `[515 281 2090 1394]`,即 2090×1394 px ≈ 1100×734 vp),
89
- * 而紧接着的 resize 把它改成 1900×1330——屏上看到的是「先弹一个尺寸、随即变成另一个」,
90
- * 观感就是窗口莫名跳一下。所以模板**默认不碰窗口尺寸**,只读取矩形打一行日志作凭证;
91
- * 应用真需要固定尺寸时自己调 `windowStage.getMainWindow().resize()`。
92
- * 前提是 `entry/build-profile.json5` 的 `deviceTypes` 写成 `2in1` 且
93
- * `cangjieOptions.checkDeviceTypes=false` 放行——写成 phone/tablet 时系统按手机应用塞进
94
- * 竖屏兼容窗(约 600 宽),那种情况才需要自己定尺寸。
95
- */
96
- private func logDefaultWindowRect(windowStage: WindowStage): Unit {
97
- try {
98
- let screen = getDefaultDisplaySync()
99
- let screenW = Int64(screen.width)
100
- let screenH = Int64(screen.height)
101
- // `densityPixels` 是 **Float32**(.cj.d 里看着像 Float64),先化成整数百分比再参与运算。
102
- let densityRaw = screen.densityPixels
103
- let densityPct = Int64(densityRaw * 100.0)
104
- let mainWin = windowStage.getMainWindow()
105
- let r = mainWin.getWindowProperties().windowRect
106
- Hilog.info(1, "CjTauri", "main window keeps system default ${r.width}x${r.height} px at density ${densityPct}% on screen ${screenW}x${screenH}, rect=[${r.left} ${r.top} ${r.width} ${r.height}]")
107
- } catch (e: Exception) {
108
- Hilog.info(1, "CjTauri", "main window geometry read failed: ${e}")
109
- }
110
- }
111
-
112
- /**
113
- * 有界等待(3s)默认窗口的宿主登记完成,并把页面地址 / 预执行脚本条数打进 hilog
114
- *
115
- * 白屏定位用:宿主把页面落盘后的 file:// 地址必须非空,否则组件拿不到 src。
116
- */
117
- private func waitAndLogHost(label: String): Unit {
118
- var polls = 0
119
- while (polls < 300) {
120
- match (ArkWebRuntime.hostFor(label)) {
121
- case Some(_) => break
122
- case None => ()
123
- }
124
- sleep(Duration.millisecond * 10)
125
- polls += 1
126
- }
127
- if (polls >= 300) {
128
- Hilog.info(1, "CjTauri", "host not registered in 3s: label=${label}")
129
- return
130
- }
131
- Hilog.info(1, "CjTauri", "host registered after ${polls} polls label=${label}")
132
- match (ArkWebRuntime.hostFor(label)) {
133
- case Some(h) =>
134
- Hilog.info(1, "CjTauri", "host pageUrl label=${label} url=\"${h.currentUrl()}\"")
135
- Hilog.info(1, "CjTauri", "host initScripts label=${label} count=${h.initScriptsSnapshot().size}")
136
- case None => Hilog.info(1, "CjTauri", "host missing at loadContent label=${label}")
137
- }
138
- }
139
- }
1
+ package ohos_app_cangjie_entry
2
+
3
+ import kit.PerformanceAnalysisKit.Hilog
4
+ import kit.AbilityKit.Want
5
+ import kit.AbilityKit.UIAbility
6
+ import kit.AbilityKit.LaunchParam
7
+ import kit.AbilityKit.LaunchReason
8
+ import kit.ArkUI.WindowStage
9
+ import ohos.display.getDefaultDisplaySync
10
+ import ohos.resource_manager.*
11
+ import cjTauri.*
12
+
13
+ /*
14
+ * {{PROJECT_NAME}} 的 UIAbility
15
+ *
16
+ * 鸿蒙应用没有「自己起进程跑一个 main」这回事:窗口属于 ArkUI、页面由 ArkWeb 组件承载。
17
+ * 所以桌面的 `main()` 在这里被拆成三段:
18
+ * ① 把沙箱目录告诉框架(`run(html)` 要把页面落到沙箱再以 file:// 加载);
19
+ * ② 在**非 UI 线程**上装配并跑框架应用(`run()` 阻塞到 quit(),UI 线程要留给 ArkUI 建树);
20
+ * ③ 等框架把默认窗口的宿主登记好,再 `loadContent`。
21
+ *
22
+ * 页面与能力清单都是 hap 里的 `resources/rawfile/` 真文件,运行期读成字符串:
23
+ * rawfile/index.html ← 就是桌面工程的 ui/index.html(改了重建即可)
24
+ * rawfile/capabilities.json ← 就是桌面的 capabilities 目录下那份 default.json
25
+ * 好处是 DevEco 里直接点 Build 也能编过(不需要先跑一次生成脚本)。
26
+ */
27
+ class MainAbility <: UIAbility {
28
+ public init() {
29
+ super()
30
+ registerSelf()
31
+ }
32
+
33
+ public override func onCreate(want: Want, launchParam: LaunchParam): Unit {
34
+ Hilog.info(1, "CjTauri", "MainAbility OnCreated.${want.abilityName}")
35
+
36
+ // 1) 沙箱目录要在 run() 之前给定:run(html) 把页面写成文件再以 file:// 加载
37
+ // (ArkWeb 的仓颉绑定没有 loadData)。
38
+ let filesDir = "${this.context.filesDir}"
39
+ ArkWebRuntime.configure(filesDir)
40
+
41
+ // 2) 页面与能力清单:从 hap 的 rawfile 读(读不到就是构建期没打进去,如实报一行)
42
+ let pageHtml = this.readRawText("index.html")
43
+ let capsJson = this.readRawText("capabilities.json")
44
+ if (pageHtml.size == 0) {
45
+ Hilog.info(1, "CjTauri", "rawfile/index.html 读不到,页面将只显示一句提示")
46
+ }
47
+
48
+ // 3) run() 会阻塞到 quit(),只能在非 UI 线程上跑——UI 线程要留给 ArkUI 建树。
49
+ let _ = spawn { startTauriApp("{{APP_LABEL}}", pageHtml, capsJson) }
50
+
51
+ match (launchParam.launchReason) {
52
+ case LaunchReason.StartAbility => Hilog.info(1, "CjTauri", "START_ABILITY")
53
+ case _ => ()
54
+ }
55
+ }
56
+
57
+ public override func onWindowStageCreate(windowStage: WindowStage): Unit {
58
+ Hilog.info(1, "CjTauri", "MainAbility onWindowStageCreate.")
59
+ this.logDefaultWindowRect(windowStage)
60
+ // 等框架把宿主登记上再建树:组件的 build() 只有在该 label 有宿主、页面地址非空时
61
+ // 才渲染 `Web`。等不到也照常 loadContent——页面会自己报桥缺失,比静默白屏好排查。
62
+ this.waitAndLogHost(DEFAULT_WINDOW_LABEL)
63
+ windowStage.loadContent("EntryView")
64
+ }
65
+
66
+ /**
67
+ * 读 hap 里的 rawfile(路径相对 `resources/rawfile/`)
68
+ *
69
+ * 读失败返回空串并把原因打进 hilog:调用方按「空 = 没有」降级,不让异常冒到生命周期里
70
+ * (生命周期里抛异常,应用直接退,页面上看到的是「点了图标没反应」)。
71
+ */
72
+ private func readRawText(path: String): String {
73
+ try {
74
+ let bytes = this.context.resourceManager.getRawFileContent(path)
75
+ Hilog.info(1, "CjTauri", "rawfile ${path} bytes=${bytes.size}")
76
+ return String.fromUtf8(bytes)
77
+ } catch (e: Exception) {
78
+ Hilog.info(1, "CjTauri", "rawfile ${path} 读取失败: ${e}")
79
+ return ""
80
+ }
81
+ }
82
+
83
+ /**
84
+ * 不干预窗口尺寸:**鸿蒙 PC 上系统给的默认窗口就是答案**
85
+ *
86
+ * 早先这里自己 `resize()` 定尺寸(先按屏幕比例 86%×84% = 2683×1747、后按逻辑 1000×700 vp),
87
+ * 两版都是在跟平台的默认窗口抢方向盘:实测系统本来就按桌面形态给一扇约 2/3 屏宽的窗
88
+ * (3120×2080 的屏上初始矩形 `[515 281 2090 1394]`,即 2090×1394 px ≈ 1100×734 vp),
89
+ * 而紧接着的 resize 把它改成 1900×1330——屏上看到的是「先弹一个尺寸、随即变成另一个」,
90
+ * 观感就是窗口莫名跳一下。所以模板**默认不碰窗口尺寸**,只读取矩形打一行日志作凭证;
91
+ * 应用真需要固定尺寸时自己调 `windowStage.getMainWindow().resize()`。
92
+ * 前提是 `entry/build-profile.json5` 的 `deviceTypes` 写成 `2in1` 且
93
+ * `cangjieOptions.checkDeviceTypes=false` 放行——写成 phone/tablet 时系统按手机应用塞进
94
+ * 竖屏兼容窗(约 600 宽),那种情况才需要自己定尺寸。
95
+ */
96
+ private func logDefaultWindowRect(windowStage: WindowStage): Unit {
97
+ try {
98
+ let screen = getDefaultDisplaySync()
99
+ let screenW = Int64(screen.width)
100
+ let screenH = Int64(screen.height)
101
+ // `densityPixels` 是 **Float32**(.cj.d 里看着像 Float64),先化成整数百分比再参与运算。
102
+ let densityRaw = screen.densityPixels
103
+ let densityPct = Int64(densityRaw * 100.0)
104
+ let mainWin = windowStage.getMainWindow()
105
+ let r = mainWin.getWindowProperties().windowRect
106
+ Hilog.info(1, "CjTauri", "main window keeps system default ${r.width}x${r.height} px at density ${densityPct}% on screen ${screenW}x${screenH}, rect=[${r.left} ${r.top} ${r.width} ${r.height}]")
107
+ } catch (e: Exception) {
108
+ Hilog.info(1, "CjTauri", "main window geometry read failed: ${e}")
109
+ }
110
+ }
111
+
112
+ /**
113
+ * 有界等待(3s)默认窗口的宿主登记完成,并把页面地址 / 预执行脚本条数打进 hilog
114
+ *
115
+ * 白屏定位用:宿主把页面落盘后的 file:// 地址必须非空,否则组件拿不到 src。
116
+ */
117
+ private func waitAndLogHost(label: String): Unit {
118
+ var polls = 0
119
+ while (polls < 300) {
120
+ match (ArkWebRuntime.hostFor(label)) {
121
+ case Some(_) => break
122
+ case None => ()
123
+ }
124
+ sleep(Duration.millisecond * 10)
125
+ polls += 1
126
+ }
127
+ if (polls >= 300) {
128
+ Hilog.info(1, "CjTauri", "host not registered in 3s: label=${label}")
129
+ return
130
+ }
131
+ Hilog.info(1, "CjTauri", "host registered after ${polls} polls label=${label}")
132
+ match (ArkWebRuntime.hostFor(label)) {
133
+ case Some(h) =>
134
+ Hilog.info(1, "CjTauri", "host pageUrl label=${label} url=\"${h.currentUrl()}\"")
135
+ Hilog.info(1, "CjTauri", "host initScripts label=${label} count=${h.initScriptsSnapshot().size}")
136
+ case None => Hilog.info(1, "CjTauri", "host missing at loadContent label=${label}")
137
+ }
138
+ }
139
+ }
@@ -1,49 +1,57 @@
1
- {
2
- "module": {
3
- "name": "entry",
4
- "type": "entry",
5
- "description": "$string:module_desc",
6
- "mainElement": "EntryAbility",
7
- /* 鸿蒙 PC 必须声明 "2in1":只写 phone/tablet 时系统按手机应用处理,窗口是竖屏兼容窗。
8
- 构建插件默认把 deviceTypes 限制成 phone/tablet,靠 entry/build-profile.json5 的
9
- cangjieOptions.checkDeviceTypes=false 放行。 */
10
- "deviceTypes": [
11
- "2in1",
12
- "tablet",
13
- "phone"
14
- ],
15
- "deliveryWithInstall": true,
16
- /* 网上取数据(http/https)都需要这条:缺它时请求死在
17
- `SocketException: Failed to create socket: Operation not permitted.`,
18
- 页面上表现为「连不上后台」,看着像网络不通。用不到就删掉这一条。 */
19
- "requestPermissions": [
20
- {
21
- "name": "ohos.permission.INTERNET"
22
- }
23
- ],
24
- "installationFree": false,
25
- "srcEntry": "ohos_app_cangjie_entry.MyAbilityStage",
26
- "abilities": [
27
- {
28
- "name": "EntryAbility",
29
- "srcEntry": "ohos_app_cangjie_entry.MainAbility",
30
- "description": "$string:EntryAbility_desc",
31
- "icon": "$media:layered_image",
32
- "label": "$string:EntryAbility_label",
33
- "startWindowIcon": "$media:startIcon",
34
- "startWindowBackground": "$color:start_window_background",
35
- "exported": true,
36
- "skills": [
37
- {
38
- "entities": [
39
- "entity.system.home"
40
- ],
41
- "actions": [
42
- "action.system.home"
43
- ]
44
- }
45
- ]
46
- }
47
- ]
48
- }
49
- }
1
+ {
2
+ "module": {
3
+ "name": "entry",
4
+ "type": "entry",
5
+ "description": "$string:module_desc",
6
+ "mainElement": "EntryAbility",
7
+ /* 鸿蒙 PC 必须声明 "2in1":只写 phone/tablet 时系统按手机应用处理,窗口是竖屏兼容窗。
8
+ 构建插件默认把 deviceTypes 限制成 phone/tablet,靠 entry/build-profile.json5 的
9
+ cangjieOptions.checkDeviceTypes=false 放行。 */
10
+ "deviceTypes": [
11
+ "2in1",
12
+ "tablet",
13
+ "phone"
14
+ ],
15
+ "deliveryWithInstall": true,
16
+ /* 网上取数据(http/https)都需要这条:缺它时请求死在
17
+ `SocketException: Failed to create socket: Operation not permitted.`,
18
+ 页面上表现为「连不上后台」,看着像网络不通。用不到就删掉这一条。 */
19
+ "requestPermissions": [
20
+ {
21
+ "name": "ohos.permission.INTERNET"
22
+ }
23
+ /* 串口(serial 插件)要在真机上用 USB 串口时,按需再加(⚠️ 可能需要系统签名,
24
+ 普通调试证书装包会报 9568289,加之前先确认你的签名方式——装不上就删掉):
25
+ ,{
26
+ "name": "ohos.permission.ACCESS_DDK_USB"
27
+ },
28
+ {
29
+ "name": "ohos.permission.ACCESS_DDK_USB_SERIAL"
30
+ } */
31
+ ],
32
+ "installationFree": false,
33
+ "srcEntry": "ohos_app_cangjie_entry.MyAbilityStage",
34
+ "abilities": [
35
+ {
36
+ "name": "EntryAbility",
37
+ "srcEntry": "ohos_app_cangjie_entry.MainAbility",
38
+ "description": "$string:EntryAbility_desc",
39
+ "icon": "$media:layered_image",
40
+ "label": "$string:EntryAbility_label",
41
+ "startWindowIcon": "$media:startIcon",
42
+ "startWindowBackground": "$color:start_window_background",
43
+ "exported": true,
44
+ "skills": [
45
+ {
46
+ "entities": [
47
+ "entity.system.home"
48
+ ],
49
+ "actions": [
50
+ "action.system.home"
51
+ ]
52
+ }
53
+ ]
54
+ }
55
+ ]
56
+ }
57
+ }
@@ -1,8 +1,8 @@
1
- {
2
- "color": [
3
- {
4
- "name": "start_window_background",
5
- "value": "#16161D"
6
- }
7
- ]
8
- }
1
+ {
2
+ "color": [
3
+ {
4
+ "name": "start_window_background",
5
+ "value": "#16161D"
6
+ }
7
+ ]
8
+ }
@@ -1,16 +1,16 @@
1
- {
2
- "string": [
3
- {
4
- "name": "module_desc",
5
- "value": "{{APP_LABEL}}"
6
- },
7
- {
8
- "name": "EntryAbility_desc",
9
- "value": "{{APP_LABEL}}"
10
- },
11
- {
12
- "name": "EntryAbility_label",
13
- "value": "{{APP_LABEL}}"
14
- }
15
- ]
16
- }
1
+ {
2
+ "string": [
3
+ {
4
+ "name": "module_desc",
5
+ "value": "{{APP_LABEL}}"
6
+ },
7
+ {
8
+ "name": "EntryAbility_desc",
9
+ "value": "{{APP_LABEL}}"
10
+ },
11
+ {
12
+ "name": "EntryAbility_label",
13
+ "value": "{{APP_LABEL}}"
14
+ }
15
+ ]
16
+ }
@@ -1,6 +1,6 @@
1
- {
2
- "layered-image": {
3
- "background": "$media:background",
4
- "foreground": "$media:foreground"
5
- }
6
- }
1
+ {
2
+ "layered-image": {
3
+ "background": "$media:background",
4
+ "foreground": "$media:foreground"
5
+ }
6
+ }
@@ -1,6 +1,6 @@
1
- {
2
- "identifier": "default",
3
- "windows": ["main"],
4
- "commands": ["greet", "timer", "system:version", "system:ping", "system:echo"],
5
- "events": ["tick"]
6
- }
1
+ {
2
+ "identifier": "default",
3
+ "windows": ["main"],
4
+ "commands": ["greet", "timer", "system:version", "system:ping", "system:echo"],
5
+ "events": ["tick"]
6
+ }