sdk: 事件分发形式化(§6.4)—— 统一命中/捕获/消费/层间隔离/焦点
根治「焦点/事件穿透」一类反复 bug。此前命中/捕获/消费/层间隔离各处 ad-hoc; 现上收为单一仲裁者(meow_ui_input.c),公共 API 只追加、不删改既有签名。 分发模型: - 触摸沿 z 序自顶向下命中(meow_draw_hit_topdown,owner==active+enable 过滤); - 命中即消费;模态层永远先审(meow_ui_modal_begin/end/active/depth); - down 捕获(meow_ui_gesture_begin/owner/end):命中目标捕获手势直到 up,防滑出误触下层; - 模态存在时下层完全收不到事件——hit_topdown 恒返回模态哨兵(背板消费,不透传); - meow_ui_run 在 TOUCH_DOWN 自动 begin、TAP/SWIPE/LONG_PRESS/NOTIF_PULL 自动 end。 焦点模型: - 唯一持有者(meow_ui_focus_acquire/release/owner/tap); - 点非 focus 区域→释放并通知(meow_ui_focus_tap,list 焦点残留根治); - 滚动容器(list/listview)tap_at 命中行自动 acquire,点外由 run 的 focus_tap 释放; - lost 回调(meow_ui_focus_set_lost_cb)通知转移。 迁移(行为修复,正常交互语义不变): - dialog/sheet → meow_ui_modal_begin/end(模态期下层收不到;叠黑由既有整帧快照+卡片仅重绘保证); - list/listview tap → meow_ui_focus_acquire; - 注入/叠加让位(overlay_input_suppressed)与模态层隔离互补,语义不变。 验证:新穿透矩阵 test_meow_ui_dispatch(M1 模态点下层不触发 / M2 弹层叠开两层层隔离 / M3 捕获手势滑出不误触 / M4 list 焦点点外释放)ALL PASS; 全量回归 widgets/ime_fix/pinyin/overlay_suppress/notif_gesture/sdk_fixes/sb_collapse/ p1p2p3_repro/box/anim/scroll/sdk_input_keys 全 PASS;交叉 -Wall -Wextra 0 warning。 meow_ui.a 新 md5:a9fcfb6eeb07ddbdd48039df4f8f18ce(主会话统一重链,本仓未重链 App)
This commit is contained in:
1 parent
c3abc3fee4
commit
54d2791f48
8 files changed
+428
-3
No files matched your search
@@ -58,6 +58,60 @@ void meow_ui_set_long_press_cb(meow_long_press_fn cb); /* 注册/更换回调
|
||||
void meow_ui_set_long_press_ms(int ms); /* 长按阈值(ms);<=0 恢复默认 500 */
|
||||
int meow_ui_long_press_ms(void); /* 当前阈值(默认 500) */
|
||||
|
||||
/* ============================================================ */
|
||||
/* §6.4 事件分发形式化(2026-09-02)—— 统一「命中测试 / 捕获 / 消费 / 层间隔离 / 焦点」
|
||||
*
|
||||
* 背景:此前命中/捕获/消费/层间隔离各处 ad-hoc 补丁(模式层穿透、弹层叠黑、list 焦点残留、
|
||||
* 同坐标二次消费)。本节把三层模型的形式化落地为**单一仲裁者**(SDK 内部实现,见
|
||||
* devdocs/plan/SDK_VIEW_FRAMEWORK_DESIGN.md §A.7 命中分流 ③②① + 本 SDK 内部拓扑):
|
||||
*
|
||||
* 触摸沿 z 序**自顶向下**命中:模态层永远先审;某一层命中即消费(返回 consumed 才继续下探)。
|
||||
* 某一次 touch-down 命中后,捕获直到 up;期间 move/up 只发给捕获目标(防滑出误触发下层)。
|
||||
* 模态层存在时下层**完全收不到**事件——未命中面板的事件由模态背板消费,不透传。
|
||||
*
|
||||
* 兼容:**只追加、不删改既有签名**;未调用本节 API 的 App 行为与之前完全一致(命中/捕获仍
|
||||
* 由 App 在 on_tap/on_touch_* 里自理)。hello/files/ncm/reader 等既有 App 只把 SDK 提供的
|
||||
* 语义用于收敛 bug,不改正常交互。
|
||||
*/
|
||||
/* ---- 模态作用域(modal scope)----
|
||||
* 一组自顶向下优先的叠层。dialog/sheet/App 自绘模态在「打开时 begin、关闭时 end」。
|
||||
* 作用域存在(meow_ui_modal_active / depth>0)时,下层(view/widget)完全收不到触摸;
|
||||
* 未命中面板的事件由背板消费(meow_ui_hit_topdown 恒返回模态哨兵)。支持嵌套(弹层叠开,
|
||||
* depth 递增)。begin 返回作用域句柄;end 销栈(幂等,NULL 忽略)。 */
|
||||
typedef struct meow_ui_modal meow_ui_modal;
|
||||
meow_ui_modal *meow_ui_modal_begin(void); /* 打开模态层入栈;返回句柄(NULL=栈满/上限) */
|
||||
void meow_ui_modal_end(meow_ui_modal *m); /* 关闭:弹到 m(含 m,一次性关上嵌套) */
|
||||
int meow_ui_modal_active(void); /* 当前是否有任一模态作用域打开(depth>0) */
|
||||
int meow_ui_modal_depth(void); /* 模态栈深(弹层叠开计数) */
|
||||
|
||||
/* ---- 自上而下命中 ---- */
|
||||
/* 沿 z 序(模态最高优先,其次注册控件 z 降序;均含 owner==active+enable 过滤)返回第一个
|
||||
* 命中绘制物(meow_widget* 或 meow_view*);无命中返回 NULL。模态存在时恒返回模态哨兵
|
||||
* (背板消费,不透传)。供 gesture_begin/focus_tap/App 自绘模态命中统一使用。 */
|
||||
void *meow_ui_hit_topdown(int x, int y);
|
||||
/* meow_widget_hit 的公共别名(owner==active + enable + 矩形/自定义命中回调一致)。 */
|
||||
int meow_ui_widget_hit(meow_widget *w, int x, int y);
|
||||
|
||||
/* ---- 手势捕获(gesture capture)----
|
||||
* touch-down 命中目标捕获整个手势直到 up。捕获期 meow_ui_gesture_owner 恒返回捕获目标;
|
||||
* 后续 move/up 只发给它(防滑出后误触发下层)。begin 返回捕获目标(未命中=NULL 不捕获);
|
||||
* end/抬手释放。 */
|
||||
void *meow_ui_gesture_begin(int x, int y); /* 命中+捕获;返回捕获目标(模态存在时=模态哨兵) */
|
||||
void *meow_ui_gesture_owner(void); /* 当前手势捕获目标(无=NULL) */
|
||||
void meow_ui_gesture_end(void); /* 手势结束(抬手/TAP/SWIPE 边沿):释放捕获 */
|
||||
|
||||
/* ---- 唯一焦点(focus,root 根治 list 焦点残留 / 滚动容器间转移)----
|
||||
* 焦点持有者唯一。点非焦点区域 → 释放焦点并触发 lost 回调;滚动容器(list/scroll)在
|
||||
* 获得焦点时 acquire,点外由 meow_ui_focus_tap 统一释放——「命中非 focus 区域 → 释放并通知」。
|
||||
* 转移规则:某滚动容器 acquire 后,随后的纵向 swipe / 拖动滚该容器;任何落在该容器外的
|
||||
* 触摸(hit != focus owner)释放焦点,回退到页面级滚动。 */
|
||||
typedef void (*meow_ui_focus_lost_fn)(void *owner, void *ctx); /* 焦点被释放/转移时回调 */
|
||||
void meow_ui_focus_set_lost_cb(meow_ui_focus_lost_fn cb, void *ctx); /* 注册/更换焦点丢失回调 */
|
||||
void *meow_ui_focus_owner(void); /* 当前唯一焦点持有者(无=NULL) */
|
||||
int meow_ui_focus_acquire(void *owner); /* 设为唯一焦点(覆盖旧焦点并触发其 lost) */
|
||||
int meow_ui_focus_release(void *owner); /* owner==当前焦点才释放+通知(NULL=任意) */
|
||||
void meow_ui_focus_tap(int x, int y); /* TAP 落点:命中焦点持有者→保位;否则释放+通知 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in new issue
Block a user