From f50abae02a4ca16d848157fa3378813957098f4c Mon Sep 17 00:00:00 2001 From: MeowOS Date: Mon, 31 Aug 2026 04:14:00 +0800 Subject: [PATCH] =?UTF-8?q?feat(launcher):=20=E5=BA=94=E7=94=A8=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E7=83=AD=E9=87=8D=E8=BD=BD=20=E2=80=94=202s=20?= =?UTF-8?q?=E8=BD=AE=E8=AF=A2=E6=AF=94=E5=AF=B9=20MeowAPPs=20=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E7=AD=BE=E5=90=8D(=E8=87=AA=E8=BA=AB+=E5=90=84?= =?UTF-8?q?=E5=BA=94=E7=94=A8=E7=9B=AE=E5=BD=95=20mtime=20FNV=20=E6=B7=B7?= =?UTF-8?q?=E5=90=88)=EF=BC=8C=E5=8F=98=E5=8C=96=E5=8D=B3=E9=87=8D?= =?UTF-8?q?=E6=89=AB=E5=88=B7=E6=96=B0=EF=BC=9B=E5=B8=B8=E9=A9=BB=E4=B8=BB?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E6=8E=A8=E6=96=B0=E5=8C=85=E7=BA=A6=202s=20?= =?UTF-8?q?=E5=86=85=E5=87=BA=E7=8E=B0=EF=BC=8C=E4=B8=8D=E5=86=8D=E9=9C=80?= =?UTF-8?q?=E9=87=8D=E5=90=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- patch_v2/meow_launcherd/main_menu.c | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/patch_v2/meow_launcherd/main_menu.c b/patch_v2/meow_launcherd/main_menu.c index 60229b2..c8b7e64 100644 --- a/patch_v2/meow_launcherd/main_menu.c +++ b/patch_v2/meow_launcherd/main_menu.c @@ -273,6 +273,32 @@ static int sim_exit_tap_done = 0; /* real menu loop */ +/* M2.77 应用列表热重载:MeowAPPs 目录签名(自身 + 各应用目录 mtime 的 FNV 混合), + * run_menu 2s 轮询比对,变化即重扫——覆盖 SSH/面板推新包、删包、应用目录内容变动等场景 + * (此前仅「无卡→有卡」过渡才重扫,常驻主界面下推包不刷新)。 */ +static unsigned long long apps_dir_sig(void) +{ + unsigned long long sig = 1469598103934665603ULL; /* FNV-1a offset */ + struct stat st; + if (stat(MEOWAPPS, &st) != 0) return 0; + sig ^= (unsigned long long)st.st_mtime; sig *= 1099511628211ULL; + DIR *d = opendir(MEOWAPPS); + if (d) { + struct dirent *de; + while ((de = readdir(d))) { + if (de->d_name[0] == '.') continue; + char p[300]; + snprintf(p, sizeof p, "%s/%s", MEOWAPPS, de->d_name); + if (stat(p, &st) == 0 && S_ISDIR(st.st_mode)) { + sig ^= (unsigned long long)st.st_mtime * 256 + (unsigned char)de->d_name[0]; + sig *= 1099511628211ULL; + } + } + closedir(d); + } + return sig; +} + static void run_menu(struct app apps[MAX_APPS], int napps, int state, long sim_tap_ms, long sim_exit_ms) { @@ -289,6 +315,7 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state, int had_player = 0; /* M2.2:菜单打开时是否存在存活播放器 */ long sim_tap_done = 0, sim_exit_done = 0; long meow_last_poll = 0; /* M2.2:MeowOS 后台拔营(卡/网)轮询时间戳 */ + unsigned long long apps_sig = 0; /* M2.77:应用目录签名(0=未初始化,首圈建立基线) */ load_config(); /* meow.conf on the card: bg_color etc. */ @@ -502,6 +529,28 @@ static void run_menu(struct app apps[MAX_APPS], int napps, int state, } g_sys.sd_mounted = 1; log_poll_card(); + /* M2.77 应用列表热重载:目录签名变化(推新包/删包/应用目录变动)→ 重扫刷新。 + * 与上面「无卡→有卡」过渡重扫互补:常驻主界面下目录内容变化也覆盖。 */ + { + unsigned long long asig = apps_dir_sig(); + if (apps_sig && asig && asig != apps_sig) { + struct app fresh[MAX_APPS]; + int fn = scan_apps(fresh); + int fstate = (fn < 0) ? (fn == -1 ? 1 : 2) : (fn == 0 ? 2 : 0); + if (fstate == 0 && fn > 0) { + memcpy(apps, fresh, sizeof fresh); + napps = fn; state = 0; + if (cursor >= napps) cursor = napps - 1; + dirty = 1; + logmsg("hot-reload: MeowAPPs changed -> %d apps", napps); + } else if (fstate != state) { + state = fstate; napps = (fn > 0) ? fn : 0; + dirty = 1; + logmsg("hot-reload: state -> %d", state); + } + } + apps_sig = asig; + } } else if (!sd_mounted()) { /* 卡在但未挂载(正挂载/失败):保持当前显示不误判;不崩。 */ g_sys.sd_mounted = 0;