feat(sdk): 通用长按事件 (agent-191, 用户定案) — MEOW_EV_LONG_PRESS 坐标式事件+meow_ui_set_long_press_cb/ms(opt-in,默认500ms,移动>12px取消,长按后抬手抑制TAP/SWIPE); 按钮按住视觉阈值同源; files 长按从App层迁入 SDK
meow_ui.a 4335c33a→6de89c27; hello→72fb20da; files→b1c4f58f 宿主 widgets(含6条长按断言)/p1p2p3/ime_fix/test_fsx 全 PASS; 未改 meow_ui_events 结构(防 -Wmissing-field-initializers 破坏既有App)
This commit is contained in:
1 parent
60072a08f1
commit
e95552b949
14 files changed
+200
-35
No files matched your search
@@ -35,6 +35,8 @@
|
||||
|
||||
#define SWIPE_THRESH 65 /* px:抬起位移超过视为滑动(GESTURE_BACK: 90→65,用户实测 90 偏多,65 更顺手) */
|
||||
#define EDGE_W 24 /* 左滑返回的「左缘起点」宽度(t_dx < EDGE_W 才认返回手势) */
|
||||
#define MEOW_LONG_PRESS_MS 500u /* §6.3 通用长按默认阈值(ms;meow_ui_set_long_press_ms 可配) */
|
||||
#define MEOW_LONG_PRESS_SLOP 12 /* §6.3 按下后「仍算按住」的最大位移(px);超此取消长按 */
|
||||
#define QUEUE_N 128
|
||||
#define MAX_DEVS 8
|
||||
#define MEOW_APP_ACTIVITY_FILE "/tmp/meow_app_activity" /* M2.71-bug5:App 活动→launcher 重置息屏计时 */
|
||||
@@ -129,6 +131,13 @@ static int t_origin_valid = 0; /* 原点是否已锁定 */
|
||||
static uint64_t t_down_ms = 0; /* 按下时刻(monotonic ms),供实时按住时长用 */
|
||||
/* M2.71-bug2/6:拖动过程事件上次上报坐标(坐标变化才入队 MEOW_EV_TOUCH_MOVE,防刷屏)。 */
|
||||
static int t_mv_x = -1, t_mv_y = -1;
|
||||
/* §6.3 通用长按:本次按压是否已触发过长按(触发后抬手不再产生 TAP/SWIPE)。 */
|
||||
static int t_long_fired = 0;
|
||||
|
||||
/* §6.3 通用长按:阈值(默认 MEOW_LONG_PRESS_MS;App 可经 meow_ui_set_long_press_ms 配)。 */
|
||||
static int g_long_press_ms = MEOW_LONG_PRESS_MS;
|
||||
/* §6.3 注册的长按回调(NULL=未注册;触发时以 (x,y) 调用,坐标=触发时刻按下点)。 */
|
||||
static meow_long_press_fn g_long_press_cb = NULL;
|
||||
|
||||
/* 按下边沿:只标记按下,绝不用传入坐标立即锁原点(避免用上一手势残留坐标当原点)。
|
||||
* t_cx/t_cy 归 -1 —— 本次手势以「无坐标」起步,只接受随后到来的有效 ABS。 */
|
||||
@@ -142,6 +151,7 @@ static void touch_press(int x, int y)
|
||||
t_dx = 0; t_dy = 0;
|
||||
t_down_ms = now_ms(); /* 记按下时刻:供实时按住时长/按住视觉 */
|
||||
t_mv_x = -1; t_mv_y = -1; /* M2.71:拖动过程起点未定 */
|
||||
t_long_fired = 0; /* §6.3:每次新按压复位长按触发标记 */
|
||||
}
|
||||
/* 由 ABS_X/ABS_Y 驱动:若本次按下且原点未锁且坐标有效 → 锁原点;再更新当前坐标。
|
||||
* M2.71-bug2/6:原点锁定即报 MEOW_EV_TOUCH_DOWN(拖动起点);随后坐标变化报 MEOW_EV_TOUCH_MOVE
|
||||
@@ -165,11 +175,18 @@ static void touch_release(void)
|
||||
{
|
||||
if (!t_down) return;
|
||||
t_down = 0; t_press_valid = 0;
|
||||
int was_long = t_long_fired; /* §6.3:本次按压是否已触发过长按(抬手不再产生点击/滑动) */
|
||||
t_long_fired = 0;
|
||||
/* 本次按下从未锁到有效坐标(幽灵触摸/坐标未就绪):丢弃,且清空全部轨迹。 */
|
||||
if (!t_origin_valid) { t_cx = t_cy = -1; t_dx = t_dy = 0; t_down_ms = 0; t_mv_x = t_mv_y = -1; return; }
|
||||
t_origin_valid = 0;
|
||||
int mdx = t_cx - t_dx, mdy = t_cy - t_dy;
|
||||
int adx = mdx < 0 ? -mdx : mdx, ady = mdy < 0 ? -mdy : mdy;
|
||||
/* 长按已触发:本次手势由长按消费,抬手不再产生 TAP/SWIPE/NOTIF_PULL(抑制点击,§6.3)。 */
|
||||
if (was_long) {
|
||||
t_cx = t_cy = -1; t_dx = t_dy = 0; t_down_ms = 0; t_mv_x = t_mv_y = -1;
|
||||
return;
|
||||
}
|
||||
/* 手势判定只在「抬手(release)边沿」做:按下/移动过程不触发 SWIPE,仅报 PROGRESS。
|
||||
*
|
||||
* 返回手势("左滑"语义):原点确实在左缘 + 向右移动 ≥SWIPE_THRESH。设备实际为
|
||||
@@ -227,17 +244,52 @@ unsigned int meow_input_touch_hold_ms(void)
|
||||
void meow_input_touch_set(int down, int x, int y, unsigned hold_ms)
|
||||
{
|
||||
if (down) {
|
||||
t_down = 1; t_press_valid = 1; t_origin_valid = 1;
|
||||
t_down = 1; t_press_valid = 1; t_origin_valid = 1; t_long_fired = 0;
|
||||
t_cx = x; t_cy = y; t_dx = x; t_dy = y;
|
||||
uint64_t now = now_ms();
|
||||
t_down_ms = (now > (uint64_t)hold_ms) ? (now - (uint64_t)hold_ms) : 0;
|
||||
} else {
|
||||
t_down = 0; t_press_valid = 0; t_origin_valid = 0;
|
||||
t_down = 0; t_press_valid = 0; t_origin_valid = 0; t_long_fired = 0;
|
||||
t_cx = -1; t_cy = -1; t_dx = 0; t_dy = 0; t_down_ms = 0;
|
||||
t_mv_x = -1; t_mv_y = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 宿主单测/内部注入:模拟按下后移动到 (x,y)(保原点、更新当前坐标;位移超长按容忍即取消)。
|
||||
* 对应输入线程 touch_update 的位移分支(这里不产生语义事件,仅更新坐标状态)。 */
|
||||
void meow_input_touch_move(int x, int y)
|
||||
{
|
||||
if (!t_down || !t_origin_valid) return;
|
||||
t_cx = x; t_cy = y;
|
||||
t_mv_x = x; t_mv_y = y;
|
||||
}
|
||||
|
||||
/* 宿主单测/内部注入:模拟一次抬手(真实 touch_release;含长按后抑制 TAP/SWIPE)。 */
|
||||
void meow_input_touch_release(void) { touch_release(); }
|
||||
|
||||
/* ---- §6.3 通用长按公共 API + 阈值跨越检测 ----
|
||||
* meow_input_long_press_poll:主循环(meow_ui_run 每帧)与宿主单测调用。读触摸状态机:
|
||||
* 按下、原点/坐标已就绪、未触发过长按、位移 ≤ 容忍、按住时长 ≥ 阈值 → 置 t_long_fired,
|
||||
* 入队 MEOW_EV_LONG_PRESS(a=x,b=y=当前按下点),返回 1;否则返回 0。幂等(一次按压一次)。 */
|
||||
void meow_ui_set_long_press_cb(meow_long_press_fn cb) { g_long_press_cb = cb; }
|
||||
void meow_ui_set_long_press_ms(int ms)
|
||||
{ g_long_press_ms = (ms > 0) ? ms : (int)MEOW_LONG_PRESS_MS; }
|
||||
int meow_ui_long_press_ms(void) { return g_long_press_ms; }
|
||||
|
||||
int meow_input_long_press_poll(void)
|
||||
{
|
||||
if (!g_long_press_cb) return 0; /* 未注册回调:长按整体关闭,保持旧点击语义(短按/长按都 TAP) */
|
||||
if (!t_down || t_long_fired || !t_origin_valid || t_cx < 0 || t_cy < 0) return 0;
|
||||
int mdx = t_cx - t_dx, mdy = t_cy - t_dy;
|
||||
int amx = mdx < 0 ? -mdx : mdx, amy = mdy < 0 ? -mdy : mdy;
|
||||
int move = amx > amy ? amx : amy;
|
||||
if (move > MEOW_LONG_PRESS_SLOP) return 0; /* 位移超容忍:取消 */
|
||||
if (meow_input_touch_hold_ms() < (unsigned)g_long_press_ms) return 0; /* 未达阈值 */
|
||||
t_long_fired = 1;
|
||||
push_ev(MEOW_EV_LONG_PRESS, t_cx, t_cy);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* ---- 输入线程:poll 所有 event 设备 + 解析 ---- */
|
||||
static void *input_thread(void *arg)
|
||||
{
|
||||
@@ -338,8 +390,12 @@ void meow_ui_run(const meow_ui_events *ev)
|
||||
|
||||
while (!g_exit) {
|
||||
/* agent-119:实时触摸按压/按住/释放 → 即时重绘命中按钮区(不等 app 重绘)。
|
||||
* IME 打开时软键盘为覆盖层且拦截触摸,不驱动背后按钮视觉,跳过。 */
|
||||
if (!meow_ime_active()) meow_widget_touch_refresh();
|
||||
* IME 打开时软键盘为覆盖层且拦截触摸,不驱动背后按钮视觉,跳过。
|
||||
* §6.3 通用长按:每帧检测「按下 ≥ 阈值且位移 ≤ 容忍」跨越(IME 打开不驱动;启动窗口不触发)。 */
|
||||
if (!meow_ime_active()) {
|
||||
meow_widget_touch_refresh();
|
||||
if (now_ms() >= startup_cooldown_until) meow_input_long_press_poll();
|
||||
}
|
||||
|
||||
meow_input_ev e;
|
||||
int got = 0;
|
||||
@@ -407,6 +463,12 @@ void meow_ui_run(const meow_ui_events *ev)
|
||||
if (g_events_set && g_events.on_swipe_progress)
|
||||
g_events.on_swipe_progress(x0, dx);
|
||||
meow_ui_flush_region(0, meow_ui_statusbar_height(), meow_ui_width(), 6);
|
||||
} else if (e.type == MEOW_EV_LONG_PRESS) {
|
||||
/* §6.3 通用长按:按下 ≥ 阈值未抬手触发。坐标=触发时刻按下点(App 用
|
||||
* meow_widget_hit/meow_listview_hit 判定命中控件/行)。已注册回调则分发;
|
||||
* 其抬手已被 touch_release 抑制(不再产生 TAP/SWIPE),此处无需吞后续 tap。 */
|
||||
if (in_startup) continue;
|
||||
if (g_long_press_cb) g_long_press_cb(e.a, e.b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user