feat(launcher): M3导航栈+M5通知点击跳转 (agent-202) — nav_stack(≤16深)+MSG_NAV REPORT/EXIT+launch_activity链路注入(MEOW_ACTIVITY/MEOW_CHAIN)+栈根退出回主屏; 通知点击按route_status(0拉起/1 NO ROUTE/2 SOURCE NOT FOUND/-1 NONE关面板不动作); picker协议位预留(0x0070/0x0071); 裸App兼容

launcher 4fe4103a→a42171a1; qemu实测 declare/query/nav report/exit/notify+querynotif 全过
发现: §10.5 App前台通知中心叠加会话(MSG_NOTIF_OPEN)实际未实现,文档超前,待补
This commit is contained in:
MeowOS committed 2026-08-31 06:27:10 +08:00
1 parent 955dbe1228
commit 85b4aea24f
9 files changed
+321 -39

No files matched your search

+49 -13
View File
@@ -420,6 +420,7 @@ static void menu_cell_rect(int i, int layout, int apps_top,
static int menu_hit_app(int x, int y, struct app *apps, int napps, int state,
int layout, int apps_top)
{
(void)apps; /* 命中判定只依赖几何;apps 保留作接口(0-warning) */
if (state != 0 || napps <= 0) return -1;
for (int i = 0; i < napps; i++) {
int cx, cy, cw, ch;
@@ -1151,8 +1152,11 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
t_last_y - loy);
t_down = 0; t_down_valid = 0; /* 消费本次手势:返回后不再判 tap/滑动/重开 */
menu_arm_touch(TAP_ARM_DELAY_MS);
int want_launch = -1;
run_notif_center(apps, napps, &want_launch, 1, t_down_x, loy);
notif_click_t click;
memset(&click, 0, sizeof click);
click.app_idx = -1;
click.status = NOTIF_CLICK_STATUS_NONE;
run_notif_center(apps, napps, &click, 1, t_down_x, loy);
/* 重播按键防抖基线(同原 top-swipe 路径),防面板内电源/音量边沿被 run_menu 误判 */
memset(&kd_pwr, 0, sizeof kd_pwr);
memset(&kd_vold, 0, sizeof kd_vold);
@@ -1167,17 +1171,32 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms();
menu_arm_touch(800);
dirty = 1;
if (want_launch >= 0 && want_launch < napps) {
logmsg("menu: notification launch app idx=%d", want_launch);
int ret = launch_app(&apps[want_launch]);
/* M5:通知点击按 route_status 产出 click(0 跳转 / 1 NO ROUTE / 2 SOURCE NOT FOUND) */
if (click.status == NOTIF_CLICK_STATUS_OK &&
click.app_idx >= 0 && click.app_idx < napps) {
logmsg("menu: notif click -> launch idx=%d chain=\"%s\"",
click.app_idx, click.chain);
int ret = click.chain[0]
? launch_activity(&apps[click.app_idx], click.chain)
: launch_app(&apps[click.app_idx]);
menu_after_app_exit(ret == 0);
last_input_ms = now_ms();
dirty = 1;
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s",
apps[want_launch].name);
apps[click.app_idx].name);
toast_ms = TOAST_MS;
}
} else if (click.status == NOTIF_CLICK_STATUS_NOROUTE) {
logmsg("menu: notif click NO ROUTE");
snprintf(toast, sizeof toast, "NO ROUTE");
toast_ms = TOAST_MS;
dirty = 1;
} else if (click.status == NOTIF_CLICK_STATUS_NOSRC) {
logmsg("menu: notif click SOURCE NOT FOUND");
snprintf(toast, sizeof toast, "SOURCE NOT FOUND");
toast_ms = TOAST_MS;
dirty = 1;
}
continue; /* 本圈不再按 tap/其余处理(剩余事件因 t_down=0 成 no-op) */
}
@@ -1228,8 +1247,11 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
if (mnp_top_swipe_down(tx, ty, dx, dy, SB_BAR_H, MENU_SWIPE_THRESH)) {
logmsg("menu: top-edge swipe-down -> notification center (release edge, fallback)");
menu_arm_touch(TAP_ARM_DELAY_MS);
int want_launch = -1;
run_notif_center(apps, napps, &want_launch, 0, 0, 0); /* ⑨ live_open=0 → 触发式自动展开(防御) */
notif_click_t click;
memset(&click, 0, sizeof click);
click.app_idx = -1;
click.status = NOTIF_CLICK_STATUS_NONE;
run_notif_center(apps, napps, &click, 0, 0, 0); /* ⑨ live_open=0 → 触发式自动展开(防御) */
/* 重播按键防抖基线,防面板内电源/音量边沿被 run_menu 误判(M2.25 同款)。 */
memset(&kd_pwr, 0, sizeof kd_pwr);
memset(&kd_vold, 0, sizeof kd_vold);
@@ -1244,18 +1266,32 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state,
last_input_ms = now_ms();
menu_arm_touch(800);
dirty = 1;
/* 点击通知命中可启动 app → 走标准启动链路(与触摸行同路径)。 */
if (want_launch >= 0 && want_launch < napps) {
logmsg("menu: notification launch app idx=%d", want_launch);
int ret = launch_app(&apps[want_launch]);
/* M5:通知点击按 route_status 产出 click(0 跳转 / 1 NO ROUTE / 2 SOURCE NOT FOUND) */
if (click.status == NOTIF_CLICK_STATUS_OK &&
click.app_idx >= 0 && click.app_idx < napps) {
logmsg("menu: notif click -> launch idx=%d chain=\"%s\"",
click.app_idx, click.chain);
int ret = click.chain[0]
? launch_activity(&apps[click.app_idx], click.chain)
: launch_app(&apps[click.app_idx]);
menu_after_app_exit(ret == 0);
last_input_ms = now_ms();
dirty = 1;
if (ret != 0) {
snprintf(toast, sizeof toast, "CANNOT START: %s",
apps[want_launch].name);
apps[click.app_idx].name);
toast_ms = TOAST_MS;
}
} else if (click.status == NOTIF_CLICK_STATUS_NOROUTE) {
logmsg("menu: notif click NO ROUTE");
snprintf(toast, sizeof toast, "NO ROUTE");
toast_ms = TOAST_MS;
dirty = 1;
} else if (click.status == NOTIF_CLICK_STATUS_NOSRC) {
logmsg("menu: notif click SOURCE NOT FOUND");
snprintf(toast, sizeof toast, "SOURCE NOT FOUND");
toast_ms = TOAST_MS;
dirty = 1;
}
continue; /* 本圈不再按 tap/其余处理 */
}