# MeowOS 核心规范速查(MEOWOS_SPEC_REF) > 单一速查来源。常量/路径**照抄原文**;矛盾处单列「已知矛盾/待确认」。 > 各条末尾 `[源:XX.md]` 标注出处。 --- ## 1. 文件系统路径 ### 1.1 板载(NAND rootfs / /data) - 设置持久化:**板载** `/usr/data/meow/settings.conf`(UBIFS,小文件 <10KB,跨换卡保留)`[SYSTEM_SETTINGS §2][MEOWOS_API §3]` - **组件持久化目录(2026-09-01 用户定案)**:`/data` = `/usr/data` 的符号链接(UBIFS rw,**不随固件**);组件的可变动持久化文件(模型系数/策略/状态缓存等)一律放 **`/data/meow/<组件名>/`**(即 `/usr/data/meow/<组件名>/`),不再平铺在 `/usr/data/meow/` 根。例:`/data/meow/powermgr/power_model.conf`、`/data/meow/netmgrd/net_policy.conf`。存量平铺件(settings.conf、services.d/、sysui.d/、meow_boot_default)保持原位不动。`[WORK_STATE 2026-09-01]` - **板载服务目录**:`/usr/data/meow/services.d/.conf`(M2.54,Data 区,恒定存在、权威优先;首启由 `S89meow_svcd` 预置 `meow_audiod.conf`/`meow_mdns.conf`(**M6.1 服务名统一 meow_\***:旧 `audiod.conf`/`mdnsd.conf` 自动迁移(stop+rm+预置),cd4e2c2 用户定案)。与 TF `MeowOS/services.d/` 双源,同名板载优先 + WARN;板载 `trigger=boot` 服务不依赖卡(拔卡保留)`[meow_svcd.md][meow_svcd.c]` - **主机名**:设置键 `system.hostname`(SET_STR,默认 `meowos`;RFC1035 首标签),`S89meow_svcd` 开机读 settings `sethostname`;供自研 mDNS 应答器公布 `.local` `[SYSTEM_SETTINGS §1][mips-repo/bins/meow_mdns]` - `/etc/meowos_version`:版本唯一来源(launcher 运行时 `load_meowos_version` 读;`MEOWOS_VERSION` 宏仅作 dev 占位兜底)`[DEV_NOTES #4]` - **`/data/meow_boot_default`:开机默认权威标记(O_TRUNC 单值:`0`=MeowOS / `1`=HiByOS)**。由 launcher `meow_settings_save()` 在保存 `boot.default` 时同步写;bootmenu `set_boot_default_meow()`(写 0)/ launcher `set_boot_default_hiby()`(写 1)同文件同语义;bootmenu 开机读它定默认;init 读入不触发、不反向覆盖;`meow.conf` 不再承担 boot_default `[M2.61 同步修复][README][meow_settings.c][meow_bootmenu.c]` - `/tmp`:tmpfs,开机清空;开机模式标记 `/tmp/meow_boot_mode`、电源菜单 `/tmp/meow_power_menu{,_active}`、app 沉浸 `/tmp/meowapp_state` `[BOOT_SELECTOR §1][KEY_CONTROL §9][APPS §3.5]` - 日志启动缓冲 `/tmp/meow_boot.log`(256KB 滚动,卡出现后自动迁卡)`[APPS §4.5]` - IPC socket:`/usr/data/meow_ipc.sock`(AF_UNIX SOCK_STREAM,0666,backlog 4)`[FRAMEWORK_DESIGN §1][WORK_STATE]` - 专项服务 IPC socket:`/usr/data/meow_perf.sock`(meow_svc_perf,收 `MSG_PERF_QUERY→RESULT`)与 `/usr/data/meow_power.sock`(meow_svc_power,收 `MSG_POWER_ACTION→STATUS`),均 0666、可 `--sock`/`MEOW_IPC_{PERF,POWER}_SOCK` 覆盖;power 服务端以 `SO_PEERCRED uid==0` 基础鉴权 `[meow_svc_perf.c][meow_svc_power.c][meow_ipc.h]` - seccomp/分区(勿写):mtd0=uboot mtd1=kernel mtd2=rootfs mtd3=kernel2 mtd4=rootfs2 mtd5=ota(8M 标记) mtd6=userdata `[WORK_STATE]` ### 1.2 TF 卡(挂载点 `/usr/data/mnt/sd_0`,exFAT) ``` /usr/data/mnt/sd_0/ ├── Music/ # 播放器标准索引目录 ├── MeowData//{data,cache} # 应用专属数据(exFAT 无软链,用 env 注入) ├── MeowAPPs/ # 应用(=app.json.package=目录名;app.json+二进制+资源, fonts/, backgrounds/;日志已入 MeowOS/logs[源:审计 2026-08-30]) └── MeowOS/ # MeowOS 专属(一切非必要文件;**MeowOpt 已废弃并入此处的 opt/**) ├── backups/settings/setting.bak # 设置导出默认路径 ├── services.d/ # 服务配置(meow_svcd 的 .conf;TF 源,与板载 /usr/data/meow/services.d 双源,同名板载优先)`[meow_svcd.md]` ├── fonts/// # 多字体库(每 / 一套三件套;见 §5.2) │ ├── font.png # 预渲染灰度 PNG(bit depth 4|8,gen/gen_font.py 产物) │ ├── font.idx # 索引(MFNI v2,gen/gen_font.py 产物) │ └── font.json # 元数据 + sha256 完整性校验(schema 见 §5.2;含 weight+charset+glyph_count) ├── config/fonts/index # 字体列表索引(M2.58:CSV family,weight,path,label,tier,glyph_count;见 §5.7) ├── logs/ # 系统日志 meow_.log + apps/...(见 §3 日志) ├── notifications/(转储区,保留最新 10MB,不被电源事件清;文件 = notifications.log,appended CSV 行) ├── opt/{bin,nyai,sources.list}, lib/, tools/ # 外围工具/二进制(MeowOpt 已废弃并入;mDNS 自研 meow_mdns 在固件,不入此) └── themes/charging// # 充电屏主题(theme.json manifest) ``` `[TF_CARD_LAYOUT §1][APPS 附录][NOTIFICATION_SYSTEM §5]` - 环境注入(launcher 每次启动 app 前):`MEOW_DATA_DIR`/`MEOW_CACHE_DIR`/`MEOW_LOG_DIR`/`MEOW_LOG_APP`(app_id=package)/`MEOW_LOG_LEVEL`/`MEOW_ACTIVITY`/`MEOW_CHAIN`;XDG:`XDG_DATA_HOME`/`XDG_CACHE_HOME`/`XDG_CONFIG_HOME`(=MeowData//{data,cache,config})`[APPS 附录 §2][FRAMEWORK_DESIGN 附录 D2]` - **升级/刷机契约**:升级镜像 = 卡根固定名 **`r3proii.upt`**(`build_fw_apps*.sh` 打包);升级模式=uboot 读 mtd5=`ota:kernel2` 引导 kernel2 自动刷(非传统 UI 升级按钮);failsafe(关机按住 音量加+电源)从卡根 `r3proii.upt` 升级;**`/data/recovery_all`=恢复出厂,危险勿触发**(调试/部署前必须 `rm -f /data/recovery_all`;发现即删+告警——highest-priority 红线)。刷 rootfs 分区不丢卡数据 `[WORK_STATE][APPS §1.3/§6]` ### 1.3 板载 vs TF 划分原则(拔卡降级) - 板载只放**稳定框架+KB 级设置**;日志/字库/媒体等大件一律 TF 卡 `[TF_CARD_LAYOUT §0][SYSTEM_SETTINGS §2]` - 拔卡:launcher/bootmenu/SSH 不死;应用列表"未插卡"、日志回退内存环、字体回退点阵、opt 不可用——均优雅降级 `[TF_CARD_LAYOUT §3]` - 关键配置优先板载(无卡系统能跑);转储/日志可降级 → 卡,无卡 /tmp 回退 `[DEV_NOTES #7]` - **服务配置双源(M2.54)**:板载 `/usr/data/meow/services.d/` + TF `MeowOS/services.d/`,板载优先;板载服务(`trigger=boot`)随 Data 区恒定存在,拔卡不丢(mDNS 应答器托管于此)`[meow_svcd.md]` - rootfs 体积上限:**45,088,768 B(≈45MB)**,回验 0 diff `[BOOT_SELECTOR §1][APPS §6]` --- ## 2. IPC / 接口 ### 2.1 launcher↔app env 注入 `MEOW_LOG_DIR`(卡日志目录,无卡不设)/`MEOW_LOG_APP`(app_id=app.json.package,缺省回退目录名)/`MEOW_LOG_LEVEL`(本 app 级别,系统下发)/`MEOW_ACTIVITY`/`MEOW_CHAIN`;;...; `[APPS §3.5][APP_LOG_MANAGER §3][FRAMEWORK_DESIGN §3]` ### 2.2 meow_ipc 消息协议(AF_UNIX,全小端 LE) - 帧头 16B:`magic=0x4D4F5701`('MEOW'|1)/`version=1`/`type`/`req_id`/`len`;`len` 上限 **MEOW_IPC_MAX=4096**;列表编码 `[u16 count]`+NUL 串 `[FRAMEWORK_DESIGN §1]` - 消息类型:`MSG_HELLO 0x0001↑ / ACK 0x0002↓ / ERR 0x0003↓ / REGISTER 0x0010↑(M4 已落地:无头后台服务注册,m_register_t,保持连接)/ SERVICE_OK 0x0011↓(M4:m_ack_t status=服务 pid)/ SERVICE_STOP 0x0012↑(M4:SIGTERM 不重启)/ MSG_NOTIFY 0x0020↑ / NOTIFY_ACK 0x0021↓ / NOTIFY_DISMISS 0x0022↑ / NOTIFY_LIST 0x0023↓ / NOTIFY_PROGRESS 0x0024↑ / ACT_DECLARE 0x0030↑ / ACT_QUERY 0x0031↑ / ACT_RESULT 0x0032↓ / ACT_FOCUS 0x0033↑ / ACT_BACK 0x0034↑ / NAV 0x0040↑ / SHOW_ACTIVITY 0x0041↓ / PERF_QUERY 0x0050↑ / PERF_RESULT 0x0051↓ / POWER_ACTION 0x0060↑ / POWER_STATUS 0x0061↓ / SYS 0x00F0↓(M4:m_sys_t,SHUTDOWN=1/SVC_DEAD=2 熔断广播)` `[FRAMEWORK_DESIGN §1][meow_ipc.h]` - 媒体:`MSG_META`(元数据)、`MSG_PLAYCTL`(cmd 1=播放2=暂停3=上一首4=下一首5=seek6=播放/暂停toggle——物理键164恒发6由源侧按当前态翻转,launcher 透传)、`MSG_PROGRESS` `[附录 B]` - 专项服务消息号(见 §4):**电源管理 `meow_powermgr`** 0x00D0 QUERY/0x00D1 RESULT/0x00D2 POLICY_GET/0x00D3 POLICY_SET(期1;SET=动作级),期2 0x00D4 HISTORY/0x00D5 HISTORY_RESULT/0x00D6 EVENTS/0x00D7 EVENTS_RESULT;**网络管理 `meow_netmgrd`** 0x00E0 STATUS_REQ/RESULT、0x00E2 IFACE_REQ/RESULT、0x00E4 WIFI_CTL(→0xE5 RESULT)、0x00E6 BT_CTL(→0xE7 RESULT)、0x00E8 CONNS_REQ/RESULT、0x00EA POLICY_GET/SET、0x00EC DNS_CTL(0x00E0-0x00EB 已用,预留 0xEE 事件订阅)。**读级任意调用者、写级(CTL/POLICY SET)仅系统身份**(沿用 svc_power SO_PEERCRED 鉴权模式)`[meow_ipc.h]` - IPC 线程**只读帧+解析+入队**;状态变更主循环单写者(eventfd 唤醒,10ms 热键轮询非阻塞排空)`[FRAMEWORK_DESIGN §0][§6]` ### 2.3 watchdog / supervisor 信号 - 应用返回键=**SIGTERM**(1s 后 SIGKILL 兜底);**SIGUSR1 仅**=沉浸左缘滑动手势,不是返回键 `[APPS §3.5]` - 强杀兜底:应用卡死 = 音量减连按 3 次(间隔 权威签名 = `patch_v2/sdk/meow_ui.h`;MEOW_APP_SDK.md §3-§8 为设计蓝本。 ### 3.1 关键常量 - 屏幕:**480×720**,24-bit RGB(`0xRRGGBB`),内部转 RGB565;文本字号 28(标题/状态栏)/20(正文/按钮) `[MEOW_APP_SDK §2]` - keycode:POWER=116/VOLUMEDOWN=114/VOLUMEUP=115/PLAYPAUSE=164/PREVIOUS=19(注释标 KEY_PREVIOUSSONG,**有疑**)/NEXT=163 `[meow_ui.h][KEY_CONTROL 注:165 才是 prevsong]` - 事件:`on_key(code,is_down)/on_tap(x,y)/on_swipe(dir,dx,dy)/on_tick/on_swipe_progress(x_start,dx)`;`MEOW_SWIPE_LEFT=0/RIGHT=1/UP=2/DOWN=3` `[meow_ui.h]` - 主题:`MEOW_THEME_LIGHT/DARK/AUTO`;`meow_theme{bg,fg,accent,dim,font_title=28,font_body=20}` `[meow_ui.h]` - 控件:`meow_list_source = int (*)(int idx,char *label,int len,void *ctx)`([D2] 定案)`[meow_ui.h]` - 刷新率:`meow_ui_set_refresh_rate(60/30/15)`/`meow_ui_set_refresh_always_max(1)`/`meow_ui_effective_rate()`/`meow_ui_frames_presented()` `[meow_ui.h §7.1]` - 状态栏:`meow_ui_set_statusbar(1/0)`/`meow_ui_statusbar_height()`(非全屏=28,全屏=0)/`meow_ui_set_fullscreen(on)`;状态栏高 **MUI_SBAR_H=28**(用户定 40→28,字号随之为 20)`[MIGRATION_AC §11.1][meow_ui.h]` - 全屏/状态栏收合(M2.5x):launcher 启动 app/切 activity 据 `app.json fullscreen`/`route..fullscreen` 预先设 SDK 全屏(env **`MEOW_FULLSCREEN`** 注入);进入全屏 = 状态栏**向上收出屏顶、只留一条提示线**(新增 `meow_ui_statusbar_collapsed()` 语义,区分「**收合=状态栏缩为提示线**」vs「**隐藏=高度0**」),带自然过渡动画;全屏下**保留左缘返回手势 + 顶部提示线,顶部下滑仍开通知中心(顶部热区缩小)** `[源:用户 2026-08-30]` - 日志:`MEOW_LOG_DEBUG=0/INFO/WARN/ERROR`;`meow_log(lvl,fmt,...)`/`meow_log_set_level`/`meow_log_get_level` `[meow_ui.h §9]` - 通知:见 §4。 ### 3.2 render/控件/图片/输入/IME 签名(关键) - `meow_ui_init(const meow_ui_opts*)`(opts.width/height,0=自动读 fb)/`meow_ui_shutdown`/`meow_ui_width`(480)/`meow_ui_height`(720) - 绘制:`meow_ui_clear/put_px/fill_rect/draw_rect/draw_rect_round/fill_rect_alpha(color,alpha 0-255)/flush/flush_region` - 文本:`meow_ui_text/text_right/text_center(x,y,utf8,size,color)/text_width/text_height` - 图片:`meow_img_load_file/mem/free/w/h`/`meow_ui_img/scaled/alpha/cover`(stb_image 解 PNG/JPEG/BMP,最近邻缩放,`cover`=居中裁方) - 控件:`meow_btn_create/slider_create/switch_create/list_create(count,src,ctx)/widget_free/draw/hit`;`meow_slider_set/get`、`meow_switch_set/get`、`meow_btn_pressed` - IME:`MEOW_IME_ASCII/NUM`;`meow_ime_ctx{mode,buf[256],maxlen,on_change,ctx}`;`meow_ui_text_input`(阻塞)/`_async`/`meow_ime_active`/`meow_ime_text`(仅英文/数字 ASCII;键盘占底 ~300px) - 生命周期:`meow_ui_run(&ev)`(阻塞)/`meow_ui_request_exit()`;`meow_ui_time_ms()`(单调 ms) ### 3.3 实现定案(相对设计稿)`[MEOW_APP_SDK §12][meow_ui.h]` - [D1] `meow_ui_opts` 补 width/height;[D2] `meow_list_source` 定案签名;[D3] 内部 `meow_gfx_fill_round/blit_rgba/mark_dirty`(非公共);[D4] 新增 `meow_theme_defaults(mode)`/`meow_theme_current()`;[D5] `on_swipe_progress`+`meow_ui_swipe_hint(x)`+内部 `MEOW_EV_SWIPE_PROGRESS`/`meow_input_inject`;[D6] 状态栏高=40(后续用户定 40→28);[D7] 音量源=settings.conf `audio.volume`;[D8] 蓝牙读 `hciconfig` 30s 缓存;[D9] 状态读取器跑在 `meow_ui_run` 1s 节流(无独立线程);[D10] 全局返回默认语义="APP 未注册 on_swipe 时 SDK 默认退出;已注册交 APP" - **构建取向(已知设计,非缺陷)**:`build_sdk.sh` 用 `-I../meow_launcherd` 引 `meow_ipc.h`(`meow_notify_ipc.c` 复用共享协议头),故 SDK 编译期依赖 launcher 头、**非独立库**;**运行时无碍** —— App 只链 `meow_ui.a`(含 meow_font.o),不会链入 launcher 符号。SDK 编译依赖 launcher 头属已知设计,勿当作耦合错误。 ### 3.4 SDK 统一控件库 + 主题增强(M2.70/M2.71 落地)`[MEOW_APP_SDK §5.8/§8.1][meow_ui.h][meow_ui_widget.c]` > 定位:把 §5(最小控件集)与设计模板(§5.2-§5.7)收敛到**统一控件架构**;实现分两批(§5.8.8)。 - **第一批 = 通用基座(M2.70/0.7.65)**:`meow_widget` 基座统一标准控件/自定义画布;`meow_widget_opts`(Modifier 式 Options,`meow_widget_set_opts`/`meow_widget_opts_get`,0/-1 用默认);统一状态机 `MEOW_WS_ENABLED/SELECTED/FOCUSED/PRESSED`(`meow_widget_set_state`/`meow_widget_state`/`meow_widget_enabled`/`selected`);`meow_widget_custom_create`(自定义画布,App 给 render/hit 回调,`W_CUSTOM`);布局 `meow_row/column/box`+`meow_layout_add/arrange`+`spacer`;MD3 语义色板(§5.8.4)+ 主题接口 `meow_ui_set_style`(`MEOW_STYLE_MD3/MIUIX`)`/meow_theme_get`。 - **第二批 = Material 组件子集(M2.71/0.7.66)**:`meow_btn_create_variant`(五型)/`meow_textfield_create`(IME)/`meow_card_create`/`meow_divider_create`/`meow_badge_create`/`meow_checkbox_create`/`meow_radio_create`/`meow_progress_create`/`meow_progress_circular_create`/`meow_fab_create`/`meow_topappbar_create`/`meow_navigationbar_create`/`meow_tabbar_create`/`meow_lazycolumn_create`/`meow_lazyrow_create`/`meow_dialog_create`/`meow_sheet_create`。 - **M2.73 控件库修复(`meow_ui.a` md5 `e8341975`,`[meow_ui_widget.c][meow_ui_ime.c]`)**:① `W_LIST`(含 LazyColumn/LazyRow,`meow_widget_draw` case W_LIST)**视口裁剪**——按 `vx0/vx1/vy0/vy1` 只绘制落在视口内的行/分隔线/文本,杜绝「行滚出视口仍画/标脏上屏」的标题栏/底部脏区(SDK 全局,非 App 侧);② **z 序**:App 侧 `hello_app/hello.c` 的 `d_paint_region` 局部刷新改按 z 栈重画(内容→标题→slider 值→chrome),根治「层动态控件实时重绘盖住/抹掉上层 FAB」;**SDK 级全局 z 序已落地并并入视图框架**(`meow_ui_view.c` 广播注册表 z 序:自动注册 + 子>父 + `set_z(999)` 置顶 + 收敛 live_btn,agent-176 · M2.76),hello App 层 `d_paint_region` 临时方案退役(agent-195 绘制期通用 clip `g_clip_stack[16]` 根除越界脏区);③ 渲染残影/脏区:局部刷新不再「清底+只画单个控件」(改 z 栈重画),消除重叠区残留;④ **IME 行为**(`meow_ui_ime.c`):键盘区背景快照/恢复(`ime_capture`/`ime_restore`,无残影)、配色走主题(不再硬编码黑底白键)、shift 大小写、阻塞 `meow_ui_text_input` 在打字循环喂 `meow_ui_activity_ping`(重置息屏计时,进度条不卡死)、OK(回车)=提交并关闭 / ESC(X)/背景点=取消;回显条=**实时输入回显**(`"%s_"` 拼接,非候选/联想),**候选框留中文输入法再做**。 - **兼容**:既有 `meow_btn/slider/switch/list_create` 签名一字不改(Options/状态机走新增挂载器);`meow_ui_theme`/`meow_widget` 结构变化 = **`meow_ui.a` ABI 变化** → 需同步重编 hello(§5.8.8)。 - **主题增强(§8.1)**:主题 = **顶级风格族 `ui.style`(md3/miuix)× 明暗 `display.theme`(dark/light)** 共同决定「整套配色+控件形态+背景底」;`display.background` 为「style×mode」派生的**可选背景底选项集**(非独立维度);状态栏图标随 `ui.style` 换集。⚠️ **`miui`/`miuix` 命名待定案(保留,勿拍板)**:`MEOW_APP_SDK §8.1` 用 `miuix`;`SYSTEM_SETTINGS §1` 注明 `meow_settings.c g_defs` 现值 `"md3,miui"`(label "Material You,MIUI"),实现时把 `g_defs` 的 `miui` 对齐为 `miuix`(**MIUIx 未实现,当前仅 md3 生效**)。 --- ## 4. SDK 之外系统组件 - **系统进程 supervisor 树(源:2026-08-30 定案;M2.71 已落地 `meow_sysui`)**:`meow_sysui`(`patch_v2/meow_sysui/meow_sysui.c`,~113KB;`etc/init.d/S70meow_sysui` 开机拉起,早于 S89)监管系统进程,**一个崩→只拉起它,绝不级联**;`meow_launcherd`=系统 UI 渲染宿主(状态栏/通知中心/电源菜单/全局手势,与 APP 进程独立);`meow_svcd`=服务管理器(服务全子进程化,svcd 自身不死);APP 进程只渲染自己内容,崩不连累系统 UI。**系统组件渲染归系统进程(launcher),APP 进程不渲染系统 UI**(SDK 系统组件 API 仅系统进程可链,App 不可自建悬浮层);通知中心 UI 渲染主体=系统进程,数据经 IPC 从通知存储读。现网(bootmenu execv launcher + S89 svcd 自启)→ 定案(sysui 统一监管)为渐进迁移,属系统基建线。**已迁移(M2.83)**:sysui 默认监护 `meow_svcd` + `meow_launcherd`(`/usr/data/meow/sysui.d/.conf`,目录式复用 services.d 语义;`sysui.d/launcher.conf` `enabled=1`(restart=always/backoff=3000/max_restart=5),bootmenu 在 MeowOS 模式让位——sysui 在则不 exec launcher;mdns 是 svcd 服务子进程,不双重管理)。`[FRAMEWORK_DESIGN §10][MEOW_APP_SDK §6.1][NOTIFICATION_SYSTEM §9][patch_v2/meow_sysui/meow_sysui.md]` - **专项子服务(一期 M2.73 已落地,规划见 `devdocs/plan/SYSTEM_FRAMEWORK_SERVICES.md`)**:两个 **svcd 托管、板载 `trigger=boot`** 的专项子服务——`meow_svc_perf`(性能/系统只读聚合)、`meow_svc_power`(关机/重启/升级/回 HiBy 系统动作)。launcher 电源菜单与 MeowPanel 均改经这些服务 IPC 触发(不再直连 `sys_do_reboot`/爬 `/proc`)。**IPC**:perf 走 `/usr/data/meow_perf.sock` `MSG_PERF_QUERY→RESULT`;power 走 `/usr/data/meow_power.sock` `MSG_POWER_ACTION→STATUS`(服务端 `SO_PEERCRED uid==0` 基础鉴权)。**M2.73**:perf 增 **network** 子集(SYSTEM 子集输出:真实 WiFi `wpa_cli`/`ip` + 蓝牙 `hci0`/sysfs + `hostname_local`,单点权威源);power **升级写保护**(`upgrade` 写 mtd5 前校验卡根 `r3proii.upt` 存在+可读+常规文件+size>0,失败不写 mtd5/不重启;**只完整性不签名**,海贝官方固件无签名,期望 md5/hash 二期)与 **`dac status` 读板载 `settings.conf` 的 `audio.volume` 真实值**(`settings_get_int_trim`,弃 amixer dummy;`dac on/off` 因 cs43198 `pwr_gpio=-1` 无控制点→`MEOW_ERR_NODEV`)。新 md5:perf `7ea196de`(M2.75 补 network 闭合括号)、power `306df962`(2B 面板精确绑定)。**电源 CLI `meow_svc_power `**(root 免鉴权、单一命令、不覆盖系统 shutdown/reboot):`shutdown`/`reboot[--hiby]`(强制回 MeowOS)/`upgrade`(写 mtd5=`ota:kernel2`,含写保护)/`set-default-meow`/`set-default-hiby` + `status`/`battery`/`reboot-reason`/`upgrade-status`/`screen on|off|timeout<秒>`/`dac on|off|status`。**二期签名鉴权已落地**(agent-185 2A / agent-221 2B):关键 IPC 只接受 **`os.meow.*`** 签权 + `.mpk` 打包签名验签(解包验签/导出保留签名;多公钥数组 + v2 签名块);读级命令鉴权已放宽到任意调用者(agent-189)。`[SYSTEM_FRAMEWORK_SERVICES][APPS 附录 §3][meow_svc_perf.c][meow_svc_power.c]` - 通知(SDK `meow_notify_*`,M2.53 最小版 `[meow_ui.h §9.1]`): - 常量:`MEOW_NOTIFY_MAX_TYPES=4`/`MEOW_NOTIFY_MAX_PER_TYPE=4`/`MEOW_NOTIFY_MAX_MEDIA=1`/`MEOW_NOTIFY_TIMEOUT_ONGOING=-1`/`MEOW_NOTIFY_TIMEOUT_NEVER=0` - 分类:`CAT_GENERAL/MESSAGE/EMAIL/EVENT/PROGRESS/MEDIA(=5)/COUNT`;紧急度 `URG_LOW/NORMAL/HIGH/CRITICAL` - `meow_notify_register_type(cat)`/`meow_notify_send(const meow_notify*)`(返回 id)/`meow_notify_cancel(id)`/`meow_notify_active_count`/`count_in_type`/`has_active`/`urgency_str`/`category_str` - **通知中心 UI 已落地**(launcher 渲染,M2.65+);**D-Bus 桥(A-14)未实现**(待后续);真实投递走 launcher IPC `[meow_ui.h 注释]` - `meow_config_*`(app 配置读写,走 meow_settings 后端)——**已落地**(agent-158 · `dcba597`,见 `devdocs/plan/SDK_CONFIG_API.md`)`[WORK_STATE]` - `meow_media_*`(媒体会话)——**已落地**(agent-204 M2.81 媒体会话 + agent-206 M2.82 SDK `meow_ui_media.c` 懒连重连封装)`[WORK_STATE]` - 崩溃捕获/看门狗——**已落地**:`meow_crash`(agent-187 · `cf86cbd` 系统级崩溃捕获 + sycd 上报)+ App 崩溃直报(agent-199)+ watchdog(应用看门狗,S89 预置)`[WORK_STATE]` - `meow_notify_dbus`(org.freedesktop.Notifications 桥)——**已定,待实现** `[FRAMEWORK_DESIGN 附录 C]` - **meow_svcd 服务管理器**(`patch_v2/meow_svcd/`,mipsel 静态 ~101KB 进固件,不入卡)`[meow_svcd.md]`: - 类 systemd/systemctl。**已接入系统启动链(M2.54)**:固件 `etc/init.d/S89meow_svcd` 开机自启(`-f` 前台 + 重挂循环,失败不死;置于 S84ssh 之后、S90meow_bootmenu 之前——因 S90 exec 引导选单阻塞 rcS)。由 bootmenu/launcher `fork/exec` + `waitpid` 托管仍为备选。 - **双源 services.d**(板载优先):板载 `/usr/data/meow/services.d/.conf` + TF **`MeowOS/services.d/.conf`**,两处都读;同名服务板载优先(TF 同名跳过 + WARN「 板载与 TF 都存在,采用板载」)。目录式 `key=value`,未知键忽略/前向兼容:`exec`(必填)/`args`/`env`/`enabled`(0=永不自动启动,默认0)/`restart`(`always`/`on-fail`/`never`,默认on-fail)/`backoff_ms`(默认1000)/`max_restart`(默认5)/`cap`(本阶段仅解析不实装)/`trigger`(`boot`/`card-mount`/`wifi-up`,默认card-mount)。 - **板载-trigger=boot 语义**:板载服务恒定存在,boot 触发不依赖卡(拔卡保留);TF 服务 boot 仍需卡。 - **服务目录规则**:**固件工具**→板载 `/usr/data/meow/services.d/.conf`(Data 区,拔卡保留);**TF 工具/第三方**→TF `MeowOS/services.d/.conf`(随卡存在/消失);**双源板载优先**(TF 同名被板载屏蔽 + WARN「 板载与 TF 都存在,采用板载」)。 - 崩溃隔离:服务=svcd **独立子进程**(`fork+execv`),svcd 只 `waitpid`/`SIGCHLD` 感知;服务死不影响 svcd/supervisor;重启受 `backoff_ms` 退避防热循环。 - 状态机:`DISABLED/STOPPED/RUNNING/STOPPING/FAILED`;稳定运行 30s 清零 restart_count。CLI(systemctl 式,SSH 直呼):`status/reload/start|stop|restart /pid`,示例 `meow_svcd status`/`meow_svcd restart meow_mdns`/`meow_svcd stop all`/`meow_svcd reload`;控制走 AF_UNIX 单行文本 `/tmp/meow_svcd.sock`;守护默认后台,`-f/--foreground` 前台供 supervisor 托管。 - **M2.73 悬垂指针修复(md5 `da6ebc66`)**:`scan_and_reconcile` 用 `*s=tmp` 整体拷贝后,`s->argv[]` 仍指向已销毁的 `tmp` 栈帧 → `execv`/`/proc/pid/cmdline` 错乱。修法:新增 `svc_rebuild_argv(s)`,赋值/`memmove` 左移后把 `s->argv[]` 重定位到 `s->exec`/`s->argbuf` 自身成员(删除一个服务后同 tick 内被拉起不再用错位 argv)。`[meow_svcd.c]` - **卡上外部工具 = `MeowOS/opt/`**(`{bin,nyai,sources.list}, lib/, tools/`):MeowOS 启动时从卡加载,拔卡降级不崩。**`MeowOpt` 已废弃并入此处**;mDNS 已改为自研 `meow_mdns`(固件 `/usr/bin`),不再放卡。`[DEV_NOTES][meow_svcd.md]`。**MeowPanel 本体 = `MeowOS/opt/MeowPanel/`**(后端+前端,svcd 托管 `MeowOS/services.d/meowpanel.conf`,无卡跳过、系统核心不依赖,不进固件;md5 `8108852f`(nyai 路径修复)→ 阶段C 后 新 md5(见 `patch_v2/meowpanel/README.md`),详见 `patch_v2/meowpanel/README.md`)。 - **MeowPanel(外置 TF 卡 Web 面板,M2.73 已落地,阶段 C 实时画面+遥控已落地)**:单进程 HTTP/JSON 后端(8080)+ 静态托管(`/`→index.html、`/assets/*`)+ `meow_svc_perf`/`meow_svc_power` IPC 客户端(读侧透传 perf 聚合、动作侧经 power)+ `settings.conf` 设置镜像(`key = value` 带空格 + 精确匹配)+ 文件白名单(`MeowOS/Music/MeowData/MeowAPPs/book`,`..` 逃逸→403)+ 应用(`nyai install/export/remove`,包名=`app.json.package`,`nyai` 固件内置 `/usr/bin/nyai` 优先+卡上回退)+ 按键注入(evdev,只音量/电源/播放/上下曲,**禁返回158/主页172/确认28/退出96**)+ 日志(`MeowOS/logs`)。M2.73:系统页「以太网」→「**蓝牙**」栏(无网口有蓝牙);**OTA 检查升级 bug 已修**(改读 `GET /api/system` 的 `ota`,不再误触 `POST /api/system/ota` 升级)。**M2.78+ 新增**:可选密码鉴权(agent-196,默认关)、通知中心后端 `/api/notifications`(TF 归档环形 200 条)、文件域 4 bug 修复 + 上传 8MB 上限 + 双重白名单(agent-182)**。**M2.84-88 阶段 C**(agent-224):`/api/screen.jpeg`(fb0 活动帧→自研 JPEG 编码器)+ `/api/input/tap`(坐标注入,本机触摸优先 5s 仲裁)+ 屏幕增量帧 `?delta=1`(8x8 块比对,近静态 27KB→804B,agent-234)+ `/api/notifications` 实时化(优先 IPC 读 launcher 活跃集 source:ipc,agent-234)。**252 新增(2026-09-01)**:`/api/audio`(audiod MSG_AUDIO_QUERY→STATE 只读透传,不在时 available:false)+ 前端「音频」页(5s 轮询只读)与「字体」页(列表/上传进度/导出/409 冲突确认 force 重试)。**⚠️ 鉴权默认关**(内网信任模型;`reboot/shutdown/ota/apps/删除/上传` 危险端点勿暴露公网,power 侧有 `SO_PEERCRED uid==0` 基础校验)。`[patch_v2/meowpanel/][devdocs/plan/MEOWPANEL_PROTOCOL.md]` - **mDNS 应答器 = `meow_mdns`(自研,已拍板替代完整 mdnsd)**:`mips-repo/bins/meow_mdns/`,**IPv4-only**(内核无 IPv6,完整 mDNSResponder/SAResponder 均 `socket(AF_INET6)` 失败),mipsel 静态 ~79KB(md5 b23de7ce)。**进固件 `/usr/bin/meow_mdns`**(不入卡),由 meow_svcd 托管(板载 `/usr/data/meow/services.d/meow_mdns.conf`,`trigger=boot`、root 即可绑 5353/组播,`cap=` 空)。功能:join `224.0.0.251:5353`,应答 `.local` A(wlan0 IPv4)/`_ssh._tcp` PTR/SRV/TXT/`_services._dns-sd` PTR;支持 `MEOW_MDNS_HOST`/`_ADDR`/`_PORT`/`_TTL`/`_CF`/`_QD`/`_MCAST`/`_MIF`/`_DBG`。⚠️ **手机热点隔离**:设备→主机组播被热点丢弃,avahi 只收组播应答 → 该热点下 `avahi-resolve .local` 超时(网络层限制,非应答器缺陷),主机需 DNS 兜底 `[mips-repo/bins/meow_mdns/manifest.md][meow_svcd.md]`。 - `meow_settings_*`(设置后端,已定)/`meowcli`/`meow_sys_devattr`/`meow_devattr_set` `[MEOWOS_API]` - **独占音频守护 `meow_audiod`(M2.90 已落地,规范 `devdocs/plan/AUDIOD_DESIGN.md`)**:板载 `/usr/bin/meow_audiod`,svcd 托管(板载 `services.d/meow_audiod.conf`,trigger=manual;launcher 确认 MeowOS 模式后拉起;**启动门控:mode≠meow → exit(0),HibyOS 下不存在**)。IPC `/usr/data/meow_audio.sock`(帧层复用 meow_ipc.h,号段 0x00C0-0x00CA:OPEN/OPEN_ACK/WRITE/PAUSE/RESUME/STOP/PREEMPTED/QUERY/STATE/ROUTE/VOLUME)。**独占+抢占**(后开赢,旧流收 PREEMPTED;socket EOF=回收;软混音已否决,留接口位)。**DAC 原生率跟随不做 SRC**;格式归一 S16 直通/S32 升位/mono 复制;切率 mute-重配-恢复。**meow_route 已并入为路由线程并退役独立服务**(⚠️ 退役服务要清板载+TF 双源 conf,否则旧 conf 会双写路由)。**CLI `meow_audio`**(root 免鉴权):`status`/`tone [freq] [ms] [rate]`(正弦测试音,排查无声不开 App)/`route <0|2|3>`/`vol [0-100]`。SDK 客户端 `meow_audio_open/write/pause/close/query/on_preempt`(`meow_ui_audio.c`,懒连接+EPIPE 标死;无 audiod → -ENOENT 不隐式直开,`MEOW_AUDIO_DIRECT=1` 仅调试)。**M2.91-97 加固批**:①**开机武装 hbc3000 FPGA**(M2.91:路由线程启动无条件写 Output Port Switch 4.4→3/3.5→2/无→4,同值先写 5 强制重烧——根治「未烧 FPGA 时 PCM 第二次 `hbc3000_start` 内核硬挂死」,调查底稿 `devdocs/plan/AUDIO_HANG_INVESTIGATION.md`)②**长流护栏**(M2.93:ring 有界等待/cond timedwait/popen 有界收割/O_NONBLOCK+poll 写/wedge 自救/心跳 watchdog)+**几何收窄 period=1024×4**(M2.94:驱动默认巨 buffer 致桥周期中断稀缺 wedge、播 ~12s 停摆;tonepcm2 矩阵 60s 零 stall 实证)③**音量反转**(M2.95:CS43198 音量寄存器=衰减量,四路统一 `dac=255-pct*255/100`)④**炸耳安全**(M2.96:`dac_vol_mute` 写 255 真静音,旧写 0=最大响度)⑤**电平监控**(261,待 M2.97 固件化:播放线程 ~100ms 窗口整数 RMS/peak dBFS(deci-dB,逐帧判边界,-990=-inf)、`MSG_AUDIO_STATE` 追加 `rms=/peak=/lvlseq=`(ABI 兼容)、流活跃时 1s 节拍写 TF `MeowOS/logs/audio_monitor_.log`、CLI `meow_audio monitor [秒]` 文本电平条)。`[patch_v2/meow_audiod/]` - **功耗管理服务 `meow_powermgr`(期0 调研 + 期1 骨架 M6.0 已落地,期2 M6.1,规范 `devdocs/plan/POWER_MANAGER_DESIGN.md`)**:板载 `/usr/bin/meow_powermgr`,svcd 托管(板载 `services.d/meow_powermgr.conf`,`trigger=boot`;**HibyOS 模式只读降级**——只采样电池,绝不放策略/不碰 wlan0/bt/声卡)。双形态 CLI **`meow_power`**(同二进制 argv[0] 分流)。**期0 事实**(`devdocs/plan/POWER_HW_FACTS.md`):`battery/current_now` **不存在**→实时功率只能 `derived+estimated` 双轨、`cpufreq` **不存在**→省电档无降频点、**背光量程 0-101**(非 255!「亮度跳 100」=满量程、默认 101=满亮的根因)、`axp_battery` 是幻影设备、**mp2731 有 `current_now`**(充电功率可测)、rfkill×4 存在(期3 控制点)、无 thermal/hwmon。**期1**:权威充电态链复用(mp2731-charger/status)+ 经验模型 14 系数(`/data/meow/powermgr/power_model.conf` 可调)+ IPC 0x00D0-D3(QUERY/RESULT/POLICY_GET/POLICY_SET)+ CLI `status/estimate/model`。**期2(M6.1)**:`history`(**30s 环形、4h 不落盘**)+`top`(功耗分解排序,2s)+`events`(充放电/低电/亮灭屏/背光跳变事件流)+模型细化(**WiFi 未关联档**、**BT rfkill/ACL 档**)+ **mp2731 `current_now` 实测充电功率**(`charge_confidence=measured`;放电仍 `estimated`,诚实区分)。系数/状态路径 = **`/data/meow/powermgr/`**(组件持久化目录定案,SPEC_REF §1.1)。IPC 0x00D4-D7(期2 HISTORY/EVENTS)。`[patch_v2/meow_powermgr/]` - **网络管理服务 `meow_netmgrd`(期1 M6.0 已落地,期2/期3 M6.1,规范 `devdocs/plan/NETMGR_DESIGN.md`)**:板载 `/usr/bin/meow_netmgrd`,svcd 托管(板载 `services.d/meow_netmgrd.conf`,`trigger=boot`);双形态 CLI **`meow_net`**(`status/iface/wifi/bt/rfkill/apps/conns/top/dns/policy/help`)。**HibyOS 模式只读降级**(接口状态可查,绝不下发控制),RSS 预算 ≤1MB。期0 内核事实(`devdocs/plan/NETWORK_HW_FACTS.md`):**无 iptables 用户态/无 cgroup/无 conntrack → 内核级每应用管控不可行**,主杠杆 = **DNS 代理(域名级)+ 连接普查(inet_diag)+ SDK 自愿通道**;**双行 resolv.conf 崩溃零断流**。**期1 = 接口统一层**(iface 枚举+热插拔/WiFi `wpa_cli` 有界收割/BT `hciconfig`+`bluetoothctl`/rfkill/IP 路由 DNS 只读/udhcpc 续租释放仅 MeowOS)。**期2 = 连接普查 + DNS 代理**:2s `/proc/net/{tcp,udp}` 普查(inode→pid→**三实体** `app:<包名>`(查 amsd)/`svc:<服务名>`(查 svcd)/`proc:` 归因)+ DNS 代理(127.0.0.1:53,双行 resolv.conf+atexit 恢复+5s 自检,真机实测 enabled)+ 事件日志(1min 去重)+ CLI `apps/conns/top/dns`。**期3(M6.1)= 策略引擎**:`/data/meow/netmgrd/net_policy.conf`(组件持久化目录定案,SPEC_REF §1.1)读改写单键+原子写;**防自锁双层**(dropbear/wpa_supplicant/udhcpc/netmgrd/svcd/sysui/init **拒绝置 block** + 策略文件被手工改坏时的加载校验强制复位);**SOCK_DESTROY 真机实测 = no-op(内核 4.4 接受请求但不销毁 socket)→ 连接级管控不可用,仅 DNS 层生效**(`meow_net policy show` 头明示 `enforce=dns_only`);classify_exe 面板白名单 + apps 归因修复 + WiFi `save_config`。日志 `MeowOS/logs/net_.log`(无卡降级 /tmp)。`[patch_v2/meow_netmgrd/]` - **音频硬件事实(sndprobe/tonepcm2 真机实测,2026-08-31)**:播放 PCM = `/dev/snd/pcmC0D0p`(`cs43198-hifi-0`);`pcmC0D1p`=snd-soc-dummy(勿用)。能力:S16_LE/S24_LE、1-2ch、8k-768k、buffer 2048-1048576 帧、period 512-262144。⚠️ **ALSA UAPI 两坑**(ncm 无声根因,勿再踩):①hw_params 必须「全放行」初始化(mask 全 1、interval [0,UINT_MAX],params_any 语义)再收窄——memset 0 的 interval=「只能取 0」求交必空 → HW_PARAMS 恒 EINVAL;②access/format/subformat mask 必须**先清零再单点**——留全 1 会被内核 choose 成 MMAP_INTERLEAVED,ch>1 时 write 恒 EINVAL。**CS43198 音量寄存器=衰减量(官方数据手册 DS1039 实证,用户供)**:PCM_VOLUME_A/B(0x0B/0x0C),0=0dB 满幅最大声、255=-127.5dB≈静音(0.5dB/步;DSD 通道独立 DSD_VOLUME_A/B)。**混音器 L/R Playback Volume 读回恒 0 是死镜像**(官方播放器走 sa_hgl_dma 硬直通不经此控制,HibyOS 对照实测同读 0),勿据此判音量。**音量寄存器=衰减量(0=最响 255=静音,M2.95 真机实测方向)**:四路(launcher/audio.c+audiod+watchdog+SDK vol)统一 `dac=255-pct*255/100`;mute 必须写 255 真静音(M2.96 炸耳修复)。混音器清单:numid=1/2 L/R Vol、3 Mute Output、4 Digital Filter、5 Soft Mute、6 NOS_EN、7 DRE_EN、8 Balance Lineout En、9 Output Port Switch(0 空闲/1 lineout/2 3.5/3 4.4/4 SPDIF;0 危险勿写;**5 = audiod 内部「强制重烧 FPGA」约定值**(M2.91 开机武装同值改写路径),非常规路由值,App/面板勿写)、10 DOP_EN。`[patch_v2/tools/sndprobe.c][tonepcm2.c][APPS §3.7]` - 后台权限:`MSG_HELLO/MSG_REGISTER.flags` 扩展 `MF_BACKGROUND`/`MF_PLAYBACK`(**已落地 M4**:app.json `background`/`background_audio` 字段 + MSG_REGISTER 校验链;播放中退出转后台保活见 FRAMEWORK_DESIGN §9);`PERF_BACKGROUND`/`PERF_AUDIO_BACKGROUND`(规划)`[FRAMEWORK_DESIGN 附录 A]` --- ## 5. 关键约定 & 约束 ### 5.1 按键/手势/状态栏/全屏 - 按键全局接管(除电源菜单),见 §2.4 `[APPS §3.4.1]` - **左缘返回手势**:手指从**屏幕左缘 ≤24px** 向内(右)划 **≥90px**,**抬手(release 边沿)才触发** `MEOW_SWIPE_LEFT`("左滑=返回"契约);过程以 `on_swipe_progress` 实时上报 + SDK 自动画顶部进度条 `meow_ui_swipe_hint(x)`(5px 高,top,theme accent 色);x<=0 清条。**中部左/右滑不是返回**(中部右滑→SWIPE_RIGHT,中部左滑→落 TAP)`[MEOW_APP_SDK §6][GESTURE_BACK §2.2/§3]` - 偏差:原「左缘+向左 mdx<-90」物理不可达 → 取「左缘向内(右)划 ≥90px」,事件仍报 `MEOW_SWIPE_LEFT` `[GESTURE_BACK §3]` - **全局状态栏**:SDK 内置,默认显示(时钟/电量/WiFi/蓝牙/音量),1s 轻刷,z 最顶;仅 APP 声明全屏/`fullscreen:1` 才隐藏;非全屏 APP 须用 `meow_ui_statusbar_height()` 做 inset `[meow_ui.h §3.1][MIGRATION_AC §3]` - **状态栏统一(M2.66 收敛,「同一个状态栏」正确闭环)**:状态栏是**某一个渲染主体**(系统进程 launcher)——主界面与 App 前台用**同一个**状态栏实例,**App 进程不渲染、不自绘、不叠加**(§10.2/@`FRAMEWORK_DESIGN §10.2`);App 前台时状态栏作为**系统叠加层**盖在内容之上(复用 fb 双缓冲备份/恢复/pan);**数据源唯一由 launcher 统一喂/取**(时间/电量/WiFi/音量/亮度)→ 两边必然一致(根治 M2.66「桌面有亮度、App 没有」的不一致)。右侧为 **MD3 图标 + 变量值**(随 `ui.style` 换图标集)。**全屏收合**:状态栏向上收出屏顶、只留提示线,**顶部保留热区**(仍可下滑通知中心)+ 左缘指示条(见 §3.1/A-13/§5.1)。`[FRAMEWORK_DESIGN §10.2]` - **全屏机制(M2.5x,`app.json fullscreen` 即 app 级 + `route..fullscreen` 即 activity 级)**:launcher 启动 app/切 activity 时据声明**预先设 SDK 全屏**(env `MEOW_FULLSCREEN`)。进入/退出全屏:**状态栏向上收出屏顶、只留一条提示线高度**(非全隐藏),带上收/恢复的**自然过渡动画**。**全屏下保留**:左缘返回手势 + 顶部动态伸缩提示线;顶部下滑仍可展开通知中心,但**顶部热区缩小**(不影响全屏 app)`[源:用户 2026-08-30]`(细化既有「全屏=隐藏状态栏/隐藏返回键」的表述,见 §7 A-13) - 沉浸:`app.json immersive:1` → launcher 写 `/tmp/meowapp_state=1` → 隐藏虚拟返回键,手势归 SDK `[APPS §3.5][GESTURE_BACK §2.4]` - **横向分页设计模板(M2.5x 预留,见 `MEOW_APP_SDK.md` §5.2)**:主页/子页多页横向滑动复用的设计模板(参照 HibyOS 播放器主页横划进播放页)。与左缘返回/顶部下滑**按起始位置分流**互斥——左缘 ≤热区→**左滑返回**(§5.1);中部左/右滑→**页切换**;顶部下滑→**通知中心**。实现要点:相邻页各预渲染一张快照、切换只 blit 快照 + 跟手平移/吸附(vsync ≤60 帧、零 UI 重算)。**注**:模板 API 为「草案/待定案」,当前未实现 `[源:2026-08-30]` - **SDK 可复用设计模板清单(M2.5x 预留,见 `MEOW_APP_SDK.md` §5.3)**:把反复出现的界面结构抽象为可复用设计模板——①**分组设置表单** ②**列表+选择** ③**弹窗/对话框** ④**顶/底下拉面板**(A+B 先行,已展开 §5.4-§5.7)+ 媒体播放/沉浸/加载(C)、卡片/导航/列表项(D,随 app/MD3 细化)、拖拽排序/长按菜单/时间轴(E,后置),共 11 项;横向分页另见 §5.2。**所有模板与既有手势约定一致**:左缘返回 + 顶部滑条 + 状态栏收合 + 通知中心热区(本 §5.1/§3.1/A-13)——模板只在内部做命中分流,**不重定义全局手势**;顶部/底部面板与左缘返回/通知中心按起始位置与触达途径分流互斥(快捷设置触达途径为**待定案**)。**注**:A①②/B③④ 模板 API 原为「草案/待定案」。**部分已落地**:B② 列表+选择 → 结构化列表控件 `W_LISTVIEW`(M2.76 agent-186);A① 分组设置表单、B④ 顶/下方面板 已在设置页/通知中心/电源菜单以 launcher 侧实作(非独立公开 SDK 模板 API);视图框架(`meow_ui_view.c` M2.76+)与控件库已覆盖其多数能力,其余(横向分页、C/D/E)仍为草案 `[源:2026-08-30]` ### 5.2 主题 - **日/夜/自动**:SDK `meow_theme` 内置 `meow_theme_light/dark`;模式键 `display.theme_mode`(SYSTEM_SETTINGS 记为 `manual`/`auto`——**与 SDK 枚举 light/dark/auto 冲突**,见 §A);AUTO 判时段 `[SYSTEM_SETTINGS §1][MEOW_APP_SDK §8]` - 背景图系统:`display.bg_mode`(color/image)/`display.bg_dark_color`/`display.bg_light_color`/`display.bg_image`/`display.bg_image_dark`/`bg_image_light`/`display.bg_overlay_alpha`(0-255 默认 ~120);图片目录 **`MeowData/backgrounds/`**(480×720 约束);叠加层颜色随主题(深=黑叠/白=白叠)`[MAIN_MD3_PLAN §6][DEV_NOTES #12/#13]` - 主界面背景:深色用 background(可选色)、浅色用 surface(白) `[DEV_NOTES #13]` - **TF 卡多字体库(M2.5x)+ 字重结构(M2.6)**: - 目录 **`<卡根>/MeowOS/fonts///`**(每 `/` 一套,如 `misans/regular`),内含三件套:`font.png`(预渲染灰度 PNG,bit depth 4|8)+ `font.idx`(MFNI v2 索引),二者均由 `font/gen/gen_font.py` 生成;`font.json` 为元数据+完整性校验。**缺任一件 → 该套不进列表 + 日志**。 - **font.json schema(定版)**:`family`(同目录名,信息用)/`name`(下拉显示名,缺则回退目录名)/`weight`(`regular|bold|italic|…`,字重 slug,缺省 `regular`;对应 `//` 目录第二级)/`glyph_count`(信息用)/`charset`(`common|gbk|full`,字库档位,信息用+驱动按需加载,见「字体档位/大字库」)/`size_list`(信息用)/`bit_depth`(4|8,信息用)/`sha256_png`(font.png 的 sha256 低 64hex)/`sha256_idx`(font.idx 的 sha256)/`source`(可选)/`license`(可选)。校验失败**仅 WARN 不硬失败**(该套仍可选);缺 font.json 或解析不出 `name` → 跳过。 - **加载优先级**:`font.file`(设置键,默认 `MeowOS/fonts/default/regular/font.png`)指向的字体**存在且能 load → 用它**;否则回退卡默认 `MeowOS/fonts/default/regular/font.png` → 固件 `/usr/share/meowos/font/font.png`。相对路径按卡根 `/usr/data/mnt/sd_0/` 解析。全失败 → 字库不可用,`ui_draw` 回退 5x7 点阵(系统不死)。 - **默认字库目录**:默认字体统一放 **`<卡根>/MeowOS/fonts/default/regular/`**(`font.png`+`font.idx`,可选 `font.json`),不再用 `MeowAPPs/fonts/font.png`;设备旧 `MeowAPPs/fonts/` 及旧 `MeowOS/fonts//`(无 weight 级)**保留**(勿删,避免破坏老约定/已有文件),仅新引用一律指向 `MeowOS/fonts/default/regular`。 - **`font.file` 变更即 unload+reload 生效**(设置页回调);拔卡 → 回退固件内置。 - **preset 动态化(两级扫描)**:启动/进设置页扫描一次 `MeowOS/fonts///`,重建「字体文件」下拉(默认字体 + ≤16 套卡内 /;上限防爆)。扫描仅此二时机,勿放热路径。**存量卡片迁移**:旧版扫 `MeowOS/fonts//`(图片直接在该层);迁移到 `/regular/` 后,旧 `/` 下不再有三件套 → 新扫默认按两级找,故若未重做成 `//` 则扫不到(需先用 mv 迁成 `//` 再重扫)。 - **MeowPanel 预留 → 已落地(2026-08-31 用户定案:**改为 `.tar.gz`、放弃 zip**,与 .mpk 同构走 busybox `gzip -dc | tar` 管道,设备必带 tar/gzip)**:面板以 `POST /api/fonts/import` + `GET /api/fonts/export` 接入(见 §5.7.6 与 `patch_v2/meowpanel/README.md` §5.11)。`meow_font_import_zip()`/`meow_font_export_zip()` 原 TODO 声明**不再按 zip 实现**,语义为 tar.gz(函数名可保留或改 `_tgz`)。导入校验→解压到 `MeowOS/fonts///`、导出打包。 - **多字体(M2.5x,`display.multi_font`)**:按字符类别(CJK/CJK_SYM/NUM/LATIN/LATIN_SYM/OTHER)逐字符路由,每类可各选一套字库(`font.class_*`,默认空=跟随全局 `font.file`);同 family 去重、同时装载不同字体 ≤4 套(超出 WARN「过多不同字体会增内存」并截断);开关关 = 单字体(现状)。详见 §5.7.7「多字体」。 - **字体档位 / 大字库(M2.5x,本次实现)**:抽象出**字库大小档位**,让系统/应用/设置页都知道选的是多大字库 `[源:用户 2026-08-30]`。**定案见 `devdocs/plan/FONT_SYSTEM.md`**(字体系统定案:三级目录 `///`、`font.json` 增 `tier`/`languages`/`label`、`charset` 改指编码、按语言选字体;本小节以下为旧口径)。 - 档位枚举:`MEOW_FONT_TIER_COMMON`(**默认 / ≈4k** 码位)/ `MEOW_FONT_TIER_GBK`(**大 / ≈20k+**)/ `MEOW_FONT_TIER_FULL`(**全 / 可选**,码位/体积最大)。 - `font/gen/gen_font.py` `--charset common|gbk|full [--weight ]` 按档生成 `font.png/font.idx/font.json`(**已实现**,现行仅 `--extra` 思路升级为**档位选择**;M2.6 加 `--weight` 写 `font.json.weight`,缺省 `regular`);每个 `MeowOS/fonts///font.json` 标 `weight`+`charset` + `glyph_count`(覆盖声明/信息用,launcher/settings 据此标注与按需装载)。 - **默认用小字库(`common`≈4k)**;仅当 app 声明需大字库(`app.json "fonts":"full"` 或档位)才为该 app 加载大字库(`gbk`≈20k+),见 §5.7.8。 - **系统设置「加载大字库」开关**(`font.load_full`,强制全系统用大字库),见 SYSTEM_SETTINGS §1;**每个字体选项标注字库大小标记**(如 `default(common≈4k)` / `gbk≈20k` / `full`),让用户知道所选字库量级。 - 判缺字:SDK `meow_font_has_glyph(cp)` 预判当前字库是否含该码位(缺字 → app 回退/提示)。 ### 5.3 通知配额/转储 - **每 App 最多 4 类型;每类型活动 ≤4;媒体单例(每 App 仅 1 条,可多 App)**;系统事件抽象为 App(`app_id=system`) 走同一配额 `[NOTIFICATION_SYSTEM §7][meow_ui.h][DEV_NOTES #11]` - 通知创建 **10s 后自动转储到 TF `MeowOS/notifications/`**(保留最新 10MB ring,不被电源事件清);正常关机先转储再清板载;无卡可运行 `[NOTIFICATION_SYSTEM §8]` - **通知 TF 转储(定案 #6,M2.5x)**:转储格式 = **appended 日志行**(每条通知一行,CSV 风格:`id,app_id,分类,标题,时间,…`)+ **按总大小滚动截断**(保留最新 **10MB**)。**启动时清板载通知 + 清内存通知表**(开机清残留/内存表);正常关机/重启前**先转储未上卡通知**再清板载(沿用既有规则)`[源:用户 2026-08-30]` - **通知模型补全(2026-08-30 用户定案,全链路 SDK→IPC→存储→dump)**: - 字段:SDK `meow_notify` / IPC `m_notify_t` / 存储 `meow_notif_t` 全链路补 **`urgency`(0-3,缺省 NORMAL)**、**`icon`(name/path,NULL/空 → 用该 app 默认图标,launcher 按 app_id 回退 app.json 的 icon;每条可独立指定)**;`progress` 已有(0-100,-1=无)。 - 实时进度:`meow_notify_update_progress(local_id, progress)`(SDK)→ IPC `MSG_NOTIFY_PROGRESS(0x0024)` → launcher 只改**内存活跃槽**(不落盘)。 - **里程碑落盘**:TF 快照只在**创建时 + 结束(100% 或 dismiss)** 触发(沿用 `meow_notif_dump_tf`,progress 写当时值);实时进度**不每帧落盘**。 - **CSV 列**(`meow_notif_dump_tf`/`tf_line`):`timestamp,id,app_id,app_icon,category,urgency,progress,title,body,target_activity,ongoing,media,dismissed`。 - 说明:旧调用(无 urgency/progress/icon)兼容——urgency 缺省 NORMAL、progress=-1、icon=NULL→app 图标。`[源:用户 2026-08-30]` - **⑥ 通知中心快捷 chip + 勿扰面板内开关(launcher 侧,M2.64)**:快捷行 **5 chip**(WiFi/蓝牙/主题/亮度/**电源菜单**——第 5 个 chip 点击唤起既有系统电源菜单 `show_power_menu`,真弹对话框);**勿扰不做 chip**,改**面板内开关**(列表上方小 toggle),开=只显示 `urgency>=2`(HIGH/CRITICAL),键 `notify.dnd`(SYSTEM_SETTINGS §1),面板内读写 `meow_settings_*` 零旁路。`[NOTIFICATION_SYSTEM §9]` - **⑦ 单条通知左滑删除(launcher 侧,M2.64)**:通知行**从右往左横向滑动删除**,跟手;未过阈值/反向滑回 → **回弹复原(半程可回)**;松手过阈值 → `meow_notif_dismiss` + 行移除/重排。竖向=列表滚动(方向随 `input.swipe_invert`)、`meow_edge_back`(左缘)优先不变。`[NOTIFICATION_SYSTEM §9]` - **⑧ 一键清除通知(launcher 侧,M2.65)**:勿扰开关**对称处(右半段)**加「一键清除」按钮;点击先**转储留档**(走既有 dump 链 `meow_notif_dismiss → meow_notif_dump_tf`,一行 CSV 追加 `MeowOS/notifications/notifications.log` + 10MB 滚动),再**清空显示**。**红线:绝不清「活动」通知**——① ongoing 常驻、② 媒体通知(媒体会话单例)、③ 带进度条进行中(`progress>=0`)一律保留;只清「非 ongoing / 非 media / 无进行中进度(`progress<0`)」的普通通知。`[NOTIFICATION_SYSTEM §9]` - **⑨ 面板「跟手下拉、半程可回」(launcher 侧,M2.65)**:面板打开/关闭由触发式 180ms 过渡升级为**手指拖动实时跟手**——顶部热区下拉 `progress = 手指位移映射`(复用 `mnp_anim_off`,∈[0,1024],1:1 跟手);松手 `progress≥40%×1024≈410` → 时间轴补到 1024(展开);`<阈值 或 反向拖回` → 回弹到 0 收回(半程取消);关闭同理可跟手。与行左滑(⑦ 横向主导)/列表滚动(竖向溢出)/`meow_edge_back`(左缘)互斥分流。`[NOTIFICATION_SYSTEM §9]` ### 5.4 配置版本单点 / 刷新率 / 息屏 - **现行:M2.96(`/etc/meowos_version` = `0.7.91`,已刷;261 audiod 电平监控已提交、待 M2.97 固件化;M2.95/0.7.90、M2.94/0.7.89、M2.93/0.7.88、M2.92/0.7.87、M2.91/0.7.86、M2.90/0.7.85、M2.89/0.7.84、M2.88/0.7.83、M2.83/0.7.78、M2.82/0.7.77、M2.79/0.7.74、M2.78/0.7.73、M2.77/0.7.72、M2.76/0.7.71、M2.75/0.7.70、M2.74/0.7.69、M2.73/0.7.68、M2.72/0.7.67、M2.71/0.7.66、M2.70/0.7.65、M2.69/0.7.64 …)**;版本单点 = `/etc/meowos_version`(见 §1.1,`build_fw_apps.sh -v` 写入)`[DEV_NOTES #4][fw_content.conf]` - 刷新率:`display.refresh_rate` enum 60/30/15(默认 60);`display.refresh_always_max` bool false(关=允许 60→30→15 降档)。governor:连续 12 帧超预算降一档,连续 4 批≈48 帧远低预算升一档 `[SYSTEM_SETTINGS §1][PERF_SCHEDULER][MIGRATION_AC §12.1]` - 息屏:`display.screen_off_timeout` int 秒 默认 **30**(0=常亮);`display.screen_off_mode` enum `panel`(面板下电+背光0+FBIOPBLANK)/`black`(背光0全黑+双击亮屏) `[SYSTEM_SETTINGS §1]` - 亮度 clamp:`display.brightness` 0-255 默认 101(clamp ≥ `display.brightness_min`);`display.brightness_min` 默认 **1**(M2.39 由 25 改 1)——**与旧文档 25 冲突见 §A** `[SYSTEM_SETTINGS §1]` - **主机名(M2.54)**:`system.hostname`(SET_STR 默认 `meowos`,RFC1035 首标签);`S89meow_svcd` 开机读板载 `settings.conf` 应用 `sethostname`,缺省 `meowos`/系统名;供 `meow_mdns` 公布 `.local`。settings 无该键 → 默认 `meowos`。`[SYSTEM_SETTINGS §1][mips-repo/bins/meow_mdns/manifest.md]` ### 5.5 MeowAPPs 包结构 / .mpk / 数据 - `/` = 程序主体+app.json+资源;`MeowData//{data,cache}` = 数据;首次启动自动建 data/cache 并经 env 注入,exFAT 无软链 `[APPS 附录 §1/§2]` - `.mpk` = tar.gz(app.json + meow 二进制 + 资源),**不含 data/cache**;导入校验 app.json/哈希→解压→数据 init→登入列表 `[APPS 附录 §3]` - 包管理 **CLI `nyai`**(静态 MIPS,部署 `MeowOS/opt/bin/nyai`):install/remove/list/info/search/index/export/upgrade/scan;源 `MeowOS/opt/nyai/sources.list`;索引 `Packages`(Package/Version/Filename/Size/SHA256/Depends/Description)`[APPS 附录 §5]` - 应用数上限 **8**(单屏 8 行);扫描深度 1 级;`app.json` 字段:name(仅 ASCII)/exec(静态 MIPS32r2 ELF)/version/author + **`package`(反域名权威 app_id;==目录名;缺省回退目录名)** + 扩展 `framework`/`immersive`/`icon`/`route.`/`awake.`(keep_awake)/`service.`(M4 起服务二进制=App 同目录 `` 文件)/**`background`/`background_audio`(M4 已落地:无头服务注册权限/后台播放保活)**/`fullscreen`(app 级;`route..fullscreen`=activity 级;**本次实现**:launcher 启动/切 activity 据声明预设 SDK 全屏,见 §5.1/§3.1/§A-12)/`fonts`(字体档位 `"full"|"gbk"|"common"`,需大字库时声明,见 §5.7.8)/`depends`(**二进制依赖**声明:`"curl,jq:optional"` 或行式 `depends=curl,jq:optional,ffmpeg:required`;comma 分项 `[:]`,mod=required|req(默认)/optional|opt;launcher 启动前查 `/usr/bin/` 与 `/usr/data/mnt/sd_0/MeowOS/opt/bin/`(X_OK,命一即可),required 缺失阻断启动(「缺依赖」toast)、optional 缺失仅 WARN,**仅启动时检查**;nyai install 同查并提示) `[APPS §2][MEOW_APP_SDK §9][FRAMEWORK_DESIGN §2][源:审计 2026-08-30][源:用户 2026-08-30]` ### 5.6 冷启动充电屏 - 触发(**三者同时**):冷启动(`poweroff` 写 `/data/meow_cold_boot=1`;`reboot` 写 0)+ 在充电(AC online=1 或 battery status=Charging)+(开机瞬间一次性快照,判定后不回头)`[CHARGING_SCREEN §0]` - 热启动(reboot、含充电态 reboot)一律**不进**充电屏,走引导选单 `[CHARGING_SCREEN §0]` - 主题:`theme.charging=`(默认 default);`MeowOS/themes/charging//theme.json`;加载失败回退内置纯代码默认主题 `[CHARGING_SCREEN §1/§2]` ### 5.7 字体管理 + 应用字库接口(扩展 → SDK 统一接口 / 应用自带字库 / 多句柄) > 在 §5.2「TF 卡多字体库(M2.5x)」基础上**扩展**:把 MeowOS 字体管理器定义为可用字库的**唯一权威来源**,向 SDK 提供统一查询/选用接口,并支持**应用自带字库**与**多句柄(多字体)**。 > ⚠️ **状态分级(2026-08-30)**:launcher 侧字体管理器(§5.7.1)与 **两级扫描/字重子菜单(agent-111,M2.58)**、`meow_font_has_glyph` 已实现;**列表枚举(§5.7.1/§5.7.2)** 落地(**agent-113,M2.58**):「扫描结果落盘 `MeowOS/config/fonts/index`(family/weight/path/label/tier/glyph_count),SDK `meow_font_get_available_count/enumerate` 从该文件读、不依赖 launcher 内存数组;字库丢失→降级默认+日志;render 走 env `MEOW_FONT_PNG/IDX`,list 枚举走 index——两路明确」。**应用自带字库(§5.7.3)/ 多句柄(§5.7.4)/ 凡 `_h` 接口仍为「草案/未实现」**,勿当作已落地;当前 SDK 只有单字体 `meow_font_*` 与 `meow_ui_text*`(用当前默认字体)。 > `[源:meow_font.h][源:agent-79 实现][源:meow_ui.h]` > **app 未自带字库 → 跟随系统 `font.file`(M2.x 已落地)**:launcher 每次 `launch_app` 前把「当前生效字体」注入为环境变量 `MEOW_FONT_PNG`/`MEOW_FONT_IDX`(绝对路径,可选 `MEOW_FONT_APP=`);SDK `meow_ui_gfx.c load_font()` **优先读 env**,无 env 则回退卡默认 `MeowOS/fonts/default` → 固件。§5.7.3 的 `load_handle`(app 自带字库)**未实现**,故当前 app 只能跟随系统字体;一旦实现自带字库,其加载优先级应高于 env。 - **5.7.1 字体管理器(launcher 侧)= 可用字库唯一权威来源** - 唯一维护并扫描 `MeowOS/fonts///`(+默认),产出「字体列表」(family slug / weight slug / 显示名 / glyph_count / size_list / bit_depth)。**SDK 不自行发现字库**,一律经本接口取 launcher 扫描结果。**扫描结果落盘 `MeowOS/config/fonts/index`**(family/weight/path/label/tier/glyph_count);SDK 读该文件(不依赖 launcher 内存数组)。 - **释放语义(agent-113 落地结论)**:持久来源 = index 文件;`font_presets*`/`*_buf` 为「静态、有界(`FONT_PRESETS_MAX=17`)、非堆」数组 → 无内存泄漏、无运行期 free;「释放」= 两个扫描点(启动/进设置页)重建 + 固定上限防膨胀,离开字体列表视图无需显式 free(下次进设置/重扫自动重建)。⚠️ **未做「启动后即清空数组」**:`meow_font_effective_paths_tiered`(launch_app 大字库档位选库)与 `meow_font_reload_multifont` 运行期持续读 `font_presets_n`,清空会造成大字库档位退化(red line「保持档位/多字体行为」);如需「零驻留」,须把这几个核心路径改为直接读 index(较大重构,留待后续)。 - 扫描与校验规则沿用 §5.2:三件套 `font.png/font.idx/font.json` **缺任一件 → 该套跳过 + 日志**;`font.json` 解析 `name`(缺回退目录名)/`weight`(缺省 `regular`)/`glyph_count`/`size_list`/`bit_depth`;`sha256_png/sha256_idx` 仅 **WARN** 不硬失败(该套仍可选)。 - 列表上限沿用 `FONT_PRESETS_MAX = 17`(1 默认 + ≤16 卡内套装,防爆);顺序 = 默认(0) + 扫描顺序。扫描时机不变(启动 / 进设置页),**勿放热路径** `[源:agent-79 实现]`。 - 权威列表数据模型(SDK 侧快照,枚举时填充): ```c typedef struct meow_font_info { char family[64]; /* family slug = MeowOS/fonts// 第一级目录名 */ char name[64]; /* font.json "name",缺则回退 family */ char weight[32]; /* font.json "weight"(regular|bold|italic|…),缺省 "regular" */ int glyph_count; /* font.json "glyph_count",信息用 */ int size_list[16]; /* font.json "size_list"(原生面字号,0 结束) */ int size_count; /* 有效字号数 */ int bit_depth; /* 4 | 8 */ char path_png[320]; /* 系统库:相对卡根 MeowOS/fonts///font.png */ } meow_font_info; ``` - **5.7.2 应用可读 TF 卡字体列表(统一规范接口,app 面向;已落地,M2.58)** `[源:agent-79 实现][源:agent-113 实现][源:meow_font.h]` - **读取来源 = `MeowOS/config/fonts/index`**(launcher 扫 `MeowOS/fonts///` 后落盘;CSV 每套一条 `"family","weight","path","label","tier",glyph_count`,path=卡根相对 `font.png`,label=显示名+字重+尺寸标记,tier=common|gbk|full;默认行恒为 index0)。`meow_font_get_available_count/enumerate` **只读该文件**,不再依赖 launcher 内存数组;无卡/无 index → 仅板载默认项(family=default,count=1)。index 解析在 `font/meow_font.c`(`meow_font_index_load`),SDK 经 `meow_ui.h §5.7` 暴露。 ```c int meow_font_get_available_count(void); /* 可用字库数(含默认;无卡→1) */ int meow_font_enumerate(int idx, meow_font_info *out); /* 按序号取,越界返回 0 */ typedef int (*meow_font_enum_cb)(const meow_font_info *info, void *ctx); int meow_font_enumerate_cb(meow_font_enum_cb cb, void *ctx); /* 回调式,返回套数 */ int meow_font_select_by_id(int id); /* 选该套为 app 会话默认字体 */ ``` - 语义:`id` = 列表序号(index 行号);`0` = **跟随系统默认**(用户 `font.file` 所选,经 env `MEOW_FONT_PNG/IDX`,app 会话不覆盖);`>0` = **app 会话内固定用该套**(覆盖 `font.file` 至 app 结束)。成功 0,越界返回负值。 - **字库丢失降级默认(不丢请求)+ 日志**:`select_by_id(id>0)` 加载失败(png 缺失/坏)→ **降级**到系统默认(env→卡默认→固件),并 `meow_log(MEOW_LOG_WARN, "font missing, fallback default")`(落 app 日志 = SDK meow_log);请求不丢(仍按"选过"处理)。渲染仍走 env `MEOW_FONT_PNG/IDX`(选中的那一套),**列表枚举走 index 文件**——两路明确匹配。 - **列表快照是临时的**:launcher 仅启动/进设置页重扫,期间拔卡或改卡内字库不刷新;app 应**每次会话重新枚举**、按 `family` 持久化,勿缓存数值 id。 - 覆盖范围:系统库 `MeowOS/fonts///` 与默认(含固件 `/usr/share/meowos/font` 回退)都反映在列表里;app 侧「选用已有字库」**只用本接口,不直接拼路径**。 - **launcher 侧系统设置同样降级 + 系统日志**:`font.file` 选中字体缺失 → `meow_font_ensure`/`meow_font_reload_multifont` 兜底链(font.file→卡默认→固件)回退默认,并 `logmsg("meow_font: selected font %s missing, fallback default")`(系统日志 = launcher logmsg;多字体类别缺失 → `multi_font: class %s font %s missing, fallback global`)。app 日志(SDK meow_log)与系统日志(launcher logmsg)分流明确。 - **5.7.3 应用自带字库(按 handle 加载)** `[源:meow_font.h]` - 目录:`MeowAPPs//fonts//{font.png,font.idx,font.json}`;`` = `app.json.package`(反域名 app_id,见 §5.5),`` = 应用自设名字(如 `lyrics`/`reader`)。 - `app.json` 声明(**可选**):`"fonts": ["lyrics","reader"]`。作用 = MeowPanel 打包校验 / launcher 装包校验 / SDK 提供取证;**不声明也可运行时按 handle 加载**。 - SDK 接口(草案): ```c int meow_font_load_handle(const char *pkg, const char *handle); /* 返回字体句柄(>0),失败负值;pkg=NULL=当前 app */ void meow_font_unload_handle(int h); int meow_font_handle_info(int h, meow_font_info *out); /* 查句柄对应信息 */ ``` - **应用自带字库校验更严**:三件套缺任一或 `font.json` 解析不出 → 加载**失败**(app 自声明字库,坏库应显式失败,而非静默回退点阵/默认)。 - 与系统库**并存可混用**:系统套件经 §5.7.2 `meow_font_select_by_id` 激活即成合法 handle;应用自带经 `load_handle` 取得 handle;两者在同一 handle 空间。 - **5.7.4 多句柄 / 多字体(不同控件用不同字体)** `[源:meow_font.h][源:meow_ui.h]` - 低层 `meow_font_*` 新增 `_h` 句柄版本(显式传 handle): ```c void meow_font_drawtext_h(uint16_t *fb,int x,int y,const char *utf8,uint16_t color,int size,int handle); void meow_font_drawtext_outline_h(uint16_t *fb,int x,int y,const char *utf8, uint16_t color,uint16_t outline_color,int ol,int size,int handle); int meow_font_width_text_h(const char *utf8,int size,int handle); int meow_font_line_height_h(int size,int handle); int meow_font_ascent_h(int size,int handle); int meow_font_has_size_h(int size,int handle); ``` - **兼容关键**:现有无 `_h` 的 `meow_font_*`(drawtext/width_text/line_height/...)语义变更为「作用于**当前句柄**」(默认 = 系统 `font.file` 那套);`meow_font_load(png,idx)` 仍是装载系统默认的入口;新增 `meow_font_use(handle)` 设定当前句柄。**不改任何现有签名 → 纯扩展、向后兼容。** ```c void meow_font_use(int handle); /* 设定后续无 _h meow_font_* 所用字体 */ int meow_font_get_current(void); ``` - SDK `meow_ui_*` 高层文本同理: ```c void meow_ui_use_font(int handle); /* 设定后续 meow_ui_text* 字体 */ int meow_ui_font_get_current(void); /* 取当前 meow_ui_text* 所用句柄 */ void meow_ui_text_h(int x,int y,const char *utf8,int size,uint32_t color,int handle); void meow_ui_text_right_h(int right_x,int y,const char *utf8,int size,uint32_t color,int handle); void meow_ui_text_center_h(int cx,int y,const char *utf8,int size,uint32_t color,int handle); int meow_ui_text_width_h(const char *utf8,int size,int handle); int meow_ui_text_height_h(int size,int handle); /* = meow_font_line_height_h */ ``` 现有 `meow_ui_text/text_right/text_center`(无 handle)= 用当前字体(`meow_ui_use_font` 设;默认系统默认)。**向后兼容。** 建议 app 切库前用 `meow_font_get_current()` / `meow_ui_font_get_current()` 求值保存,画完再 `meow_ui_use_font(旧)` 显式恢复,避免句柄状态泄漏影响后续绘制。 - **5.7.5 多句柄用法示例(歌词页用 A 库、正文用 B 库)** ```c /* 应用自带 lyrics(歌词页) + 系统字库(正文)混用 */ int hLyrics = meow_font_load_handle(NULL, "lyrics"); /* MeowAPPs//fonts/lyrics/ */ meow_ui_use_font(hLyrics); meow_ui_text_center(240, 300, "歌词行…", 20, 0xFFFFFF); /* 用 lyrics 库 */ int hBody = meow_font_select_by_id(2); /* 系统字库第 2 套(正文用) */ meow_ui_use_font(hBody); meow_ui_text(20, 60, "正文…", 20, 0xFFFFFF); /* 用系统库 */ /* 量宽/行高须与最终实际字形一致:用同 handle 的 _h 版 */ int w = meow_ui_text_width_h("正文…", 20, hBody); int lh = meow_ui_text_height_h(20, hBody); ``` - 说明:句柄状态为 app 进程内**全局**;同一屏需混排时,推荐每段绘制前显式 `meow_ui_use_font`,或全部走 `*_h` 显式传 handle,避免依赖上次绘制遗留的句柄状态。 - **5.7.6 MeowPanel 上传 / 导出(.tar.gz,2026-08-31 用户定案:放弃 zip,与 .mpk 同构)** `[源:meow_font.h][源:patch_v2/meowpanel/README.md §5.11]` - **已由 MeowPanel 后端落地**:`POST /api/fonts/import`(multipart `file`=<.tar.gz>)+ `GET /api/fonts/export?family=&weight=` + `GET /api/fonts`(列表)。**不用 zip**——设备 busybox `gzip`/`tar` 必带,后端走 `gzip -dc | tar` 管道(与 nyai .mpk 同款), 零新增依赖、不引入 zlib/miniz/自研 zip。原 `meow_font_import_zip(zip_path)` / `meow_font_export_zip(family,out_zip)` TODO 声明**不再按 zip 实现**,语义即 tar.gz(函名可保留或改 `_tgz`,注明即可)。 - **系统字库导入**:`.tar.gz` 内含 `font.png+font.idx+font.json` 三件套;校验三件套就绪 + `font.json` 可解析; sha256 沿用 `font.json` 约定(= **WARN**,仅缺件/不可解析硬失败);`family`/`weight` 取自 `font.json.family`/ `font.json.weight`(缺省 `regular`);解压到 `MeowOS/fonts///`;**覆盖冲突需先确认**(409 → 前端 confirm 后 `force=1` 重试);导入后进设备「设置→字体」页自动重扫(扫描时机=启动/进设置页,面板**不**主动触发重扫)。 - **应用字库导入**:目标 `MeowAPPs//fonts//`,与 `app.json "fonts"` 声明对齐,校验同上(待面板后续扩展)。 - **导出**:系统库把 `MeowOS/fonts///` 三件套打包为 `-.font.tar.gz`;应用库同理(待扩展)。 - 约定:`.tar.gz` 布局与校验沿用 `font.json` schema(§5.2);导入/导出后的一致性(列表刷新、应用声明同步)归 MeowPanel + launcher 协作。**安全**:tar 解出条目逐个校验(拒绝对路径/`..`/软链/多出条目/子目录包裹),沿用 nyai 的 sanitize 思路。 - **5.7.7 多字体(按字符类别逐字符路由,`display.multi_font`,M2.5x 新增)** `[源:meow_font.h][源:MEOWOS_SPEC_REF §5.2/§5.5]` - **背景**:一款字体难兼顾中文(大图集、字形全)与拉丁/数字(干净、省内存)。多字体让**不同字符类别各用一套字库**,按 codepoint 逐字符路由取字形。 - **设置键**(launcher 读,SDK 经 env 读同一映射): - `display.multi_font`(int **0/1,默认 0=单字体**):1=按字符类别逐字符路由;0=只走 `font.file`(现状,零额外内存/性能开销)。 - 6 个类别字体(SET_STR,值 = 字体 `/` 相对路径(如 `misans/bold`,M2.6);**默认空 = 跟随全局 `font.file`**):`font.class_cjk`(CJK 表意+扩展)、`font.class_cjk_sym`(全角/中文标点)、`font.class_num`(0-9)、`font.class_latin`(A-Za-z)、`font.class_latin_sym`(半角标点)、`font.class_other`(其他)。 - **字符分类器**(`meow_font_class_of(cp)`,按 codepoint):`MEOW_FCLS_CJK`/`_CJK_SYM`/`_NUM`/`_LATIN`/`_LATIN_SYM`/`_OTHER`。规则(ASCII 优先 + Unicode 区间):0x30-39→NUM、0x41-5A/61-7A→LATIN、<0x80(其余)→LATIN_SYM;0x3000-303F/0xFF00-FFEF/0x2014/0x2018-201D/0x2026/0x00B7→CJK_SYM;CJK 表意+扩展+兼容表意区(0x3400-4DBF/4E00-9FFF/20000-2FA1F…)→CJK;其余(假名/韩文/其他文字/扩展区)→OTHER。 - **逐字符路由**:`meow_font_drawtext`/`_outline`/`width_text`/`line_height`/`ascent`/`has_size` 在 multi_font 开启时**逐字符分类 → 用类别对应槽的字库取字形与度量**(宽度/行高按该字体);缺某类字体/槽未载 → **回退全局**(slot0);该字符其字体无字形 → **豆腐缺字**(可经 `meow_font_has_glyph(cp)` 预判)。开关关 → 一律 slot0,与单字体一致。 - **SDK 接口**:`meow_font_load_slot(slot,png,idx)`/`meow_font_unload_slot(slot)`/`meow_font_enable_multifont(on)`/`meow_font_set_class_slot(cls,slot)`/`meow_font_config_multifont(on,global_png,global_idx,cfg[],&distinct,&truncated)`;`MEOW_MAX_SLOTS=5`(slot0=全局 + ≤4 类别)。`meow_font_config_multifont` 统一做**同 png 去重**(含与全局相同 → follow slot0)与**≤4 套上限**(超出 → 置 `*truncated=1`,调用方 WARN「过多不同字体会增内存」,已装载者保留、新类别回退全局)。 - **launcher env 注入**(launch_app,app 跟随系统字体):`MEOW_MULTI_FONT=0/1`;`MEOW_FONT_PNG/IDX`(全局,保留);6 类 `MEOW_FONT_CLS_<类>_PNG/IDX`(命中则覆盖全局;类值为空=跟随全局不注入)。SDK `meow_ui_gfx` 读 env 构建同一映射;无 env/关 → 单字体。 - **持久化**:类别字体设置在 settings.conf(板载,无卡也可存),经 `meow_settings_*` 读写,随设置页变更即重配。 - **内存**(推断解码 atlas = `plane_w×plane_h×(depth 4→0.5 / 8→1.0)` 字节;每套另加 glyph 数组 ≈ glyph_count×16B、idx 头保留约 128KB,idx 原始缓冲载毕即释)。实测仓库字库(depth 4):misans(CJK)≈2.44MiB、source_han_sans(CJK)≈2.53MiB、meslo(Latin)≈1.68MiB、google_sans(Latin)≈1.12MiB;按用户估算口径(**depth 8**):CJK ≈ 5-6MB、Latin ≈ 0.3-0.5MB(后者为窄覆盖 Latin 专库)。**典型「1CJK+1Latin」增量**:全局=CJK,另加一套 Latin → 增加 ≈0.3-1.7MB(depth 8 约 0.5MB;实测 depth4 latin 1.1-1.7MB);全局=Latin 另加一套 CJK → 增加 ≈2.4-2.5MB(depth 8 约 5-6MB)。`display.multi_font=0` 时仅全局一套,无任何额外装载。 - **5.7.8 字体档位分层 / 按需大字库(app 声明 + 系统开关,本次实现)** `[源:用户 2026-08-30]` - **口径**:默认用**小字库 `common`(≈4k 码位)**;当 app 声明需要**大字库**(如小说阅读器,`app.json` 声明 `"fonts":"full"` 或档位 `"gbk"`/`"common"`)时,才为该 app 加载**大字库 `gbk`(≈20k+)**。档位与 `gen_font.py --charset`、`font.json charset/glyph_count` 见 §5.2「字体档位/大字库」。 - **app 级 / activity 级**:app 级以 `app.json "fonts":""` 声明(launcher `meow_parse_app_json` 已解析);activity 级(如需)以 `route..fonts` 声明(沿用 `route.` 扩展口径)。launcher 启动 app 时据声明 + `font.load_full` 算**生效档**,经 env 注入(`MEOW_FONT_PNG/IDX` 指向所选档位字库绝对路径;`MEOW_FONT_TIER` 标注档位;launcher `meow_font_effective_paths_tiered` 按卡内 `font.json charset` 选库)。 - **系统设置「加载大字库」**(`font.load_full`,默认 0):开 → **强制全系统用大字库(gbk 档)**,覆盖 app 未声明 + 覆盖默认 `font.file`;关(默认)→ 默认小字库,app 声明才大字库。 - **SDK 判缺字**:`meow_font_has_glyph(cp)` 预判当前字库是否含该码位 → app 据此决定回退/提示(避免 `common` 小字库下静默豆腐或缺字)。 - **⚠️ 与 §5.7.3 冲突**:§5.7.3 `"fonts":[…]` 为**应用自带字库句柄数组**;本小节 `"fonts":"full"` 为**字库档位字符串**。同名键两种语义,需统一解析口径(见 §7 A-14)。 --- ## 6. 标志性 TODO / 未决(文档未定,勿凭猜实现) - OPEN_QUESTIONS.md 待定 ❓:多数已由后续定案/落地覆盖——#1 背景图加载(「启动加载一次+预渲染快照不每帧缩放」已落地)、#2 图处理(**cover 居中裁剪**)、#3 叠加层颜色(**固定跟明暗主题**)、#4 背景色板枚举(**已清结**:MD3+MIUIx 色板 M2.90 落地,`display.background` 按 style×mode 派生)、#7 应用图标(**已做,app.json icon 加载缓存+首字母占位**)、#8 通知来源(**系统事件 + MeowAPP IPC + D-Bus 桥 三路**,中心 UI 已落地)、#9 下拉手势(**顶部下滑=通知中心**,与左滑返回按起始位置分流)、#10 通知存储(**TF 归档 CSV + 10MB 滚动 + 环形 200 条**)、#11 媒体活跃会话(**active_seq 最近活跃源,30s 超时回收**)、#12 多 app 音频(**已被 meow_audiod 取代(M2.90):守护独占 hw:0,0 + 抢占,App 经 SDK meow_audio_*,软混音否决**)、#13 web 实时画面(**`/api/screen.jpeg` + 增量帧**)、#14 输入注入(**本机触摸优先 5s 仲裁**)、#16 主页左滑=侧边栏 vs 返回(**Now Playing 横划页,左缘返回保留**)、#17 音频输出设置(**底层已由 audiod 收口:路由自动+CLI;设置页 UI 项留后续**)。**仍待定**:#5 浅色文字对比度(待实机观感验收)+ 2026-09-01 新增批(~~PCM 内核挂死~~**已根治**:M2.91 FPGA 开机武装 + M2.94 几何收窄/~~WiFi 录入 UI~~**已落地(M6.1 286:设置页 wifi_page/bt_page 迁 netmgr IPC + 扫 SSID→IME 输密码→connect)**/~~amsd DECLARE 残余(`am start` ACK 后 launcher 未真拉起 App)~~**已修(M6.0 274:`meow_ams_start.c` 忙/非法分支返回正错误码致 ACK 假 OK,改 pending-start 2s 重扫)**/流媒体客户端出声终验(链路技术指标已全绿:FPGA 武装+几何+监控 hwrate 健康,待用户耳机终验)/流媒体客户端 UI 专项/感知音量曲线 dB taper) `[OPEN_QUESTIONS]` - DEVELOPMENT_PLAN:**阶段 0(bootmenu 双系统)已落地(现网即运行中)**;阶段 B/E/F 达成;阶段 D M0-M5 已落地(**M4 后台服务保活+后台播放 2026-09-01 落地**:MSG_REGISTER/SERVICE_STOP/MSG_SYS + 退避熔断 + nav-exit 后台保活,见 FRAMEWORK_DESIGN §9)、**M6 加固 待排期** `[DEVELOPMENT_PLAN]` - 未定/待拍板:MeowOS 音频输出设置(只读还是可配,OPEN_QUESTIONS #17);OTA 在线「检查更新/下载」依赖 MeowPanel(本地/检查升级已可用,URL 下载待定案 #18)`[WORK_STATE][OPEN_QUESTIONS #17/#18]` - **meow_svcd 后续(M2.54 已落地大部分)**:~~接入 supervisor 启动链~~(已改 `etc/init.d/S89meow_svcd` 开机自启;bootmenu/launcher `fork+exec`+`waitpid` 仍为备选);~~写 `MeowOS/services.d/mdnsd.conf` 落地 mDNS~~(已改**板载** `/usr/data/meow/services.d/meow_mdns.conf` 预置,`trigger=boot`;M6.1 起服务名统一为 `meow_mdns`)。剩余:`cap` setcap 真机实装(cap_net_bind_service,cap_net_raw);`wifi-up` 判定收紧。**services.d/svcd 已接入开机链(S89)**,但真机行为待验证。 `[WORK_STATE][meow_svcd.md]` --- ## 7. 已知矛盾 / 待确认(⚠️ 别凭猜) - **A-1 热键窗口下限**:APPS.md §3.1/§4.2 写「电源按下后 **300ms**~2.5s」;DEVELOPMENT_PLAN §0/阶段A 写「窗口下限 **60ms**(v6.7 修)。→ 以 **60ms** 为准,APPS.md 已过时。 - **A-2 主题模式枚举**:SYSTEM_SETTINGS §1 `display.theme_mode`=`manual`/`auto`(另设 `display.theme`=dark/light);MEOW_APP_SDK §8 / meow_ui.h `meow_theme_mode`=`LIGHT/DARK/AUTO` 且直接跟随 `display.theme_mode`。→ 两套枚举语义不一致;AUTO 时段:SYSTEM_SETTINGS 用可配 `theme_dark_start/end`(分钟),SDK §12 用固定「6:00-18:00 日间」。WORK_STATE/DEV_NOTES 明言「时段判定 launcher/SDK 两份逻辑需抽共享纯函数」。→ **DOM 键值 enum 与 SDK enum 需统一,时段判定需抽共享函数后再实现。** - **A-3 亮度下限**:`display.brightness_min` 默认 **1**(SYSTEM_SETTINGS §1,M2.39 由 25 改 1);但 MEOWOS_API §2.2「clamp ≥ brightness_min 默认 **25**」、MD3_UI_SPEC §3.2「亮度 clamp ≥25」仍写 25。→ 以 **SYSTEM_SETTINGS(1)** 为准,另两份文档陈旧。 - **A-4 左缘返回阈值**:MEOW_APP_SDK §6 / GESTURE_BACK 取「左缘 ≤24px + 向内划 **≥90px**,抬手触发」;MIGRATION_AC §7 写「左缘 24px + 右滑 **≥65px** 触发」。→ **90 vs 65 不一致**(meow_ui.h 未给阈值,GESTURE_BACK + MEOW_APP_SDK 较权威=90,但确认真机前留疑)。 - **A-5 通知 app_quota**:NOTIFICATION_SYSTEM §7/meow_ui.h = 4 类型×每类型 4=16 条/App;SYSTEM_SETTINGS §1 `notify.app_quota`=16。FRAMEWORK_DESIGN §4「配额 ≤16/应用」。→ **口径可归并(4×4=16)**,但 SYSTEM_SETTINGS 未列 4/4 细分,建议实现以 meow_ui.h 的 `MEOW_NOTIFY_MAX_TYPES/MAX_PER_TYPE` 为准。 - **A-6 KEY_PREVIOUS(code)**:KEY_CONTROL §3 明注「KEY_PREVIOUSSONG 是 **165**;19 是另一码」;meow_ui.h `#define MEOW_KEY_PREVIOUS 19 /* KEY_PREVIOUSSONG */` 注释标错。→ **19 的标签应改**(值 19 非 prevsong;165 才是),属 meow_ui.h 注释误导。 - **A-7 app 日志路径**:APP_LOG_MANAGER §4 写 `apps/.log`(单文件);meow_ui.h §9 / DEV_NOTES #9 为 **`apps/<包名>/logs/<启动时间>_.log`**(每次启动新文件)——用户已纠正,勿用单文件。→ 以 meow_ui.h/DEV_NOTES(M2.51)为准,APP_LOG_MANAGER 目录小节过时。 - **A-8 状态栏高**:MEOW_APP_SDK §3.1「slim ~20-40px」;实际定案 **40px**([D6] MIGRATION_AC §11.1),后被用户改为 **28px**(MUI_SBAR_H=28,字号 20,图标 ink 16/中线 14,见 M2.x 状态栏压缩)。→ 现取 28。 - **A-9 SDK 通知转储**:NOTIFICATION_SYSTEM §8「创建 10s 后自动转储到 TF」;meow_ui.h 现仅「活动表+meow_log 打日志,真实投递 UI/D-Bus 为后续」。→ **10s 转储/TF 已实现(M2.5x,#6)**:launcher 侧带 TTL 10s 转储钩子,dump 到 `MeowOS/notifications/notifications.log`(appended CSV + 10MB 滚动 + 开机清板载/内存表);meow_ui.h 注释「真实投递 UI/D-Bus 为后续」仍指**通知中心 UI / D-Bus 桥**未做。 - **A-10 版本来源细解**:DEV_NOTES #4「/etc/meowos_version 唯一来源;MEOWOS_VERSION 宏仅 dev 占位永不动」;APPS.md §4.6「MEOWOS_VERSION 宏=单一来源,build 时 sed 写入 etc/meowos_version」。→ 两者都强调"写入同源",但"谁是源头"措辞矛盾;实践上 build 脚本 echo 生成 /etc/meowos_version,宏作屏显 dev 占位。→ **M2.64:APPS.md §4.6 已修正为「`/etc/meowos_version` 单点、`MEOWOS_VERSION` 宏仅 dev 占位」,方使矛盾消除**。 - **A-11 `MeowOS/opt/` vs `MeowOpt/`(已归并)**:曾有顶层 `MeowOpt/`(板载外部工具/二进制,如 mdnsd)与 `MeowOS/opt/{bin,nyai,sources.list},lib/,tools/`(nyai 包管 + 工具)并存、命名仅大小写之差。→ **已归并**:`MeowOpt` 废弃并入 `MeowOS/opt/`;mDNS 由完整 mdnsd(TF MeowOS/opt/mdnsd)改为**自研 `meow_mdns`(固件 `/usr/bin`,IPv4-only)**,不再放卡。全仓库统一用 `MeowOS/opt/`。 - **A-12 `fullscreen` 字段(已定 → 已实现,M2.5x)**:§5.5 与 MEOW_APP_SDK §9 将 `fullscreen` 列为 app.json 字段,但 `meow_parse_app_json()` **此前并未读取该键**(实现只解析 name/exec/icon/package/framework/immersive/route./awake./service.),属"已定未做"。→ **已实现**:launcher 启动 app/切 activity 据 `app.json fullscreen`/`route..fullscreen` 预设 SDK 全屏(env `MEOW_FULLSCREEN`),见 §5.1/§3.1。全屏语义由「隐藏状态栏+隐藏返回键」细化为「状态栏收合至提示线 + 保留左缘返回+顶部提示线+下滑通知中心(热区缩小)」(见 A-13)。 - **A-13 全屏语义细化(状态栏「隐藏」→「收合至提示线」)**:既有 §3.1/§5.1 描述全屏=隐藏状态栏(`meow_ui_statusbar_height()`=0、隐藏返回键=沉浸);本次定案细化为**进入/退出全屏:状态栏向上收出屏顶、只留一条提示线高度**,**全屏下保留**左缘返回手势 + 顶部动态伸缩提示线,且**顶部下滑仍可开通知中心(顶部热区缩小)**。→ **已实现(M2.5x)**:SDK 端明确「收合(collapsed)=状态栏缩为提示线(4px)」vs「隐藏=高度0」;全屏下保留左缘返回+顶部伸缩滑条+顶部下滑通知中心(热区缩小)。⚠️ **全屏顶部动态伸缩滑条仍有已知问题在跟进(agent-112)**。 - **A-14 `fonts` 键二义**:§5.7.3 `"fonts":[…]`=应用自带字库句柄数组;§5.2/§5.7.8 `"fonts":"full"|"gbk"|"common"`=字库档位字符串。→ 同名键两种语义,解析器需区分(字符串→档位 / 数组→句柄);若避免歧义可改用专键如 `"font_tier"`(**未拍板**)。 `[各源标注见上]`