fix(sdk+launcher): 图标不渲染真根因(agent-219) — meow_ui_img.c scale_buf cover 采样把乘写成除(÷缩放比→采到源图左上角透明区,全丢); 改乘+居中裁剪偏移修正; 宿主旧测试用纯色图掩盖了该bug。+ main_menu App退出/结构变化重绘时 fb_pan_buf0_force 无条件pan回buffer0(防App翻页留buffer1致菜单残帧)

meow_ui.a→3e0ee8f7 launcher→9d0efc2f hello→9609ea6e files→90f5cf07 ncm→be8be221(均已上卡); 真机截图证据 .tmp/meowbug/fix1.png+fix_b2_after.png
This commit is contained in:
MeowOS committed 2026-08-31 15:42:24 +08:00
1 parent 05a19a9ea3
commit ab4da09e75
45 files changed
+1926 -147

No files matched your search

+90 -2
View File
@@ -1097,6 +1097,32 @@ void meow_ipc_process(void)
}
/* ---- AMSD_DESIGN §6.2 二期:launcher → amsd 转发工具(best-effort)---- */
/* hex 编码二进制/字符串到 out(小写 2 字符/字节)。返回编码字节数。 */
static int ams_hex_encode(const unsigned char *src, int slen, char *out, int outsz)
{
static const char *hx = "0123456789abcdef";
int n = 0;
for (int i = 0; i < slen && n + 2 < outsz; i++) {
out[n++] = hx[src[i] >> 4];
out[n++] = hx[src[i] & 15];
}
out[n] = 0;
return n;
}
/* m_act_declare_t.entries 为 count 个 NUL 结尾 "id=chain" 串的拼接;返回其字节长(含 NUL)。 */
static int declare_entries_len(const m_act_declare_t *d)
{
const char *p = d->entries;
for (int k = 0; k < d->count && *p; k++) {
while (*p) p++;
p++;
}
return (int)(p - d->entries);
}
/* 处理一条入队帧:HELLO→ACK、ACT_QUERY→ACT_RESULT/ERR、ACT_DECLARE→ACK、其他→ERR。 */
static void ipc_dispatch(struct meow_ipc_msg *m)
{
@@ -1125,6 +1151,18 @@ static void ipc_dispatch(struct meow_ipc_msg *m)
a.status = (uint32_t)g_naccts;
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
logmsg("ipc: ACT_DECLARE app=%s n=%u -> ACK", d.app_id, d.count);
/* AMSD_DESIGN §6.2 二期:运行时 declare 转发 amsd(权威表增量;amsd 不在→静默丢)。
* entries 载荷 hex 编码(含 NUL 分隔),amsd 解码后并集覆盖。 */
{
int elen = declare_entries_len(&d);
if (elen > 0) {
char hex[2 * MEOW_IPC_CARGO + 8];
(void)ams_hex_encode((const unsigned char *)d.entries, elen, hex, sizeof hex);
char fwd[2 * MEOW_IPC_CARGO + 80];
int fl = snprintf(fwd, sizeof fwd, "DECLARE %s %d %s\n", d.app_id, (int)d.count, hex);
if (fl > 0) meow_ams_send(fwd, fl);
}
}
break;
}
case MSG_ACT_QUERY: {
@@ -1214,12 +1252,21 @@ static void ipc_dispatch(struct meow_ipc_msg *m)
memcpy(&s, m->payload, m->plen < (uint16_t)sizeof s ? m->plen : (uint16_t)sizeof s);
s.app_id[MEOW_APP_ID_MAX - 1] = 0;
s.activity[MEOW_ACT_MAX - 1] = 0;
int rc = meow_ams_pending_start_set(s.app_id, s.activity);
s.picker_action[23] = 0;
s.picker_caller[MEOW_APP_ID_MAX - 1] = 0;
/* §6.2 二期:Picker 上下文(picker=1 且 action 非空)→ 置位武装位,launch_app_chain 注入 env */
int rc;
if (s.picker)
rc = meow_ams_pending_start_set_ex(s.app_id, s.activity,
s.picker_action, s.picker_req_id, s.picker_caller);
else
rc = meow_ams_pending_start_set(s.app_id, s.activity);
m_ack_t a;
a.code = (uint32_t)(rc < 0 ? -rc : MEOW_OK); /* 0=OK;MEOW_ERR_BUSY=有前台 App */
a.status = 0;
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
logmsg("ipc: AMS_START app=%s act=\"%s\" -> ACK code=%u", s.app_id, s.activity, a.code);
logmsg("ipc: AMS_START app=%s act=\"%s\" picker=%u req=%u -> ACK code=%u",
s.app_id, s.activity, s.picker, s.picker_req_id, a.code);
break;
}
case MSG_AMS_KILL: {
@@ -1239,6 +1286,47 @@ static void ipc_dispatch(struct meow_ipc_msg *m)
logmsg("ipc: AMS_KILL app=%s -> ACK code=%u", k.app_id, a.code);
break;
}
/* AMSD_DESIGN §6.2 二期:picker 跨 App 调用(App A → launcher → amsd 路由)。
* launcher 仅转发 amsd + ACK 发起方(best-effort;结果经 MSG_PICKER_RESULT 回路记录)。
* 诚实出入:A 发送后即断开,amsd 结果暂时落记录(picker-status 可查),push 回 A 需
* 将来 MSG_REGISTER 会话通道(M4)。 */
case MSG_PICKER_CALL: {
m_picker_call_t p;
memset(&p, 0, sizeof p);
memcpy(&p, m->payload, m->plen < (uint16_t)sizeof p ? m->plen : (uint16_t)sizeof p);
p.caller[MEOW_APP_ID_MAX - 1] = 0;
p.action[23] = 0;
m_ack_t a;
a.code = MEOW_OK;
a.status = 0;
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
char fwd[96];
int fl = snprintf(fwd, sizeof fwd, "PICKER_CALL %s %u %s\n", p.caller, p.req_id, p.action);
if (fl > 0) meow_ams_send(fwd, fl);
logmsg("ipc: PICKER_CALL caller=%s req=%u act=%s -> ACK", p.caller, p.req_id, p.action);
break;
}
/* AMSD_DESIGN §6.2 二期:picker 结果回传(handler App → launcher → amsd 记录)。
* value 可能含空格 → hex 编码,amsd 解码。 */
case MSG_PICKER_RESULT: {
m_picker_result_t r;
memset(&r, 0, sizeof r);
memcpy(&r, m->payload, m->plen < (uint16_t)sizeof r ? m->plen : (uint16_t)sizeof r);
r.caller[MEOW_APP_ID_MAX - 1] = 0;
r.action[23] = 0;
m_ack_t a;
a.code = MEOW_OK;
a.status = 0;
ipc_send(m->fd, MSG_ACK, m->req_id, &a, sizeof a);
char hex[512 + 8];
(void)ams_hex_encode((const unsigned char *)r.value, (int)strlen(r.value), hex, sizeof hex);
char fwd[96 + 512 + 8];
int fl = snprintf(fwd, sizeof fwd, "PICKER_RESULT %u %s %u %s\n",
r.req_id, r.action, r.code, hex);
if (fl > 0) meow_ams_send(fwd, fl);
logmsg("ipc: PICKER_RESULT req=%u act=%s code=%u value=\"%s\"", r.req_id, r.action, r.code, r.value);
break;
}
/* M2a:通知存储(NOTIFICATION_SYSTEM.md §4/§7/§8)。IPC 线程只入队,此处在主循环
* 单写者落存储 + 回 ACK(与 HELLO/QUERY 同一线程模型,绝不在 socket IO 阻塞)。 */
case MSG_NOTIFY: {