Files
MeowOS-For-R3P2/patch_v2/sdk/test_meow_ui_home_gesture.c
T
AskaEth 501867b362 feat(sdk): M6.39批 — LazyGrid/LazyColumn/LazyRow MD3容器化 + SDK全局App内底部上滑回桌面(系统手势优先)
- meow_ui_widget.c: W_LIST/meow_list/LazyColumn/LazyRow默认container=1(MD3圆角卡surfaceContainer+tonal选中+卡内按压+去分隔线) + 新增meow_list_set_container; 平坦回退set_container(0)
- meow_lazygrid.c: lg_draw_cell容器化(卡内缩8,surfaceContainer圆角+tonal选中+按压)
- meow_ui_input.c: 新增meow_ui_input_is_home_swipe(镜像np_home_gesture:屏底28px热区+上移65px+竖向主导,与左缘返回/列表中滑互斥) + MEOW_EV_HOME分发→meow_ui_nav_request_exit(系统保留手势**优先于App on_swipe**,任意App内生效→MSG_NAV EXIT→批①保活回桌面; 不调request_exit避免进程退出断送保活)
- 声明: meow_ui_input.h / meow_ui_widgets.h 各追加
- 宿主测试: test_meow_ui_home_gesture 19-0 / test_meow_ui_lazygrid 32-0, 0warning
2026-09-04 13:56:11 +08:00

197 lines
9.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* test_meow_ui_home_gesture.c — 批② SDK 全局「App 内底部热区上滑回桌面」宿主验证。
*
* 覆盖(并同 meow_ui_input_is_home_swipe 判据、touch_release 分类、meow_ui_run 分发三层):
* T1 判定矩阵(meow_ui_input_is_home_swipe,镜像 launcher np_gesture.h np_home_gesture):
* 底部热区上滑=1;底部左缘上滑=0(左缘返回互斥);中部上滑=0(App 滚动);底部横向=0;
* 底部下滑=0;上移不足=0;横向主导=0;屏底边界(down_y=fb_h-HOME_EDGE_H)之外=0。
* T2 触摸状态机分类(真实 touch_release → 队列 pop 断言):
* 底部热区上滑→MEOW_EV_HOME(a=MEOW_SWIPE_UP);中部上滑→MEOW_EV_SWIPE(UP)(不被剥回桌面);
* 底部左缘横滑→MEOW_EV_SWIPE(LEFT)(原左缘返回,不被剥)。
* T3 分发(meow_ui_run 主循环,run-loop 复用 test_meow_ui_view_event 的 driver 线程范式):
* 3a 未注册 on_swipe:注入 MEOW_EV_HOME → meow_ui_nav_request_exit 被触发(一次)——回桌面;
* 3b 未注册 on_swipe:注入 MEOW_EV_SWIPE(UP)(中部上滑)→ nav_request_exit 不触发(App 滚动);
* 3c 注册 on_swipe:注入 MEOW_EV_HOME → nav_request_exit 触发(系统级手势优先于 App on_swipe),
* on_swipe 不被调用——屏底热区上滑是系统保留手势,任意 App 内生效(用户 2026-09-04 批②)。
*
* 编译(宿主 gcc,链真实 SDK 源全集 + 打桩 font/global;**不链 meow_ui_nav.c**——本测以测试内
* meow_ui_nav_request_exit 桩计数验证触发):
* gcc -Wall -Wextra -o test_meow_ui_home_gesture test_meow_ui_home_gesture.c test_host_stub.c \
* meow_ui_gfx.c meow_ui_sys.c meow_ui_theme.c meow_ui_vol.c meow_ui_log.c \
* meow_ui_widget.c meow_ui_input.c meow_ui_activity.c meow_ui_dialog.c meow_ui_ime.c meow_ui_str.c \
* meow_pinyin.c meow_ui_draw.c meow_ui_view.c meow_ui_box.c meow_ui_anim.c meow_ui_scroll.c \
* meow_ui_img.c meow_ui_media.c meow_notify_ipc.c stb_image.c \
* -I. -I../meow_launcherd -DMEOW_UI_HOST_TEST -pthread -lm
* 运行:./test_meow_ui_home_gesture
*/
#include "meow_ui.h"
#include "meow_ui_internal.h" /* meow_input_touch_set/move/release + meow_input_pop + MEOW_EV_* */
#include "meow_ui_nav.h" /* meow_ui_nav_request_exit 原型(本测以桩计数验证) */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <assert.h>
/* MEOW_EV_HOME 是 meow_ui_input.c 内部常量(未入公共头,同 MEOW_EV_NOTIF_PULL 惯例),按同值声明。 */
#ifndef MEOW_EV_HOME
#define MEOW_EV_HOME 9
#endif
static int g_pass = 0, g_fail = 0;
#define CHECK(cond, ...) do { \
if (cond) { g_pass++; } \
else { g_fail++; printf("FAIL %s:%d ", __FILE__, __LINE__); printf(__VA_ARGS__); printf("\n"); } \
} while (0)
/* fb 高度(宿主 480x720) */
#define FBW 480
#define FBH 720
/* 判据常量镜像(np_gesture.h NP_HOME_EDGE_H=28 / NP_HOME_SWIPE=65 / NP_EDGE_W=24)。 */
#define H_EDGE 28
#define H_SWIPE 65
#define EDGE_W 24
/* ---- nav_request_exit 桩(不链 meow_ui_nav.c;计数验证 SDK 触发) ---- */
static int g_nav_exit_calls = 0;
void meow_ui_nav_request_exit(void) { g_nav_exit_calls++; }
/* ---- on_swipe 桩(App 接管验证) ---- */
static int g_swipe_calls = 0;
static int g_swipe_dir = -1;
static int g_swipe_dx = 0;
static void app_on_swipe(int dir, int dx, int dy) { (void)dy; g_swipe_calls++; g_swipe_dir = dir; g_swipe_dx = dx; }
/* 从队列 pop 一个事件并回填 (type,a,b);无事件返回 0。 */
static int pop_ev(int *type, int *a, int *b)
{
meow_input_ev e;
if (!meow_input_pop(&e)) return 0;
*type = e.type; *a = e.a; *b = e.b;
return 1;
}
/* ============ T1 判定矩阵(meow_ui_input_is_home_swipe) ============ */
static void test_predicate(void)
{
printf("T1 meow_ui_input_is_home_swipe matrix\n");
int bz = FBH - H_EDGE; /* 底部热区上边界 y = 720-28 = 692 */
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, 0, -120, FBH) == 1, "T1 bottom-hotzone up -> 1");
CHECK(meow_ui_input_is_home_swipe(100, FBH - 1, 20, -80, FBH) == 1, "T1 screen-bottom up (x>EDGE_W) -> 1");
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, 0, -H_SWIPE, FBH) == 1, "T1 exactly threshold up -> 1");
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, -30, -70, FBH) == 1, "T1 up w/ small left dx (adx<dy) -> 1");
/* 左缘互斥(down_x<EDGE_W) */
CHECK(meow_ui_input_is_home_swipe(10, bz + 10, 0, -120, FBH) == 0, "T1 left-edge origin -> 0 (edge-back reserved)");
/* 中部上滑(App 滚动) */
CHECK(meow_ui_input_is_home_swipe(240, 300, 0, -120, FBH) == 0, "T1 mid-screen up -> 0 (App scroll)");
/* 底部横向(左缘返回/横向逻辑保留) */
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, 120, 0, FBH) == 0, "T1 bottom horizontal -> 0");
/* 底部下滑 */
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, 0, 120, FBH) == 0, "T1 bottom down -> 0");
/* 上移不足(<H_SWIPE) */
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, 0, -(H_SWIPE - 1), FBH) == 0, "T1 up below threshold -> 0");
/* 竖向未主导(横向位移≥上移量,adx>=dy) */
CHECK(meow_ui_input_is_home_swipe(240, bz + 10, -120, -80, FBH) == 0, "T1 up w/ big dx (not vertical-dominant) -> 0");
/* 热区边界之外(down_y < bz) */
CHECK(meow_ui_input_is_home_swipe(240, bz - 1, 0, -120, FBH) == 0, "T1 just above hotzone -> 0");
}
/* ============ T2 触摸状态机分类(touch_release → 队列) ============ */
static void test_touch_classify(void)
{
printf("T2 touch_release classification\n");
meow_input_drain();
/* 底部热区上滑 → MEOW_EV_HOME */
meow_input_touch_set(1, 240, FBH - 5, 0); /* 起点 y=715 ∈ [692,720) */
meow_input_touch_move(240, FBH - 5 - 130); /* 上移 130 */
meow_input_touch_release();
{
int t, a, b;
CHECK(pop_ev(&t, &a, &b) == 1 && t == MEOW_EV_HOME && a == MEOW_SWIPE_UP,
"T2 bottom-hotzone up -> MEOW_EV_HOME(UP) got type=%d a=%d", t, a);
}
/* 中部上滑 → 普通 MEOW_EV_SWIPE(UP)(不被剥回桌面) */
meow_input_touch_set(1, 240, 300, 0);
meow_input_touch_move(240, 300 - 130);
meow_input_touch_release();
{
int t, a, b;
CHECK(pop_ev(&t, &a, &b) == 1 && t == MEOW_EV_SWIPE && a == MEOW_SWIPE_UP,
"T2 mid up -> SWIPE(UP) got type=%d a=%d", t, a);
}
/* 底部左缘横滑 → 原有左缘返回(不被剥) */
meow_input_touch_set(1, 5, FBH - 5, 0);
meow_input_touch_move(5 + 100, FBH - 5);
meow_input_touch_release();
{
int t, a, b;
CHECK(pop_ev(&t, &a, &b) == 1 && t == MEOW_EV_SWIPE && a == MEOW_SWIPE_LEFT,
"T2 bottom-left horizontal -> SWIPE(LEFT) got type=%d a=%d", t, a);
}
}
/* ============ T3 分发(meow_ui_run 主循环) ============ */
static int g_inj_type, g_inj_a, g_inj_b;
static void *driver(void *arg)
{
(void)arg;
usleep(700000); /* 等 startup cooldown(500ms) 过后再注入 */
meow_input_inject(g_inj_type, g_inj_a, g_inj_b);
usleep(80000);
meow_ui_request_exit();
return NULL;
}
static void run_scenario(int inj_type, int inj_a, int inj_b, int register_swipe)
{
g_inj_type = inj_type; g_inj_a = inj_a; g_inj_b = inj_b;
g_nav_exit_calls = 0;
g_swipe_calls = 0; g_swipe_dir = -1; g_swipe_dx = 0;
meow_input_drain(); /* 防上一次残留事件影响本次分发 */
meow_ui_events ev; memset(&ev, 0, sizeof ev);
if (register_swipe) ev.on_swipe = app_on_swipe;
pthread_t thd; pthread_create(&thd, NULL, driver, NULL);
meow_ui_run(&ev);
pthread_join(thd, NULL);
}
static void test_dispatch(void)
{
printf("T3 meow_ui_run dispatch (home = nav_request_exit fallback)\n");
/* 3a 未注册 on_swipe:底部热区上滑 → nav_request_exit 触发一次(回桌面) */
run_scenario(MEOW_EV_HOME, MEOW_SWIPE_UP, 120, 0);
CHECK(g_nav_exit_calls == 1, "T3a no-on_swipe MEOW_EV_HOME -> nav_request_exit fired (got %d)", g_nav_exit_calls);
CHECK(g_swipe_calls == 0, "T3a no-on_swipe -> on_swipe NOT called");
/* 3b 未注册 on_swipe:中部上滑(普通 MEOW_EV_SWIPE UP)→ nav_request_exit 不触发(App 滚动) */
run_scenario(MEOW_EV_SWIPE, MEOW_SWIPE_UP, 120, 0);
CHECK(g_nav_exit_calls == 0, "T3b mid-swipe-up -> nav_request_exit NOT fired (App scroll), got %d", g_nav_exit_calls);
/* 3c 注册 on_swipe:底部热区上滑 → 系统优先,nav_request_exit 触发(回桌面),on_swipe 不被调用 */
run_scenario(MEOW_EV_HOME, MEOW_SWIPE_UP, 120, 1);
CHECK(g_nav_exit_calls == 1, "T3c on_swipe registered -> nav_request_exit STILL fired (system gesture wins), got %d", g_nav_exit_calls);
CHECK(g_swipe_calls == 0, "T3c system-priority home -> on_swipe NOT called");
}
int main(void)
{
meow_ui_opts o = { FBW, FBH };
if (meow_ui_init(&o) != 0) { printf("init failed\n"); return 1; }
test_predicate();
test_touch_classify();
test_dispatch();
meow_ui_shutdown();
printf("home_gesture: %d pass / %d fail\n", g_pass, g_fail);
return g_fail ? 1 : 0;
}