cj-tauri 2.0.0 → 2.1.1
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.
- package/README.md +206 -139
- package/bin/cj-tauri.js +287 -287
- package/cjpm.toml +63 -52
- package/cli/cjpm.toml +22 -22
- package/cli/src/doctor.cj +308 -306
- package/cli/src/main.cj +129 -129
- package/cli/src/manifest.cj +643 -558
- package/cli/src/manifest_test.cj +87 -0
- package/cli/src/project.cj +770 -770
- package/cli/src/resolve.cj +348 -348
- package/cli/src/scaffold.cj +369 -369
- package/cli/src/sync.cj +638 -526
- package/cli/src/util.cj +168 -168
- package/cli/templates/app/README.md +51 -48
- package/cli/templates/app/assets/capabilities/default.json +7 -7
- package/cli/templates/app/assets/ui/index.html +120 -118
- package/cli/templates/app/cj-tauri.toml +32 -22
- package/cli/templates/app/cjpm.toml +34 -34
- package/cli/templates/app/src/main.cj +101 -90
- package/cli/templates/app-react/README.md +56 -56
- package/cli/templates/app-react/assets/capabilities/default.json +7 -7
- package/cli/templates/app-react/assets/ui/index.html +25 -25
- package/cli/templates/app-react/assets/ui/package.json +19 -19
- package/cli/templates/app-react/assets/ui/src/App.css +67 -67
- package/cli/templates/app-react/assets/ui/src/App.jsx +124 -124
- package/cli/templates/app-react/assets/ui/src/main.jsx +6 -6
- package/cli/templates/app-react/assets/ui/vite.config.js +24 -24
- package/cli/templates/app-react/cj-tauri.toml +33 -23
- package/cli/templates/app-react/cjpm.toml +34 -34
- package/cli/templates/app-react/src/main.cj +91 -91
- package/cli/templates/app-vue/README.md +56 -56
- package/cli/templates/app-vue/assets/capabilities/default.json +7 -7
- package/cli/templates/app-vue/assets/ui/index.html +25 -25
- package/cli/templates/app-vue/assets/ui/package.json +18 -18
- package/cli/templates/app-vue/assets/ui/src/App.vue +176 -176
- package/cli/templates/app-vue/assets/ui/src/main.js +4 -4
- package/cli/templates/app-vue/assets/ui/vite.config.js +24 -24
- package/cli/templates/app-vue/cj-tauri.toml +33 -23
- package/cli/templates/app-vue/cjpm.toml +34 -34
- package/cli/templates/app-vue/src/main.cj +91 -91
- package/cli/templates/ohos-skeleton/AppScope/app.json5 +13 -13
- package/cli/templates/ohos-skeleton/AppScope/resources/base/element/string.json +8 -8
- package/cli/templates/ohos-skeleton/AppScope/resources/base/media/layered_image.json +6 -6
- package/cli/templates/ohos-skeleton/README.md +84 -79
- package/cli/templates/ohos-skeleton/build-hap.sh +15 -0
- package/cli/templates/ohos-skeleton/build-profile.json5 +46 -46
- package/cli/templates/ohos-skeleton/entry/build-profile.json5 +26 -26
- package/cli/templates/ohos-skeleton/entry/cjpm.toml +51 -43
- package/cli/templates/ohos-skeleton/entry/hvigorfile.ts +6 -6
- package/cli/templates/ohos-skeleton/entry/oh-package.json5 +9 -9
- package/cli/templates/ohos-skeleton/entry/src/main/cangjie/ability_stage.cj +17 -17
- package/cli/templates/ohos-skeleton/entry/src/main/cangjie/app_host.cj +94 -94
- package/cli/templates/ohos-skeleton/entry/src/main/cangjie/dialog_host.cj +217 -0
- package/cli/templates/ohos-skeleton/entry/src/main/cangjie/index.cj +527 -167
- package/cli/templates/ohos-skeleton/entry/src/main/cangjie/main_ability.cj +139 -139
- package/cli/templates/ohos-skeleton/entry/src/main/module.json5 +57 -49
- package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/color.json +8 -8
- package/cli/templates/ohos-skeleton/entry/src/main/resources/base/element/string.json +16 -16
- package/cli/templates/ohos-skeleton/entry/src/main/resources/base/media/layered_image.json +6 -6
- package/cli/templates/ohos-skeleton/entry/src/main/resources/base/profile/main_pages.json +2 -2
- package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/capabilities.json +6 -6
- package/cli/templates/ohos-skeleton/entry/src/main/resources/rawfile/index.html +92 -92
- package/cli/templates/ohos-skeleton/hvigor/hvigor-config.json5 +5 -5
- package/cli/templates/ohos-skeleton/hvigorfile.ts +6 -6
- package/cli/templates/ohos-skeleton/oh-package.json5 +10 -10
- package/native/build_win.bat +62 -62
- package/native/core/bridge_core.c +1681 -1626
- package/native/core/bridge_core.h +675 -618
- package/native/core/bridge_js.h +108 -108
- package/native/platforms/harmonyos/README.md +115 -6
- package/native/platforms/linux/bridge_linux.c +2787 -2485
- package/native/platforms/windows/bridge_win.c +3745 -3248
- package/native/tests/gtk_threading_probe.c +143 -143
- package/native/tests/test_bridge_core.c +1339 -1228
- package/package.json +53 -53
- package/src/api_system.cj +67 -67
- package/src/app.cj +335 -969
- package/src/app_events.cj +166 -0
- package/src/app_host_ops.cj +287 -0
- package/src/app_run.cj +283 -0
- package/src/app_spec.cj +76 -76
- package/src/arkweb_menu.cj +216 -0
- package/src/arkweb_script.cj +142 -142
- package/src/capability.cj +409 -409
- package/src/clipboard_bridge.cj +178 -0
- package/src/dialog_spec.cj +79 -0
- package/src/dragdrop.cj +26 -26
- package/src/embedded_assets.cj +98 -98
- package/src/host.cj +752 -607
- package/src/host_arkweb.cj +924 -778
- package/src/host_webkit.cj +663 -570
- package/src/host_webview2.cj +663 -570
- package/src/hotkey.cj +66 -66
- package/src/ipc_hub.cj +401 -337
- package/src/ipc_message.cj +286 -286
- package/src/launch.cj +62 -62
- package/src/logging.cj +127 -127
- package/src/menu.cj +197 -197
- package/src/platform/platform_app_context.cj +77 -77
- package/src/platform/platform_assets.cj +33 -33
- package/src/platform/platform_discover.cj +176 -176
- package/src/platform/platform_env.cj +29 -29
- package/src/platform/platform_feature.cj +31 -31
- package/src/platform/platform_page_source.cj +87 -87
- package/src/platform/platform_target_info.cj +32 -32
- package/src/platform_host_provider.cj +87 -87
- package/src/plugin.cj +333 -333
- package/src/plugins/clipboard/plugin_clipboard.cj +152 -152
- package/src/plugins/dialog/plugin_dialog.cj +209 -209
- package/src/plugins/fs/plugin_fs.cj +105 -1
- package/src/plugins/http/http_backend.cj +131 -0
- package/src/plugins/http/http_desktop.cj +195 -0
- package/src/plugins/http/http_ohos.cj +204 -0
- package/src/plugins/http/plugin_http.cj +310 -459
- package/src/plugins/log/plugin_log.cj +105 -105
- package/src/plugins/menu/plugin_menu.cj +158 -158
- package/src/plugins/notification/plugin_notification.cj +154 -154
- package/src/plugins/serial/plugin_serial.cj +458 -454
- package/src/plugins/serial/serial_bridge.cj +194 -194
- package/src/plugins/serial/serial_manager_ohos.cj +92 -0
- package/src/plugins/serial/serial_ohos.cj +529 -0
- package/src/plugins/shell/plugin_shell.cj +258 -258
- package/src/plugins/sqlite/plugin_sqlite.cj +705 -710
- package/src/plugins/sqlite/sqlite_ffi.cj +206 -211
- package/src/plugins/ws/plugin_ws.cj +488 -470
- package/src/process_hidden.cj +174 -174
- package/src/scope.cj +391 -391
- package/src/shell_event.cj +69 -69
- package/src/tests/app_spec_test.cj +130 -127
- package/src/tests/capability_test.cj +243 -243
- package/src/tests/dialog_spec_test.cj +73 -0
- package/src/tests/fake_host.cj +201 -201
- package/src/tests/ipc_hub_test.cj +563 -487
- package/src/tests/logging_test.cj +62 -62
- package/src/tests/platform_contract_test.cj +264 -251
- package/src/tests/plugin_clipboard_test.cj +222 -222
- package/src/tests/plugin_dialog_test.cj +237 -237
- package/src/tests/plugin_fs_test.cj +207 -0
- package/src/tests/plugin_http_test.cj +124 -124
- package/src/tests/plugin_notification_test.cj +205 -205
- package/src/tests/plugin_serial_test.cj +48 -0
- package/src/tests/plugin_test.cj +605 -585
- package/src/tests/plugin_ws_test.cj +40 -40
- package/src/tests/process_hidden_test.cj +129 -129
- package/src/tests/scope_test.cj +350 -350
- package/src/tests/system_host_test.cj +99 -81
- package/src/tests/urlutil_test.cj +53 -53
- package/src/tests/version_test.cj +75 -75
- package/src/tests/window_registry_test.cj +123 -123
- package/src/tray.cj +90 -90
- package/src/urlutil.cj +159 -159
- package/src/version.cj +44 -44
- package/src/window.cj +51 -51
- package/src/window_registry.cj +116 -116
- package/prebuilt/win32-x64/cj-tauri.exe +0 -0
- package/src/plugins/serial/serial_ohos_stub.cj +0 -61
- 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
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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,2 +1,2 @@
|
|
|
1
|
-
{
|
|
2
|
-
}
|
|
1
|
+
{
|
|
2
|
+
}
|
|
@@ -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
|
+
}
|