A
Air官方
【Air 系列 · 鸿蒙 PC 适配全记录】50 / 56
■ 应用:AirTex(from TeXstudio)(AirTex)
■ 定位:TeXstudio 移植,LaTeX 编辑器
■ 上游:TeXstudio | 路线:Qt6+QtDeclarative | 版本:1.4.0
■ 开源: https://gitcode.com/Andy88/Harmony-TeXstudio
■ 市场状态:已上架 AGC 应用页: https://appgallery.huawei.com/app/6917614463958004557
■ 官网(免费下载): https://www.shunidc.cn/
————————————————————
开源鸿蒙 PC 社区: https://harmonypc.csdn.net/
PC 社区项目申请: https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://gitcode.com/Andy88/Harmony-TeXstudio
环境搭建文章:https://blog.csdn.net/weixin_52908342/article/details/161343743
▍一、为什么要适配 AirTex
TeXstudio 是 LaTeX 写作场景使用最广的集成编辑环境之一:语法高亮、自动补全、代码折叠、结构视图、多文档管理、模板向导、拼写检查、用户宏,外加 PDF 预览与一键编译。对需要写论文、报告与文档的用户,它是"打开就能干活"的那类工具。把这样完整的 IDE 带到鸿蒙 PC,考验的不是单个控件的能力,而是整套 Qt Widgets 应用在无窗口管理器环境下的工程化生存。
AirTex 是 TeXstudio 4.9.8(master 快照)的全原生移植,走 Qt 6.11.1 + ohos QPA 的双层架构,非重写、非 Web 壳。应用包名 com.airtex.app,版本 1.1.0,deviceTypes 覆盖 phone、tablet、2in1,申请 READ_PASTEBOARD 权限支撑剪贴板交互。PORTING.md 记载 HAP 约 126MB(28 个 .so 共 101MB 加 rawfile 数据 16MB),这是一个重资产应用:TeXstudio 本体 libtexstudio.so 达 29.6MB,PDF 预览、拼写、宏系统的依赖全部随包。验证记录覆盖模拟器 AirSky2in1 全链与 MatePad Mini、MateBook Pro 真机多轮迭代。
▍二、先划清边界:不把编译通过当成适配完成
桌面 TeXstudio 的每一个关键机制都隐含前提:QProcess 能 fork 出 pdflatex、WM 能管理一堆顶层窗口、QMenuBar 交给系统、字体度量交给桌面环境。鸿蒙沙箱把这些前提逐条收回。AirTex 的边界因此逐层重划——TeXstudio 的编辑内核、文档模型、语言数据全部保留原样,凡是依赖桌面环境的服务层换成鸿蒙等价物,并且明确每一处"谁上谁下":
层次 桌面 TeXstudio 鸿蒙侧当前方案
应用入口 main() + QApplication ArkTS EntryAbility + 薄 NAPI libairtexbridge.so
窗口承载 WM 管理的多个顶层窗口 单 XComponent(TEXTURE) surface + ohos QPA(Strategy A 共享 EGLSurface)
主程序形态 可执行文件 add_library(texstudio SHARED),dlopen 加载 29.6MB 本体
菜单/工具栏/标签栏 QMenuBar / QToolBar / QTabBar ArkTS 化:JSON 桥 + 原生弹层(PATCH-AIRTEX-12/14/15)
本地编译 QProcess 启动外部 pdflatex 进程内 libairtextex.so(PATCH-AIRTEX-48)
PDF 预览 poppler-qt5 poppler 26.07.0 + poppler-qt6 自建链入
文件对话框 Qt 内建 系统 DocumentViewPicker(mode 0 打开 / mode 3 另存为)
拼写检查 hunspell 外部依赖 源码内置 static 编入,en/de/fr 词典随包
边界里最关键的一条是本地编译:上游靠外部 TeX 发行版,鸿蒙没有 TeX 发行版且沙箱禁 fork/exec。这个限制后来被 PATCH-AIRTEX-48 以进程内引擎终结,方式在下文详述。
▍三、鸿蒙版的整体架构
README 记载的架构一图流:ArkTS 壳只有一个主页面 Index.ets(约 1900 行),承担启动遮罩、IME 输入条、系统 picker 桥、菜单/工具栏/标签行的原生渲染;NAPI 薄桥按拓扑序 dlopen 全部依赖,Qt 栈、poppler 系与 TeXstudio 本体在同一进程内组装,最终由 core 驱动 QPA 生命周期。
text
ArkTS 壳(entry/src/main/ets)
├─ Index.ets:XComponent(TEXTURE) + 启动遮罩 + IME 输入条 + picker 桥
│ + 菜单栏/工具栏/标签行 ArkTS 渲染(JSON 桥驱动)
└─ NAPI:libairtexbridge.so(薄壳,只链系统库)
↓ dlopen 按拓扑序(RTLD_GLOBAL)
Qt6 栈(AirGis 6.11.1 基座 13 模块 + 自建 libQt6Qml)+ poppler 系
↓ dlsym
libtexstudio.so(应用本体,main→texstudio_ohos_main)
↘ libairtex_core.so(QPA 生命周期/EGL Strategy A/输入注入/桥接)
↘ libqohos.so(ohos QPA,AirCad 同款预编译直接复用)
libairtextex.so(进程内 pdftex+kpathsea+bibtex,编译指令由 buildmanager 接管)
主要目录如下:
text
AirTex/
├── PORTING.md / README.md # 移植档案(补丁清单/验证记录/速查表)
├── entry/
│ ├── src/main/ets/pages/Index.ets # 壳主页面:遮罩、IME、picker、三大 ArkTS 化栏
│ ├── src/main/cpp/ # airtex_core.cpp、napi_init.cpp
│ │ └── qt_platform/ohos_qt6/ # libqohos QPA 源与构建脚本
│ ├── libs/arm64-v8a/ # 依赖 .so 部署(hvigor 整目录打包)
│ └── src/main/resources/rawfile/ # texstudio-share 资源 + texlive 裁剪树
├── native/
│ ├── sources/texstudio/ # TeXstudio 源码树(PATCH-AIRTEX-n 就地标记)
│ ├── sources/teXengine/ # TinyTeX、web2c 交叉构建、libairtextex.so 产物
│ ├── scripts/ # env.sh、build_qtdeclarative.sh、
│ │ # build_poppler_qt6.sh、build_texstudio.sh、
│ │ # build_texengine.sh、prune_tinytex.sh、deploy.sh
│ ├── install/ # Qt6/poppler 依赖前缀
│ └── cross/ # 交叉工具链
└── out/
▍四、核心适配过程
### 1. 依赖矩阵:站在姊妹工程的产物上
TeXstudio 的依赖面很宽,工程按四类处理:Qt6 基座 13 模块直接复用 AirGis 的 native/install(6.11.1 权威版本,与 libqohos 同源构建);QPA 二进制复用 AirCad 的 libqohos.so(含 75 个以上实战补丁);poppler 26.07.0 源码借 AirScape 纯净树、poppler-qt6 满足 TeXstudio 的 pkg-config 三件套探测;hunspell、quazip、qcodeedit、qtsingleapplication 是 TeXstudio 源码内置,全部 static 编入。宏系统依赖的 QJSEngine 必须自建 qtdeclarative——AirLive 虽有现成构建,但其 qtbase 与 AirGis 的 md5 不同,跨构建混用私有 ABI 有风险,build_qtdeclarative.sh 对 AirGis qtbase 重编,耗时约 50 分钟。
### 2. 菜单、工具栏、标签栏的 ArkTS 化
TeXstudio 的原生控件在单 surface 上各有病变:QToolBar 参与布局协商会把停靠面板挤成浮动窗口(bar->hide() 后仍占协商位,实测新建文档即塌缩,A/B 实证记录在 PORTING 四.8)。工程因此把三大栏整体搬到 ArkTS 侧:airtex_get_menubar_json()/airtex_get_toolbar_json()/airtex_get_tabs_json() 三组导出函数把 Qt 侧状态序列化为 JSON(工具栏图标转 b64 PNG,48px),ArkTS 用原生菜单弹层与按钮行渲染,操作经 act/tab 指令队列回投 Qt 线程。配套三律来自血泪教训:按钮列表一次性加载后冻结、必须动态的标签行用稳定 key、易变的 enabled/checked 位不参与重建——否则 ArkUI ForEach 重建瞬间会合成假点击,把会话恢复的文档静默关闭。
### 3. 输入链重建
触摸与软键盘是重灾区,最终形态由多个补丁拼成:ArkUI 对 XComponent native 触摸回调的派发逐会话随机失活(K4),Index.ets 以触摸覆盖层接管后经 napi 转发注入(PATCH-18);QWSI 事件排水原本挂在渲染合成链上,渲染死的会话输入全滞留,core 里加 50ms 定时器无条件泵事件(PATCH-20);软键盘回车不产生 KeyEvent,走 IME action 通道,把输入条换成默认 NEW_LINE 的 TextArea 让换行走 onChange diff 链(PATCH-29);键盘压缩避让会 resize surface 触发 Qt 脆弱 relayout,改 KeyboardAvoidMode.NONE 悬浮(PATCH-16)。
### 4. 进程内 TeX 引擎:K2 的终结
"编译按钮无效"的根因是沙箱禁 fork/exec——buildmanager.cpp 的 QProcess start 必败。PATCH-AIRTEX-48 的做法是把 texlive web2c 的 pdftex、kpathsea 与 bibtex 交叉编成单个 libairtextex.so(构建脚本 build_texengine.sh 做符号手术:main 改名、重复全局符号加前缀、-Wl,-Bsymbolic 防宿主进程同名符号插入,仅导出 airtex_engine_run),再在 ProcessX::startCommand 层拦截接管:引擎契约 airtex_engine_run(argv0, argc, argv, workdir, out_cb) 内部以 dup2 捕获 stdout/stderr、串行互斥(TeX 非可重入)、按需 dump format 文件;输出回调经 Queued invokeMethod 回 Qt 线程,发出与 QProcess readyRead 等价的信号——TeXstudio 的日志面板与错误解析零改动。配套数据侧:prune_tinytex.sh 把 TinyTeX 裁掉 doc/source/man 后生成 texlive 树,Index.ets 首启 8 路并行解压到应用沙箱(stamp 幂等,后台执行不阻塞 GUI)。README 功能表中"本地编译不可用"是 K2 时期的记录,当前代码链已由引擎接管,端到端编译实测尚未写入 PORTING 验证记录。
▍五、适配中遇到的几个难点
### 难点1:所有弹窗点不动,而编辑器"看起来正常"
K1 的表象是 Qt 弹窗与菜单收不到点击。真相由探针定案:core 注入层 button 基准错位——napi 契约 1=左键,QPA 契约 0=左键,漏了减一,左键全成中键;叠加 core 关闭了 Qt 的触摸到鼠标自动合成后,显式注入是唯一鼠标路径,于是弹窗全灭而编辑器焦点/光标走触摸链照常。修复一行(PATCH-25),但后续 30e 又收紧了告警抑制条件:只自动拒绝仅含 OK 单键的 Warning 框,否则关闭未保存文档的"是否保存"会被误杀,用户失去保存机会。
### 难点2:dpr 会话彩票
设备像素比时灵时不灵,探针揭示两个来源:其一,libqohos 由 Qt 插件机制在 QApplication 构造期才加载,qt_gui_thread 启动时 dlsym 全空,显示指标注入被静默跳过——修法是显式 dlopen 后再等指标(PATCH-36);其二,ArkTS 到 napi 到 core 的异步链抢跑,构造 QApplication 前等待 metrics 就绪(PATCH-33)。更深一层是渲染悬崖:dpr 约 2.97 时任何路径新建文档中央区整体空白,疑 QPA 逻辑到物理换算在该非整数 dpr 下的边界问题,终态把 UI_DPI_SCALE 定为 1.125(dpr 约 2.67)规避。字体则因 Qt6 QHighDpi 把 pt 到 px 的换算除回 factor 而减半,改为按 logicalDpi 自适应(PATCH-31/35)。
### 难点3:QApplication 不在主线程,全局钩子全失效
本架构下 QApplication 构造在领养线程,qApp 级 eventFilter 收不到任何事件——应用层抑制器与 QPA 的 PATCH-76 同因失效。改重写 TexstudioApp::notify() 虚函数(线程无关)后真机复验两轮全中。这条结论写进了症状速查表:凡全局事件钩子,一律走 notify() 重写。
### 难点4:无 WM 的窗口自理债
桌面 Qt 依赖 WM 回答的问题——窗口多大、放哪、点击给谁——在单 surface 上全部要自己答。坐标就有三套空间(屏幕/surface/窗口内容),覆盖层坐标一度系统性偏移 287px(PATCH-34a 把屏幕空间当 surface 空间,PATCH-41 定案"覆盖层本地坐标乘 density 即 surface 空间,零偏移");超屏 QDialog 按钮整行在屏外,需钳到屏幕 92%×95% 居中,且第一版无差别钳制把全屏主窗也缩了,只钳 QDialog 才对(PATCH-39 系列);对话框关闭后共享 surface 留残影,需合并强刷可见顶层 repaint。
▍六、编译、安装与启动
native 侧构建顺序在 PORTING 七有明确铁律——build 后必须 install(build 阶段不拷贝),再 deploy,再 hvigor,漏一环就是"修复从未进设备":
bash
source native/scripts/env.sh
bash native/scripts/build_texstudio.sh all # build + install 一体入口
bash native/scripts/deploy.sh # readelf 闭包计算 + ELF 三件套 + rawfile
Qt 依赖首次搭建另需 build_qtdeclarative.sh all(约 50 分钟)与 build_poppler_qt6.sh all;重编 QPA 用 entry/src/main/cpp/qt_platform/ohos_qt6/build_libqohos_qt6.sh。ArkTS 侧标准构建:
bash
export JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
hvigorw --mode module -p module=entry assembleHap --no-daemon
产物位于 entry/build/default/outputs/default/entry-default-signed.hap。安装启动:
bash
hdc install -r entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.airtex.app
PORTING 验证记录(2026-08-18 模拟器、2026-08-23 真机 MatePad Mini 多轮)覆盖启动首帧、完整 UI 渲染、触摸链、中文界面、会话恢复、系统 picker 文件打开与另存为、软键盘全链。
▍七、当前功能边界
当前版本已覆盖的能力(依据 README 功能表与补丁清单):
- LaTeX 编辑器完整内核:语法高亮、自动补全、代码折叠、结构视图、多文档;
- 完整 TeXstudio 界面:菜单栏/工具栏/标签行/停靠面板 ArkTS 化渲染,简体中文默认界面;
- 触摸全链与软键盘输入(含换行键面与多行回显);
- 系统文件选择器打开/保存/另存为,会话恢复;
- 进程内本地编译:libairtextex.so(pdftex+kpathsea+bibtex)接管编译指令,texlive 裁剪树随 HAP 部署;
- 用户宏系统(QJSEngine,自建 qtdeclarative);拼写检查(hunspell,en/de/fr 词典随包);
- 模板与向导(文档类/Beamer/表格/字母);
- 内嵌 PDF 预览的 poppler-qt6 链已编入。
尚未收敛的部分(依据 PORTING 已知问题与 README 记载):PDF 预览已编入但验证记录标注"待实测";K6 小型模态框在高 dpr 下命中穿透(Question 类交互框依赖 Esc/BACK 兜底);K4/K5 触摸与窗口激活链的平台级耦合仍在调查;MateBook Pro 真机装机后尚待解锁验证;上游名已按 PATCH-40 全量替换为 AirTex。
因此,当前版本更准确的定位是"TeXstudio 鸿蒙 PC 编辑与编译基础版":编辑闭环、界面体系与进程内编译链均已落地,预览实测与平台级输入稳定性是下一阶段的验收重点。
▍八、总结
AirTex 是 Air 系列 Qt 路线上集成度最高的移植:29.6MB 的应用本体、四类依赖来源、三大栏 ArkTS 化改造,叠加起来是对"Qt 应用如何在无 WM 沙箱里活成 IDE"的完整回答。它沉淀出的症状速查表与五大根因类分析(窗口自理债、异步链无确认、观测通道不可靠、修复引入新异常、契约不对照)已经超出单项目范畴,成为后续 Qt 移植工程的通用参考。
后续工作按两条线推进:一是验证线,把 PDF 预览实测、本地编译端到端与 MateBook Pro 解锁验证补进验证记录;二是平台线,与姊妹工程合力收敛 K4/K5 的触摸与激活链耦合。TeXstudio 的内核没有动过一行业务逻辑,这意味着平台问题收敛之日,就是这个 IDE 完整能力自然兑现之时。
■ 应用:AirTex(from TeXstudio)(AirTex)
■ 定位:TeXstudio 移植,LaTeX 编辑器
■ 上游:TeXstudio | 路线:Qt6+QtDeclarative | 版本:1.4.0
■ 开源: https://gitcode.com/Andy88/Harmony-TeXstudio
■ 市场状态:已上架 AGC 应用页: https://appgallery.huawei.com/app/6917614463958004557
■ 官网(免费下载): https://www.shunidc.cn/
————————————————————
开源鸿蒙 PC 社区: https://harmonypc.csdn.net/
PC 社区项目申请: https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://gitcode.com/Andy88/Harmony-TeXstudio
环境搭建文章:https://blog.csdn.net/weixin_52908342/article/details/161343743
▍一、为什么要适配 AirTex
TeXstudio 是 LaTeX 写作场景使用最广的集成编辑环境之一:语法高亮、自动补全、代码折叠、结构视图、多文档管理、模板向导、拼写检查、用户宏,外加 PDF 预览与一键编译。对需要写论文、报告与文档的用户,它是"打开就能干活"的那类工具。把这样完整的 IDE 带到鸿蒙 PC,考验的不是单个控件的能力,而是整套 Qt Widgets 应用在无窗口管理器环境下的工程化生存。
AirTex 是 TeXstudio 4.9.8(master 快照)的全原生移植,走 Qt 6.11.1 + ohos QPA 的双层架构,非重写、非 Web 壳。应用包名 com.airtex.app,版本 1.1.0,deviceTypes 覆盖 phone、tablet、2in1,申请 READ_PASTEBOARD 权限支撑剪贴板交互。PORTING.md 记载 HAP 约 126MB(28 个 .so 共 101MB 加 rawfile 数据 16MB),这是一个重资产应用:TeXstudio 本体 libtexstudio.so 达 29.6MB,PDF 预览、拼写、宏系统的依赖全部随包。验证记录覆盖模拟器 AirSky2in1 全链与 MatePad Mini、MateBook Pro 真机多轮迭代。
▍二、先划清边界:不把编译通过当成适配完成
桌面 TeXstudio 的每一个关键机制都隐含前提:QProcess 能 fork 出 pdflatex、WM 能管理一堆顶层窗口、QMenuBar 交给系统、字体度量交给桌面环境。鸿蒙沙箱把这些前提逐条收回。AirTex 的边界因此逐层重划——TeXstudio 的编辑内核、文档模型、语言数据全部保留原样,凡是依赖桌面环境的服务层换成鸿蒙等价物,并且明确每一处"谁上谁下":
层次 桌面 TeXstudio 鸿蒙侧当前方案
应用入口 main() + QApplication ArkTS EntryAbility + 薄 NAPI libairtexbridge.so
窗口承载 WM 管理的多个顶层窗口 单 XComponent(TEXTURE) surface + ohos QPA(Strategy A 共享 EGLSurface)
主程序形态 可执行文件 add_library(texstudio SHARED),dlopen 加载 29.6MB 本体
菜单/工具栏/标签栏 QMenuBar / QToolBar / QTabBar ArkTS 化:JSON 桥 + 原生弹层(PATCH-AIRTEX-12/14/15)
本地编译 QProcess 启动外部 pdflatex 进程内 libairtextex.so(PATCH-AIRTEX-48)
PDF 预览 poppler-qt5 poppler 26.07.0 + poppler-qt6 自建链入
文件对话框 Qt 内建 系统 DocumentViewPicker(mode 0 打开 / mode 3 另存为)
拼写检查 hunspell 外部依赖 源码内置 static 编入,en/de/fr 词典随包
边界里最关键的一条是本地编译:上游靠外部 TeX 发行版,鸿蒙没有 TeX 发行版且沙箱禁 fork/exec。这个限制后来被 PATCH-AIRTEX-48 以进程内引擎终结,方式在下文详述。
▍三、鸿蒙版的整体架构
README 记载的架构一图流:ArkTS 壳只有一个主页面 Index.ets(约 1900 行),承担启动遮罩、IME 输入条、系统 picker 桥、菜单/工具栏/标签行的原生渲染;NAPI 薄桥按拓扑序 dlopen 全部依赖,Qt 栈、poppler 系与 TeXstudio 本体在同一进程内组装,最终由 core 驱动 QPA 生命周期。
text
ArkTS 壳(entry/src/main/ets)
├─ Index.ets:XComponent(TEXTURE) + 启动遮罩 + IME 输入条 + picker 桥
│ + 菜单栏/工具栏/标签行 ArkTS 渲染(JSON 桥驱动)
└─ NAPI:libairtexbridge.so(薄壳,只链系统库)
↓ dlopen 按拓扑序(RTLD_GLOBAL)
Qt6 栈(AirGis 6.11.1 基座 13 模块 + 自建 libQt6Qml)+ poppler 系
↓ dlsym
libtexstudio.so(应用本体,main→texstudio_ohos_main)
↘ libairtex_core.so(QPA 生命周期/EGL Strategy A/输入注入/桥接)
↘ libqohos.so(ohos QPA,AirCad 同款预编译直接复用)
libairtextex.so(进程内 pdftex+kpathsea+bibtex,编译指令由 buildmanager 接管)
主要目录如下:
text
AirTex/
├── PORTING.md / README.md # 移植档案(补丁清单/验证记录/速查表)
├── entry/
│ ├── src/main/ets/pages/Index.ets # 壳主页面:遮罩、IME、picker、三大 ArkTS 化栏
│ ├── src/main/cpp/ # airtex_core.cpp、napi_init.cpp
│ │ └── qt_platform/ohos_qt6/ # libqohos QPA 源与构建脚本
│ ├── libs/arm64-v8a/ # 依赖 .so 部署(hvigor 整目录打包)
│ └── src/main/resources/rawfile/ # texstudio-share 资源 + texlive 裁剪树
├── native/
│ ├── sources/texstudio/ # TeXstudio 源码树(PATCH-AIRTEX-n 就地标记)
│ ├── sources/teXengine/ # TinyTeX、web2c 交叉构建、libairtextex.so 产物
│ ├── scripts/ # env.sh、build_qtdeclarative.sh、
│ │ # build_poppler_qt6.sh、build_texstudio.sh、
│ │ # build_texengine.sh、prune_tinytex.sh、deploy.sh
│ ├── install/ # Qt6/poppler 依赖前缀
│ └── cross/ # 交叉工具链
└── out/
▍四、核心适配过程
### 1. 依赖矩阵:站在姊妹工程的产物上
TeXstudio 的依赖面很宽,工程按四类处理:Qt6 基座 13 模块直接复用 AirGis 的 native/install(6.11.1 权威版本,与 libqohos 同源构建);QPA 二进制复用 AirCad 的 libqohos.so(含 75 个以上实战补丁);poppler 26.07.0 源码借 AirScape 纯净树、poppler-qt6 满足 TeXstudio 的 pkg-config 三件套探测;hunspell、quazip、qcodeedit、qtsingleapplication 是 TeXstudio 源码内置,全部 static 编入。宏系统依赖的 QJSEngine 必须自建 qtdeclarative——AirLive 虽有现成构建,但其 qtbase 与 AirGis 的 md5 不同,跨构建混用私有 ABI 有风险,build_qtdeclarative.sh 对 AirGis qtbase 重编,耗时约 50 分钟。
### 2. 菜单、工具栏、标签栏的 ArkTS 化
TeXstudio 的原生控件在单 surface 上各有病变:QToolBar 参与布局协商会把停靠面板挤成浮动窗口(bar->hide() 后仍占协商位,实测新建文档即塌缩,A/B 实证记录在 PORTING 四.8)。工程因此把三大栏整体搬到 ArkTS 侧:airtex_get_menubar_json()/airtex_get_toolbar_json()/airtex_get_tabs_json() 三组导出函数把 Qt 侧状态序列化为 JSON(工具栏图标转 b64 PNG,48px),ArkTS 用原生菜单弹层与按钮行渲染,操作经 act/tab 指令队列回投 Qt 线程。配套三律来自血泪教训:按钮列表一次性加载后冻结、必须动态的标签行用稳定 key、易变的 enabled/checked 位不参与重建——否则 ArkUI ForEach 重建瞬间会合成假点击,把会话恢复的文档静默关闭。
### 3. 输入链重建
触摸与软键盘是重灾区,最终形态由多个补丁拼成:ArkUI 对 XComponent native 触摸回调的派发逐会话随机失活(K4),Index.ets 以触摸覆盖层接管后经 napi 转发注入(PATCH-18);QWSI 事件排水原本挂在渲染合成链上,渲染死的会话输入全滞留,core 里加 50ms 定时器无条件泵事件(PATCH-20);软键盘回车不产生 KeyEvent,走 IME action 通道,把输入条换成默认 NEW_LINE 的 TextArea 让换行走 onChange diff 链(PATCH-29);键盘压缩避让会 resize surface 触发 Qt 脆弱 relayout,改 KeyboardAvoidMode.NONE 悬浮(PATCH-16)。
### 4. 进程内 TeX 引擎:K2 的终结
"编译按钮无效"的根因是沙箱禁 fork/exec——buildmanager.cpp 的 QProcess start 必败。PATCH-AIRTEX-48 的做法是把 texlive web2c 的 pdftex、kpathsea 与 bibtex 交叉编成单个 libairtextex.so(构建脚本 build_texengine.sh 做符号手术:main 改名、重复全局符号加前缀、-Wl,-Bsymbolic 防宿主进程同名符号插入,仅导出 airtex_engine_run),再在 ProcessX::startCommand 层拦截接管:引擎契约 airtex_engine_run(argv0, argc, argv, workdir, out_cb) 内部以 dup2 捕获 stdout/stderr、串行互斥(TeX 非可重入)、按需 dump format 文件;输出回调经 Queued invokeMethod 回 Qt 线程,发出与 QProcess readyRead 等价的信号——TeXstudio 的日志面板与错误解析零改动。配套数据侧:prune_tinytex.sh 把 TinyTeX 裁掉 doc/source/man 后生成 texlive 树,Index.ets 首启 8 路并行解压到应用沙箱(stamp 幂等,后台执行不阻塞 GUI)。README 功能表中"本地编译不可用"是 K2 时期的记录,当前代码链已由引擎接管,端到端编译实测尚未写入 PORTING 验证记录。
▍五、适配中遇到的几个难点
### 难点1:所有弹窗点不动,而编辑器"看起来正常"
K1 的表象是 Qt 弹窗与菜单收不到点击。真相由探针定案:core 注入层 button 基准错位——napi 契约 1=左键,QPA 契约 0=左键,漏了减一,左键全成中键;叠加 core 关闭了 Qt 的触摸到鼠标自动合成后,显式注入是唯一鼠标路径,于是弹窗全灭而编辑器焦点/光标走触摸链照常。修复一行(PATCH-25),但后续 30e 又收紧了告警抑制条件:只自动拒绝仅含 OK 单键的 Warning 框,否则关闭未保存文档的"是否保存"会被误杀,用户失去保存机会。
### 难点2:dpr 会话彩票
设备像素比时灵时不灵,探针揭示两个来源:其一,libqohos 由 Qt 插件机制在 QApplication 构造期才加载,qt_gui_thread 启动时 dlsym 全空,显示指标注入被静默跳过——修法是显式 dlopen 后再等指标(PATCH-36);其二,ArkTS 到 napi 到 core 的异步链抢跑,构造 QApplication 前等待 metrics 就绪(PATCH-33)。更深一层是渲染悬崖:dpr 约 2.97 时任何路径新建文档中央区整体空白,疑 QPA 逻辑到物理换算在该非整数 dpr 下的边界问题,终态把 UI_DPI_SCALE 定为 1.125(dpr 约 2.67)规避。字体则因 Qt6 QHighDpi 把 pt 到 px 的换算除回 factor 而减半,改为按 logicalDpi 自适应(PATCH-31/35)。
### 难点3:QApplication 不在主线程,全局钩子全失效
本架构下 QApplication 构造在领养线程,qApp 级 eventFilter 收不到任何事件——应用层抑制器与 QPA 的 PATCH-76 同因失效。改重写 TexstudioApp::notify() 虚函数(线程无关)后真机复验两轮全中。这条结论写进了症状速查表:凡全局事件钩子,一律走 notify() 重写。
### 难点4:无 WM 的窗口自理债
桌面 Qt 依赖 WM 回答的问题——窗口多大、放哪、点击给谁——在单 surface 上全部要自己答。坐标就有三套空间(屏幕/surface/窗口内容),覆盖层坐标一度系统性偏移 287px(PATCH-34a 把屏幕空间当 surface 空间,PATCH-41 定案"覆盖层本地坐标乘 density 即 surface 空间,零偏移");超屏 QDialog 按钮整行在屏外,需钳到屏幕 92%×95% 居中,且第一版无差别钳制把全屏主窗也缩了,只钳 QDialog 才对(PATCH-39 系列);对话框关闭后共享 surface 留残影,需合并强刷可见顶层 repaint。
▍六、编译、安装与启动
native 侧构建顺序在 PORTING 七有明确铁律——build 后必须 install(build 阶段不拷贝),再 deploy,再 hvigor,漏一环就是"修复从未进设备":
bash
source native/scripts/env.sh
bash native/scripts/build_texstudio.sh all # build + install 一体入口
bash native/scripts/deploy.sh # readelf 闭包计算 + ELF 三件套 + rawfile
Qt 依赖首次搭建另需 build_qtdeclarative.sh all(约 50 分钟)与 build_poppler_qt6.sh all;重编 QPA 用 entry/src/main/cpp/qt_platform/ohos_qt6/build_libqohos_qt6.sh。ArkTS 侧标准构建:
bash
export JAVA_HOME=/Applications/DevEco-Studio.app/Contents/jbr/Contents/Home
export DEVECO_SDK_HOME=/Applications/DevEco-Studio.app/Contents/sdk
hvigorw --mode module -p module=entry assembleHap --no-daemon
产物位于 entry/build/default/outputs/default/entry-default-signed.hap。安装启动:
bash
hdc install -r entry/build/default/outputs/default/entry-default-signed.hap
hdc shell aa start -a EntryAbility -b com.airtex.app
PORTING 验证记录(2026-08-18 模拟器、2026-08-23 真机 MatePad Mini 多轮)覆盖启动首帧、完整 UI 渲染、触摸链、中文界面、会话恢复、系统 picker 文件打开与另存为、软键盘全链。
▍七、当前功能边界
当前版本已覆盖的能力(依据 README 功能表与补丁清单):
- LaTeX 编辑器完整内核:语法高亮、自动补全、代码折叠、结构视图、多文档;
- 完整 TeXstudio 界面:菜单栏/工具栏/标签行/停靠面板 ArkTS 化渲染,简体中文默认界面;
- 触摸全链与软键盘输入(含换行键面与多行回显);
- 系统文件选择器打开/保存/另存为,会话恢复;
- 进程内本地编译:libairtextex.so(pdftex+kpathsea+bibtex)接管编译指令,texlive 裁剪树随 HAP 部署;
- 用户宏系统(QJSEngine,自建 qtdeclarative);拼写检查(hunspell,en/de/fr 词典随包);
- 模板与向导(文档类/Beamer/表格/字母);
- 内嵌 PDF 预览的 poppler-qt6 链已编入。
尚未收敛的部分(依据 PORTING 已知问题与 README 记载):PDF 预览已编入但验证记录标注"待实测";K6 小型模态框在高 dpr 下命中穿透(Question 类交互框依赖 Esc/BACK 兜底);K4/K5 触摸与窗口激活链的平台级耦合仍在调查;MateBook Pro 真机装机后尚待解锁验证;上游名已按 PATCH-40 全量替换为 AirTex。
因此,当前版本更准确的定位是"TeXstudio 鸿蒙 PC 编辑与编译基础版":编辑闭环、界面体系与进程内编译链均已落地,预览实测与平台级输入稳定性是下一阶段的验收重点。
▍八、总结
AirTex 是 Air 系列 Qt 路线上集成度最高的移植:29.6MB 的应用本体、四类依赖来源、三大栏 ArkTS 化改造,叠加起来是对"Qt 应用如何在无 WM 沙箱里活成 IDE"的完整回答。它沉淀出的症状速查表与五大根因类分析(窗口自理债、异步链无确认、观测通道不可靠、修复引入新异常、契约不对照)已经超出单项目范畴,成为后续 Qt 移植工程的通用参考。
后续工作按两条线推进:一是验证线,把 PDF 预览实测、本地编译端到端与 MateBook Pro 解锁验证补进验证记录;二是平台线,与姊妹工程合力收敛 K4/K5 的触摸与激活链耦合。TeXstudio 的内核没有动过一行业务逻辑,这意味着平台问题收敛之日,就是这个 IDE 完整能力自然兑现之时。
楼主
8 天前