mcpField
H
handle-input

handle-input

github.com/even-realities开发79135 次安装1 周前更新
代码仓库

关于 handle-input

为 Even Hub G2 应用开发者提供输入、手势和生命周期事件处理指南,涵盖容器事件路由、零值省略及退出清理。

主要功能

  1. 01说明触控手势的事件路由
  2. 02列出系统与生命周期事件
  3. 03解释 Protobuf 零值省略
  4. 04提供事件处理与退出模式

适用场景

  1. 01排查文本容器点击事件
  2. 02处理列表选择和滚动
  3. 03实现应用退出与资源清理

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/even-realities/everything-evenhub --skill handle-input

安装后在 Claude Code 中输入/handle-input确认已加载。

详细介绍

处理输入

Even Hub G2 应用中处理用户输入、手势和生命周期事件的指南。

输入来源

来源手势备注
G2 触摸板(镜腿)按下、双击、向上滑动、向下滑动主要输入方式
R1 触摸板(戒指)按下、双击、向上滑动、向下滑动可选配件,手势集相同
IMU(加速度计/陀螺仪)头部方向、运动数据参见 device-features 技能

事件路由规则

事件的路由方式取决于当前激活的容器类型(即 isEventCapture: 1 的容器)。每个页面只能有一个容器捕获事件。

文本容器处于激活状态
手势事件字段eventType
向上滑动event.textEvent1 (SCROLL_TOP_EVENT)
向下滑动event.textEvent2 (SCROLL_BOTTOM_EVENT)
单击event.sysEventundefined / 0
双击event.sysEvent3 (DOUBLE_CLICK_EVENT)

要点:文本容器上的单击和双击会作为 sysEvent 触发,而非 textEvent。只有滚动手势会作为 textEvent 触发。

列表容器处于激活状态
手势事件字段详情
向上/向下滑动(内部处理)SDK 在内部滚动列表,不会触发事件
单击event.listEvent.currentSelectItemIndex = 所选项目的索引
双击event.sysEvent.eventType = 3
系统事件(始终可用)
手势事件字段eventType
进入前台event.sysEvent4 (FOREGROUND_ENTER_EVENT)
退出前台event.sysEvent5 (FOREGROUND_EXIT_EVENT)
异常退出event.sysEvent6 (ABNORMAL_EXIT_EVENT)
系统退出event.sysEvent7 (SYSTEM_EXIT_EVENT)

OsEventTypeList 枚举值

值名称描述
0CLICK_EVENT单击(G2 或 R1)
1SCROLL_TOP_EVENT向上滑动
2SCROLL_BOTTOM_EVENT向下滑动
3DOUBLE_CLICK_EVENT双击(G2 或 R1)
4FOREGROUND_ENTER_EVENT应用进入前台
5FOREGROUND_EXIT_EVENT应用进入后台
6ABNORMAL_EXIT_EVENT意外断开连接
7SYSTEM_EXIT_EVENT系统级退出(例如,用户确认退出对话框)
8IMU_DATA_REPORTIMU 数据样本

事件模型

interface Text_ItemEvent {
  containerID?: number
  containerName?: string
  eventType?: number  // 1 = scroll up, 2 = scroll down
}

interface List_ItemEvent {
  containerID?: number
  containerName?: string
  currentSelectItemName?: string
  currentSelectItemIndex?: number  // 0-based; undefined when 0 (protobuf)
  eventType?: number
}

interface Sys_ItemEvent {
  eventType?: number    // undefined/0 = single click, 3 = double click
  eventSource?: EventSourceType  // 0=null, 1=glasses right, 2=ring, 3=glasses left
  imuData?: IMU_Report_Data
  systemExitReasonCode?: number
}

Protobuf 零值省略

SDK 在底层使用 protobuf。任何值为零/默认值(0、false、空字符串)的字段都会是 undefined,而非零值。这会影响:

  • sysEvent.eventType — 单击的值为 0,但接收到时是 undefined
  • listEvent.currentSelectItemIndex — 第一项的索引为 0,但接收到时是 undefined
  • 任何其他值为 0 的数值字段

始终使用空值合并运算符:event.sysEvent.eventType ?? 0、event.listEvent.currentSelectItemIndex ?? 0。

完整事件处理模板

import { waitForEvenAppBridge } from '@evenrealities/even_hub_sdk'

const bridge = await waitForEvenAppBridge()

const unsubscribe = bridge.onEvenHubEvent(event => {
  if (event.listEvent) {
    // List item selected (single press on list container)
    const idx = event.listEvent.currentSelectItemIndex ?? 0
    console.log('Selected index:', idx)
    return
  }

  if (event.textEvent) {
    // Scroll on text container (NOT clicks — those come via sysEvent)
    const type = event.textEvent.eventType ?? 0
    if (type === 1) {
      // Swipe up / scroll up
    } else if (type === 2) {
      // Swipe down / scroll down
    }
    return
  }

  if (event.sysEvent) {
    const type = event.sysEvent.eventType ?? 0
    if (type === 0) {
      // Single press (on text container, or system-level)
    } else if (type === 3) {
      // Double press
    } else if (type === 4) {
      // App resumed (foreground enter)
    } else if (type === 5) {
      // App backgrounded (foreground exit)
    }
    return
  }
})

// Always clean up on teardown
// unsubscribe()

G2 与 R1 的区别

G2(镜腿触摸板)和 R1(戒指触摸板)使用相同的手势集。要区分两者,请检查 Sys_ItemEvent 中的 eventSource。EventSourceType 的值会指明输入来自左臂、右臂还是戒指配件。

退出机制

每个应用都应提供通过眼镜/戒指交互退出的方式。请使用 SDK 内置的系统退出对话框,而不要自行构建确认界面。

标准模式——双击以显示系统退出对话框:

if (eventType === 3) { // DOUBLE_CLICK_EVENT
  // Show the system exit dialog. Don't clean up resources here —
  // the user can still cancel. If they confirm, the SDK fires
  // SYSTEM_EXIT_EVENT (7) and you clean up in that handler.
  bridge.shutDownPageContainer(1)
  return
}

shutDownPageContainer 模式:

  • shutDownPageContainer(0) — 立即退出,不进行确认
  • shutDownPageContainer(1) — 系统退出确认对话框(推荐)

在调用 shutDownPageContainer(1) 之前,不要调用 unsubscribe()、停止硬件或刷新状态。如果这样做后用户点按取消,应用仍会显示在屏幕上,但不再监听事件。请在 ABNORMAL_EXIT_EVENT / SYSTEM_EXIT_EVENT 处理程序中进行清理。

生命周期事件

为应用正确处理全部四种生命周期事件:

事件使用场景
FOREGROUND_ENTER_EVENT (4)重新渲染当前状态,恢复计时器/IMU
FOREGROUND_EXIT_EVENT (5)将待处理状态写入 setLocalStorage,暂停计时器
ABNORMAL_EXIT_EVENT (6)停止硬件(imuControl(false)、audioControl(false)),取消订阅,写入状态
SYSTEM_EXIT_EVENT (7)执行与 ABNORMAL_EXIT 相同的清理操作——用户已在系统对话框中确认退出

重要说明

  • 点击文本容器会触发 sysEvent,而不是 textEvent。只有滚动手势才会触发 textEvent。这是事件处理错误最常见的来源。
  • 清理:bridge.onEvenHubEvent() 会返回一个取消订阅函数。组件销毁时务必调用。
  • 每个页面只允许一个事件监听器:只有设置了 isEventCapture: 1 的容器才会接收输入事件。如果多个容器都设置了 isEventCapture: 1,SDK 会因验证错误而拒绝该页面。

任务

$ARGUMENTS

评论

支持 Markdown