需求(用户定案):App 复杂功能若依赖现成 Linux 二进制(板载 /usr/bin 或卡上 MeowOS/opt/bin)能效更好,声明后系统启动 App 前检查依赖是否存在。 - depends 行式声明:depends=curl,jq:optional,ffmpeg:required(无标注默认 required;也接受 :opt/:req;未知修饰符按 required 处理并 WARN;空项/超量丢弃) - launch_app_chain 冷启动时按序查 /usr/bin/<name> 与 <卡>/MeowOS/opt/bin/<name> (X_OK,两类命中即满足);缺 required → 不启动(toast「缺依赖: <name>」+ 日志, 沿用 CANNOT START 风格);optional 缺失 → 仅 WARN 放行;只在启动时查,不做周期复查 - nyai install 对包内 app.json depends 同查并提示(不阻断安装,缺 required 标注 「安装后启动将失败」) - 新增 meow_dep.c(独立 TU,解析/检查/块原因),宿主测试 test_depends.c 解析矩阵 12 用例 + 假根检查路径 12 用例全 PASS;launcher/nyai mipsel 交叉 -Wall -Wextra 0 warning;launcher 现有宿主测试回归全过 - 文档:APPS.md §2.1 字段表 + docs/MEOWOS_SPEC_REF.md §5.5 同步;hello app.json 加 depends:curl:optional 示例 launcher md5 899ac22c10f596909d7f35ea685744de(fw_content.conf 已更新;/usr/bin 只读,留给主会话打包固件)
77 KiB
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] - 板载服务目录:
/usr/data/meow/services.d/<name>.conf(M2.54,Data 区,恒定存在、权威优先;首启由S89meow_svcd预置mdnsd.conf)。与 TFMeowOS/services.d/双源,同名板载优先 + WARN;板载trigger=boot服务不依赖卡(拔卡保留)[meow_svcd.md][meow_svcd.c] - 主机名:设置键
system.hostname(SET_STR,默认meowos;RFC1035 首标签),S89meow_svcd开机读 settingssethostname;供自研 mDNS 应答器公布<host>.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)。由 launchermeow_settings_save()在保存boot.default时同步写;bootmenuset_boot_default_meow()(写 0)/ launcherset_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/<pkg>/{data,cache} # 应用专属数据(exFAT 无软链,用 env 注入)
├── MeowAPPs/ # 应用(<package>=app.json.package=目录名;app.json+二进制+资源, fonts/, backgrounds/;日志已入 MeowOS/logs[源:审计 2026-08-30])
└── MeowOS/ # MeowOS 专属(一切非必要文件;**MeowOpt 已废弃并入此处的 opt/**)
├── backups/settings/setting.bak # 设置导出默认路径
├── services.d/ # 服务配置(meow_svcd 的 <name>.conf;TF 源,与板载 /usr/data/meow/services.d 双源,同名板载优先)`[meow_svcd.md]`
├── fonts/<family>/<weight>/ # 多字体库(每 <family>/<weight> 一套三件套;见 §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_<bootts>.log + apps/...(见 §3 日志)
├── notifications/(转储区,保留最新 10MB,不被电源事件清;文件 = notifications.log,appended CSV 行)
├── opt/{bin,nyai,sources.list}, lib/, tools/ # 外围工具/二进制(MeowOpt 已废弃并入;mDNS 自研 meow_mdns 在固件,不入此)
└── themes/charging/<id>/ # 充电屏主题(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/+ TFMeowOS/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] - IPC 线程只读帧+解析+入队;状态变更主循环单写者(eventfd 唤醒,10ms 热键轮询非阻塞排空)
[FRAMEWORK_DESIGN §0][§6]
2.3 watchdog / supervisor 信号
- 应用返回键=SIGTERM(1s 后 SIGKILL 兜底);SIGUSR1 仅=沉浸左缘滑动手势,不是返回键
[APPS §3.5] - 强杀兜底:应用卡死 = 音量减连按 3 次(间隔 <hotkey_seq_gap)→SIGTERM→0.5s→SIGKILL
[APPS §3.5] - 全程禁:
killall hiby_player/SIGUSR1 发给播放器/走 hiby_player.sh(其sleep 1; reboot看门狗)/触碰 NAND/recovery_all[APPS §1.3][WORK_STATE] - 播放器信号:SIGSTOP/CONT 安全;SIGTERM 仅运行态(~2s)有效,T 态需先 SIGCONT;SIGKILL 兜底
[BOOT_SELECTOR §1] - supervisor(meow_bootmenu)接管关机/升级:播放器
exit(0)→真 poweroff;检测 mtd5=ota:kernel2→真 reboot[WORK_STATE][MIGRATION_AC 无]
2.4 按键信号全局接管(除电源菜单)[APPS §3.4.1][KEY_CONTROL §1]
- 红线:除电源菜单(允许电源=确认、音量=导航)外,所有按键由 MeowOS 全局接管——任何界面(含 MeowOS 设置页/应用列表/MeowAPP)不得私自定义按键映射;导航走触摸(返回钮/左缘左滑)
[APPS §3.4.1] -
键 code 语义 阶段 电源单击 116 息屏/亮屏 ✅ watchdog 电源长按 3s 116 电源菜单(关机/重启/回HibyOS/取消) ✅ launcher 一处绘制 电源长按 8s 116 强制关机 ✅ 音量+ 115 调音量(CS43198) ✅ 音量− 114 调音量 ✅ 播放/暂停 164 活跃媒体会话 🔵先抓住 上一曲 165 同上 🔵先抓住 下一曲 163 同上 🔵先抓住
2.5 热键 / 菜单 / 电源菜单 / 音量
- 热键(默认):按住电源 + 300ms~2.5s 内单击音量减(
meow.conf hotkey=power_voldown;历史hotkey=seq已退役)[APPS §4.2];v6.7 修正窗口下限 60ms(见矛盾 §A) - 电源菜单 5 按钮:关机/重启/回 HibyOS / 取消 /(+「升级模式」按钮)
[WORK_STATE][BOOT_SELECTOR] - 音量跳步:
audio.volume_stepint 1-5 默认 1;watchdog 每按下边沿一步(无线性渐变)[KEY_CONTROL §9 偏差2]
3. SDK 公共 API(meow_ui.h)—— 以实现定案为准
权威签名 =
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.<id>.fullscreen预先设 SDK 全屏(envMEOW_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.confaudio.volume;[D8] 蓝牙读hciconfig30s 缓存;[D9] 状态读取器跑在meow_ui_run1s 节流(无独立线程);[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.amd5e8341975,[meow_ui_widget.c][meow_ui_ime.c]):①W_LIST(含 LazyColumn/LazyRow,meow_widget_drawcase 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 绘制期通用 clipg_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.aABI 变化 → 需同步重编 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/<name>.conf,目录式复用 services.d 语义;sysui.d/launcher.confenabled=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.sockMSG_PERF_QUERY→RESULT;power 走/usr/data/meow_power.sockMSG_POWER_ACTION→STATUS(服务端SO_PEERCRED uid==0基础鉴权)。M2.73:perf 增 network 子集(SYSTEM 子集输出:真实 WiFiwpa_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因 cs43198pwr_gpio=-1无控制点→MEOW_ERR_NODEV)。新 md5:perf7ea196de(M2.75 补 network 闭合括号)、power306df962(2B 面板精确绑定)。电源 CLImeow_svc_power <cmd>(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 SDKmeow_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/launcherfork/exec+waitpid托管仍为备选。 - 双源 services.d(板载优先):板载
/usr/data/meow/services.d/<name>.conf+ TFMeowOS/services.d/<name>.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/<name>.conf(Data 区,拔卡保留);TF 工具/第三方→TFMeowOS/services.d/<name>.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 <name|all>/pid,示例meow_svcd status/meow_svcd restart mdnsd/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]
- 类 systemd/systemctl。已接入系统启动链(M2.54):固件
- 卡上外部工具 =
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,无卡跳过、系统核心不依赖,不进固件;md58108852f(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_powerIPC 客户端(读侧透传 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/mdnsd.conf,trigger=boot、root 即可绑 5353/组播,cap=空)。功能:join224.0.0.251:5353,应答<host>.localA(wlan0 IPv4)/_ssh._tcpPTR/SRV/TXT/_services._dns-sdPTR;支持MEOW_MDNS_HOST/_ADDR/_PORT/_TTL/_CF/_QD/_MCAST/_MIF/_DBG。⚠️ 手机热点隔离:设备→主机组播被热点丢弃,avahi 只收组播应答 → 该热点下avahi-resolve <host>.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/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 会双写路由)。CLImeow_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 节拍写 TFMeowOS/logs/audio_monitor_<bootts>.log、CLImeow_audio monitor [秒]文本电平条)。[patch_v2/meow_audiod/] - 音频硬件事实(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.jsonbackground/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]
- 偏差:原「左缘+向左 mdx<-90」物理不可达 → 取「左缘向内(右)划 ≥90px」,事件仍报
- 全局状态栏: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.66 收敛,「同一个状态栏」正确闭环):状态栏是某一个渲染主体(系统进程 launcher)——主界面与 App 前台用同一个状态栏实例,App 进程不渲染、不自绘、不叠加(§10.2/@
- 全屏机制(M2.5x,
app.json fullscreen即 app 级 +route.<id>.fullscreen即 activity 级):launcher 启动 app/切 activity 时据声明预先设 SDK 全屏(envMEOW_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.cM2.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/<family>/<weight>/(每<family>/<weight>一套,如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;对应<family>/<weight>/目录第二级)/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/<family>/(无 weight 级)保留(勿删,避免破坏老约定/已有文件),仅新引用一律指向MeowOS/fonts/default/regular。 font.file变更即 unload+reload 生效(设置页回调);拔卡 → 回退固件内置。- preset 动态化(两级扫描):启动/进设置页扫描一次
MeowOS/fonts/<family>/<weight>/,重建「字体文件」下拉(默认字体 + ≤16 套卡内 /;上限防爆)。扫描仅此二时机,勿放热路径。存量卡片迁移:旧版扫MeowOS/fonts/<family>/(图片直接在该层);迁移到<family>/regular/后,旧<family>/下不再有三件套 → 新扫默认按两级找,故若未重做成<family>/<weight>/则扫不到(需先用 mv 迁成<family>/<weight>/再重扫)。 - MeowPanel 预留 → 已落地(2026-08-31 用户定案:改为
.tar.gz、放弃 zip,与 .mpk 同构走 busyboxgzip -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/<family>/<weight>/、导出打包。 - 多字体(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(字体系统定案:三级目录<family>/<weight>/<tier>/、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 <name>]按档生成font.png/font.idx/font.json(已实现,现行仅--extra思路升级为档位选择;M2.6 加--weight写font.json.weight,缺省regular);每个MeowOS/fonts/<family>/<weight>/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/ IPCm_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)→ IPCMSG_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]
- 字段:SDK
- ⑥ 通知中心快捷 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_rateenum 60/30/15(默认 60);display.refresh_always_maxbool false(关=允许 60→30→15 降档)。governor:连续 12 帧超预算降一档,连续 4 批≈48 帧远低预算升一档[SYSTEM_SETTINGS §1][PERF_SCHEDULER][MIGRATION_AC §12.1] - 息屏:
display.screen_off_timeoutint 秒 默认 30(0=常亮);display.screen_off_modeenumpanel(面板下电+背光0+FBIOPBLANK)/black(背光0全黑+双击亮屏)[SYSTEM_SETTINGS §1] - 亮度 clamp:
display.brightness0-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公布<host>.local。settings 无该键 → 默认meowos。[SYSTEM_SETTINGS §1][mips-repo/bins/meow_mdns/manifest.md]
5.5 MeowAPPs 包结构 / .mpk / 数据
<pkg>/= 程序主体+app.json+资源;MeowData/<pkg>/{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.<id>/awake.<id>(keep_awake)/service.<svc>(M4 起服务二进制=App 同目录<svc>文件)/background/background_audio(M4 已落地:无头服务注册权限/后台播放保活)/fullscreen(app 级;route.<id>.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 分项<name>[:<mod>],mod=required|req(默认)/optional|opt;launcher 启动前查/usr/bin/<name>与/usr/data/mnt/sd_0/MeowOS/opt/bin/<name>(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=<id>(默认 default);MeowOS/themes/charging/<id>/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),SDKmeow_font_get_available_count/enumerate从该文件读、不依赖 launcher 内存数组;字库丢失→降级默认+日志;render 走 envMEOW_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=<family>);SDKmeow_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>/<weight>/(+默认),产出「字体列表」(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 侧快照,枚举时填充):
typedef struct meow_font_info { char family[64]; /* family slug = MeowOS/fonts/<family>/ 第一级目录名 */ 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/<family>/<weight>/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/<family>/<weight>/后落盘;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暴露。
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所选,经 envMEOW_FONT_PNG/IDX,app 会话不覆盖);>0= app 会话内固定用该套(覆盖font.file至 app 结束)。成功 0,越界返回负值。 - 字库丢失降级默认(不丢请求)+ 日志:
select_by_id(id>0)加载失败(png 缺失/坏)→ 降级到系统默认(env→卡默认→固件),并meow_log(MEOW_LOG_WARN, "font <path> missing, fallback default")(落 app 日志 = SDK meow_log);请求不丢(仍按"选过"处理)。渲染仍走 envMEOW_FONT_PNG/IDX(选中的那一套),列表枚举走 index 文件——两路明确匹配。 - 列表快照是临时的:launcher 仅启动/进设置页重扫,期间拔卡或改卡内字库不刷新;app 应每次会话重新枚举、按
family持久化,勿缓存数值 id。 - 覆盖范围:系统库
MeowOS/fonts/<family>/<weight>/与默认(含固件/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/<pkg>/fonts/<handle>/{font.png,font.idx,font.json};<pkg>=app.json.package(反域名 app_id,见 §5.5),<handle>= 应用自设名字(如lyrics/reader)。 app.json声明(可选):"fonts": ["lyrics","reader"]。作用 = MeowPanel 打包校验 / launcher 装包校验 / SDK 提供取证;不声明也可运行时按 handle 加载。- SDK 接口(草案):
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):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)设定当前句柄。不改任何现有签名 → 纯扩展、向后兼容。void meow_font_use(int handle); /* 设定后续无 _h meow_font_* 所用字体 */ int meow_font_get_current(void); - SDK
meow_ui_*高层文本同理:现有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 库)
/* 应用自带 lyrics(歌词页) + 系统字库(正文)混用 */ int hLyrics = meow_font_load_handle(NULL, "lyrics"); /* MeowAPPs/<pkg>/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,避免依赖上次绘制遗留的句柄状态。
- 说明:句柄状态为 app 进程内全局;同一屏需混排时,推荐每段绘制前显式
- 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(multipartfile=<.tar.gz>)+GET /api/fonts/export?family=&weight=+GET /api/fonts(列表)。不用 zip——设备 busyboxgzip/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/<family>/<weight>/;覆盖冲突需先确认(409 → 前端 confirm 后force=1重试);导入后进设备「设置→字体」页自动重扫(扫描时机=启动/进设置页,面板不主动触发重扫)。 - 应用字库导入:目标
MeowAPPs/<pkg>/fonts/<handle>/,与app.json "fonts"声明对齐,校验同上(待面板后续扩展)。 - 导出:系统库把
MeowOS/fonts/<family>/<weight>/三件套打包为<family>-<weight>.font.tar.gz;应用库同理(待扩展)。 - 约定:
.tar.gz布局与校验沿用font.jsonschema(§5.2);导入/导出后的一致性(列表刷新、应用声明同步)归 MeowPanel + launcher 协作。安全:tar 解出条目逐个校验(拒绝对路径/../软链/多出条目/子目录包裹),沿用 nyai 的 sanitize 思路。
- 已由 MeowPanel 后端落地:
- 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,值 = 字体
<family>/<weight>相对路径(如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(命中则覆盖全局;类值为空=跟随全局不注入)。SDKmeow_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":"<tier>"声明(launchermeow_parse_app_json已解析);activity 级(如需)以route.<id>.fonts声明(沿用route.<id>扩展口径)。launcher 启动 app 时据声明 +font.load_full算生效档,经 env 注入(MEOW_FONT_PNG/IDX指向所选档位字库绝对路径;MEOW_FONT_TIER标注档位;launchermeow_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":[<handle>…]为应用自带字库句柄数组;本小节"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/amsd DECLARE 残余(am startACK 后 launcher 未真拉起 App)/流媒体客户端出声终验(链路技术指标已全绿: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/launcherfork+exec+waitpid仍为备选);写(已改板载MeowOS/services.d/mdnsd.conf落地 mDNS/usr/data/meow/services.d/mdnsd.conf预置,trigger=boot)。剩余:capsetcap 真机实装(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.hmeow_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/<app_id>.log(单文件);meow_ui.h §9 / DEV_NOTES #9 为apps/<包名>/logs/<启动时间>_<pid>.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/vsMeowOpt/(已归并):曾有顶层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.<id>.fullscreen预设 SDK 全屏(envMEOW_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":[<handle>…]=应用自带字库句柄数组;§5.2/§5.7.8"fonts":"full"|"gbk"|"common"=字库档位字符串。→ 同名键两种语义,解析器需区分(字符串→档位 / 数组→句柄);若避免歧义可改用专键如"font_tier"(未拍板)。[各源标注见上]