fix: M6.41批 — 启动失败原因透传 + 阅读器左缘返回/阅读页接入view栈 + 后台管理按钮点不动 + 阅读器瘦身(fonts common+页位图释放) + files txt换行

- launcher(453): app_launcher.c g_launch_fail_reason+launch_fail()统一出口(5失败点 fork OOM/exec/no such file/missing dep/execpipe)+main_menu.c launch_fail_toast(缺依赖/CANNOT START: name(reason))+toast256
- launcher(457): bg_page.c bgm_enumerate跳过term_at_ms(杀后当下消失)+不可杀行按钮置灰+row_tap/top_action返回1; subpage.c 消warning
- reader(454): reader_on_swipe LEFT/RIGHT→返回(先关overlay否则page_pop回书架)+app.c书架根LEFT→exit
- reader(458瘦身A+B): app.json fonts full→common(省13MB atlas)+reader.c RD_PAGE_CACHE 3→2+g_anim_old懒分配/anim_done释放+on_enter/on_leave页位图离开释放重建
- reader(459导航): reader_open返回int+shelf点书push ACT_READER(阅读页接入view栈,on_enter/on_leave驱动) — 使454左缘返回+458瘦身B真正生效
- files(455): viewer.c viewer_cp_len+按码位折行(txt中文不冲出右缘)

0warning;宿主测试全过;files二进制已热更
This commit is contained in:
AskaEth committed 2026-09-04 19:43:28 +08:00
1 parent 626a87a30d
commit ddc8d35eb9
11 files changed
+154 -66

No files matched your search

+29 -28
View File
@@ -38,8 +38,6 @@ typedef struct {
int napps;
bgmgr_row_t rows[MEOW_BGMR_ROW_MAX];
int n;
char toast[64];
long toast_ms;
} bgm_ctx_t;
/* 找 struct app(launcher 应用表)by id */
@@ -71,19 +69,24 @@ static int bgm_app_meta(void *ctx, const char *app_id, pid_t pid,
static int bgm_enumerate(void *ctx, bgmgr_row_t *rows, int max)
{
(void)ctx;
int n = meow_bg_count();
if (n > max) n = max;
for (int i = 0; i < n; i++) {
/* 逐槽扫描并**压缩**(g_bg 可能有空洞),跳过已发出终止的条目:
* meow_bg_terminate 只置 term_at_ms 发 SIGTERM,真正的 reap/摘表在 meow_bg_tick(launcher
* 主循环),它在本页 meow_subpage_run 阻塞期间**不跑**——若不在此过滤,kill/清后旧行会一直
* 残留(pid 已死/0 CPU),页面上看就是「点不动」。过滤后 kill/一键清当下即从列表消失(可见反馈)。 */
int k = 0;
for (int i = 0; i < MEOW_BG_MAX && k < max; i++) {
const meow_bg_entry_t *e = meow_bg_at(i);
if (!e || !e->used || !e->app_id[0]) continue;
memset(&rows[i], 0, sizeof rows[i]);
snprintf(rows[i].app_id, sizeof rows[i].app_id, "%s", e->app_id);
rows[i].pid = e->pid;
rows[i].keepalive = (e->keepalive ? 1 : 0);
rows[i].on_card = (e->on_card ? 1 : 0);
rows[i].bg_since_ms = e->bg_since_ms;
if (e->term_at_ms) continue; /* 已进入终止序列(kill/宽限回收/卡拔)→ 行不再显示 */
memset(&rows[k], 0, sizeof rows[k]);
snprintf(rows[k].app_id, sizeof rows[k].app_id, "%s", e->app_id);
rows[k].pid = e->pid;
rows[k].keepalive = (e->keepalive ? 1 : 0);
rows[k].on_card = (e->on_card ? 1 : 0);
rows[k].bg_since_ms = e->bg_since_ms;
k++;
}
return n;
return k;
}
/* proc_sample:/proc/<pid>/stat(utime+stime 差分) + /proc/<pid>/status(VmRSS)。
@@ -226,12 +229,16 @@ static void bgm_row_draw(void *ctx, int idx, sub_row_t *r,
int ry = cy + (ch - (th + tsub + 4)) / 2; /* 内容在卡内垂直居中(行中心=卡中心) */
if (r->label) meow_ui_text(rx, ry, r->label, 20, mt->onSurface);
if (r->sub) meow_ui_text(rx, ry + th + 4, r->sub, 16, mt->onSurfaceVariant);
/* 行内杀按钮(全形=胶囊(bh/2);「杀」;error=红=杀)——P1 按钮胶囊化 */
/* 行内杀按钮(全形=胶囊(bh/2);「杀」;error=红=杀)——P1 按钮胶囊化。
* 不可杀行(框架/前台/无进程,bgmgr_can_kill=0)→ 置灰禁点外观,避免误导(按钮可点但不可杀)。 */
int bx, by, bw, bh; bgm_btn_rect(x, y, w, h, &bx, &by, &bw, &bh);
meow_ui_draw_rect_round(bx, by, bw, bh, bh / 2, mt->error);
uint32_t btn_col = mt->error; /* 可杀:error 红 */
if (i >= 0 && i < b->n && !b->rows[i].killable)
btn_col = mt->onSurfaceVariant; /* 禁点:置灰(onSurfaceVariant) */
meow_ui_draw_rect_round(bx, by, bw, bh, bh / 2, btn_col);
int bth = meow_ui_text_height(16);
if (bth > bh) bth = bh;
meow_ui_text_center(bx + bw / 2, by + (bh - bth) / 2, "杀", 16, mt->error);
meow_ui_text_center(bx + bw / 2, by + (bh - bth) / 2, "杀", 16, btn_col);
}
/* ---- 行内自定义命中(sub_page_t.row_tap;仅按钮区 kill,行体不响应/不误杀)---- */
@@ -244,14 +251,9 @@ static int bgm_row_tap(void *ctx, int idx, sub_row_t *r, int x, int y,
if (i < 0 || i >= b->n) return 0; /* 空态行无按钮 */
int bx, by, bw, bh; bgm_btn_rect(rx, ry, rw, rh, &bx, &by, &bw, &bh);
if (x < bx || x >= bx + bw || y < by || y >= by + bh) return 0; /* 行体/按钮外 → 不杀 */
if (!bgmgr_can_kill(&b->rows[i])) {
snprintf(b->toast, sizeof b->toast, "该 App 不可杀(框架/前台)");
b->toast_ms = (long)now_ms();
return 1;
}
meow_bg_terminate(b->rows[i].app_id);
snprintf(b->toast, sizeof b->toast, "已请求终止 %s", b->rows[i].app_id);
b->toast_ms = (long)now_ms();
if (!bgmgr_can_kill(&b->rows[i]))
return 1; /* 禁点:不可杀(框架/前台/无进程)→ 按钮已置灰,不 kill(返回 1=重绘) */
meow_bg_terminate(b->rows[i].app_id); /* 置 term_at_ms → bgm_enumerate 下一跳行消失(可见反馈) */
return 1;
}
@@ -270,11 +272,10 @@ static int bgm_top_action(void *ctx)
memset(&ops, 0, sizeof ops);
ops.ctx = b;
ops.enumerate = bgm_enumerate; /* 行已由 bgm_rows 建 */
int k = bgmgr_kill_all(&ops, b->rows, b->n, bgm_kill_fn);
if (k > 0) snprintf(b->toast, sizeof b->toast, "已清 %d 个后台 App", k);
else snprintf(b->toast, sizeof b->toast, "无后台 App 可清");
b->toast_ms = (long)now_ms();
return 1;
/* kill 只置 term_at_ms(真退/摘表在 launcher 主循环 bgm_tick),此处由 bgm_enumerate 过滤
* term_at_ms 让清后的行当下消失(可见反馈;不可杀行本就在上/一键不杀)。 */
bgmgr_kill_all(&ops, b->rows, b->n, bgm_kill_fn);
return 1; /* 重绘:重扫行(已清行消失) */
}
/* ---- 入口:运行后台管理页(阻塞到返回)---- */