图库: 修系统返回语义与打开册资源路径(M15)
- 返回手势:书库列表排除左缘 24px 系统返回带并清空残留拖拽态;library_go_up 到 TF 根返回 0(app.c 退出 App),不再上溯系统目录;顶栏返回改为显式 library_go_parent(访问放开,可越过 TF 根到 /)。lock 页继续自行消费返回。 - 打开册:缩略图源图改用预算解码(meow_img_load_file_dim,峰值数十 MB→~1MB); 离开书库页停止后台探测/缩略图线程,避免与 open_book 争内存/FD;打开失败按 errno 记日志,ENOMEM/EMFILE/ENFILE/EAGAIN/EINTR 自动重试一次;修 open_book 自拷贝 snprintf 的未定义行为。 - 测试:test_browse_ui_host 增加 TF 根退出/顶栏上级/左缘不拖拽断言;新增 test_open_book_host(封面图+含图子目录的父目录 → reader 打开的完整 UI 链路)。
This commit is contained in:
1 parent
5ac227b225
commit
3cbcaaaac1
7 files changed
+377
-13
No files matched your search
@@ -6,8 +6,8 @@
|
||||
* - 首帧只做**单层**枚举(logic/library.c:一次 opendir/readdir+lstat),
|
||||
* 不做任何递归「子树含图」探测;列表行 = 当前目录的直接子目录(M11 起还包括
|
||||
* .cbz/.zip 档案册,与目录自然序混排);
|
||||
* - 系统目录/空目录/无图目录都列出且可进入;可一路向上到文件系统 '/',
|
||||
* 左缘返回由 app.c 逐级上溯、到 '/' 才退出 App;
|
||||
* - 系统目录/空目录/无图目录都列出且可进入;左缘返回按系统语义逐级上移,
|
||||
* **到 TF 根即退出 App**(不再上溯系统目录);TF 根以外的上级浏览走顶栏「上级」动作;
|
||||
* - 「直接含图目录=一本书」与档案册页数改为后台懒算:行仍在 PENDING 时副标题「…」,
|
||||
* 后台线程用 mr_library_probe_path(单层 + mtime/size 失效缓存)算出页数/首图,
|
||||
* on_tick 补位后只 invalidate 列表视口——首帧/滚动/命中判定都不读子目录/档案;
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
#define MR_THUMB_MAX 24
|
||||
#define MR_THUMB_DIM 96
|
||||
#define MR_THUMB_DECODE_DIM 256 /* 缩略图源图预算解码边长(峰值 ~1MB;整幅解码可达数十 MB) */
|
||||
#define MR_TOPAPPBAR_H 56
|
||||
#define MR_DEFAULT_ROW_H 56
|
||||
#define MR_CACHE_MAX_FILES 64
|
||||
@@ -294,7 +295,10 @@ static meow_img *thumb_load(const char *cover)
|
||||
}
|
||||
}
|
||||
|
||||
meow_img *im = meow_img_load_file(src);
|
||||
/* 预算解码:封面可能是 12MP 手机照片,整幅解码峰值 ~48MB,会在低内存设备上
|
||||
* 挤掉随后 reader 打开所需的 opendir/malloc(用户报告「点开父文件夹=无法打开此册」)。
|
||||
* 缩略图最终只要 96px,先解到 ≤MR_THUMB_DECODE_DIM 再精修,视觉无损、峰值 ~1MB。 */
|
||||
meow_img *im = meow_img_load_file_dim(src, MR_THUMB_DECODE_DIM);
|
||||
if (!im) return NULL;
|
||||
meow_img *small = meow_img_downscale(im, MR_THUMB_DIM);
|
||||
if (small) { meow_img_free(im); im = small; }
|
||||
@@ -559,7 +563,8 @@ static void update_topbar(void)
|
||||
if (slash && slash[1]) title = slash + 1;
|
||||
}
|
||||
meow_topappbar_set_title(g_tb, title);
|
||||
/* 可一路向上到文件系统 '/':到 '/' 才隐藏返回(此时左缘返回=退出 App)。 */
|
||||
/* 顶栏「上级」是显式浏览动作(访问放开,可越过 TF 根上溯到 '/');
|
||||
* 左缘返回是系统返回语义,TF 根=退出 App(见 library_go_up)。到 '/' 才隐藏。 */
|
||||
meow_topappbar_set_back(g_tb, strcmp(g_cur_dir, "/") != 0);
|
||||
}
|
||||
|
||||
@@ -640,7 +645,8 @@ static int load_dir(const char *dir)
|
||||
char msg[200];
|
||||
snprintf(msg, sizeof msg, "无法读取目录:%s", name);
|
||||
show_hint(msg);
|
||||
meow_log(MEOW_LOG_WARN, "library scan failed: %s", target);
|
||||
meow_log(MEOW_LOG_WARN, "library scan failed: %s (errno=%d %s)", target,
|
||||
errno, strerror(errno));
|
||||
/* 启动首帧根目录不可读:仍建一个空列表,页面可交互(返回/回根/上溯)。 */
|
||||
if (!g_lv) {
|
||||
mr_library_free(&g_lib);
|
||||
@@ -678,7 +684,17 @@ int library_at_root(void)
|
||||
|
||||
int library_go_up(void)
|
||||
{
|
||||
if (strcmp(g_cur_dir, "/") == 0) return 0; /* 到文件系统根:交给 app.c 退出 */
|
||||
/* 系统返回语义:TF 根 = 退出 App(app.c 收到 0 后 request_exit),
|
||||
* 不再上溯系统目录;文件系统 "/" 同理。 */
|
||||
if (strcmp(g_cur_dir, g_root_dir) == 0) return 0;
|
||||
if (strcmp(g_cur_dir, "/") == 0) return 0;
|
||||
return library_go_parent();
|
||||
}
|
||||
|
||||
/* 顶栏「上级」:显式浏览动作,访问放开——可越过 TF 根一路到 '/'。 */
|
||||
int library_go_parent(void)
|
||||
{
|
||||
if (strcmp(g_cur_dir, "/") == 0) return 0;
|
||||
char parent[MR_PATH_MAX];
|
||||
if (mr_path_parent(g_cur_dir, parent, (int)sizeof parent) != 0) return 0;
|
||||
if (!load_dir(parent)) {
|
||||
@@ -719,10 +735,13 @@ static void library_open_entry(int idx)
|
||||
|
||||
if (e->probe_state == MR_LIB_PENDING) {
|
||||
mr_library_probe p;
|
||||
if (mr_library_probe_path(e->path, e->is_archive, cbz_archive_pages, NULL, &p) == 0)
|
||||
if (mr_library_probe_path(e->path, e->is_archive, cbz_archive_pages, NULL, &p) == 0) {
|
||||
mr_library_apply_probe(&g_lib, idx, &p);
|
||||
else
|
||||
} else {
|
||||
meow_log(MEOW_LOG_WARN, "library probe failed: %s (errno=%d %s)", e->path,
|
||||
errno, strerror(errno));
|
||||
mr_library_mark_error(&g_lib, idx);
|
||||
}
|
||||
list_invalidate();
|
||||
}
|
||||
if (e->probe_state == MR_LIB_FAILED) {
|
||||
@@ -752,7 +771,7 @@ void library_on_tap(int x, int y)
|
||||
|
||||
if (g_tb) {
|
||||
int hit = meow_topappbar_hit(g_tb, x, y);
|
||||
if (hit == MEOW_TOPBAR_BACK) { library_go_up(); return; }
|
||||
if (hit == MEOW_TOPBAR_BACK) { library_go_parent(); return; }
|
||||
if (g_tb_home_idx >= 0 && hit == g_tb_home_idx) { library_go_tf_root(); return; }
|
||||
if (hit >= 0) { meow_view_page_push(ACT_SETTINGS); return; }
|
||||
}
|
||||
@@ -788,8 +807,14 @@ void library_on_swipe(int dir, int dist)
|
||||
void library_on_touch_down(int x, int y)
|
||||
{
|
||||
if (!g_ctrl.active || !g_lv) return;
|
||||
/* 每次按下都作废上一次手势的拖拽状态:热区/左缘提前返回时不能残留 g_drag,
|
||||
* 否则系统返回手势的 move 仍会驱动列表滚动。 */
|
||||
g_drag = 0;
|
||||
g_dragged = 0;
|
||||
/* 屏底 28px 是系统「上滑回桌面」热区:不从这里启动列表拖拽,避免拦截系统手势。 */
|
||||
if (y >= meow_ui_height() - 28) return;
|
||||
/* 左缘 24px 是系统返回手势带(与 reader 同口径):列表不启动拖拽,把滑动留给系统返回。 */
|
||||
if (x < 24) return;
|
||||
if (x < g_list_x || x >= g_list_x + g_list_w ||
|
||||
y < g_list_y || y >= g_list_y + g_list_h) return;
|
||||
g_drag = 1;
|
||||
@@ -911,6 +936,7 @@ static void library_page_enter(meow_view *v, void *ctx)
|
||||
hint_place();
|
||||
g_drag = 0;
|
||||
g_dragged = 0;
|
||||
worker_start(); /* 离开时停止(见 leave),回页恢复探测/缩略图 */
|
||||
update_topbar();
|
||||
mr_nav_report();
|
||||
meow_ui_paint_full();
|
||||
@@ -923,6 +949,10 @@ static void library_page_leave(meow_view *v, void *ctx)
|
||||
g_drag = 0;
|
||||
g_dragged = 0;
|
||||
if (g_scroll) meow_scroll_stop(g_scroll);
|
||||
/* 停止后台解码:进 reader 前释放/停止潜在的大图解码,避免与 open_book 的
|
||||
* opendir/malloc 抢内存(设备上「点开父文件夹=无法打开此册」的诱因之一)。
|
||||
* worker_stop 会 join,保证 page_push 的 on_enter 打开册时线程已退出。 */
|
||||
worker_stop();
|
||||
}
|
||||
|
||||
static void library_page_destroy(meow_view *v, void *ctx)
|
||||
@@ -1012,6 +1042,23 @@ int library_test_go_up(void)
|
||||
return library_go_up();
|
||||
}
|
||||
|
||||
int library_test_go_parent(void)
|
||||
{
|
||||
return library_go_parent();
|
||||
}
|
||||
|
||||
/* 跟手拖拽是否在本次手势中被启动(左缘/屏底热区排除的回归观测口)。 */
|
||||
int library_test_drag_active(void)
|
||||
{
|
||||
return g_drag;
|
||||
}
|
||||
|
||||
/* 后台探测/缩略图线程是否在跑(离开书库页应停止,回页恢复)。 */
|
||||
int library_test_worker_on(void)
|
||||
{
|
||||
return g_worker_on;
|
||||
}
|
||||
|
||||
/* 缩略图 LRU 接缝(M11 P2-1 回归):指向当前缓存目录并同步跑一次 prune。 */
|
||||
const char *library_test_cache_dir(void)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user