v0.1首个版本化设计基线查看版本范围
Developer

input

input 把用户对本应用绘图面的直接操作变成有界、类型化事件。它不暴露 DOM Event、浏览器全局监听器、原始设备对象或跨应用输入。

基本示例

下面在按下指针时记录逻辑坐标:

await host.input.focus('main');

host.events.on('input.pointer', (event) => {
  if (event.canvasId !== 'main' || event.kind !== 'down') return;
  beginStroke(event.pointerId, event.x, event.y, event.pressure);
});

适用场景

  • 游戏、画板、图表和自绘控件的指针交互。
  • 键盘快捷键和非文本按键。
  • 鼠标、触控板或等价设备产生的滚轮/平移增量。
  • 在多个应用绘图面之间请求焦点。

文本输入、输入法合成、候选词和字符边界查询使用 ime,不能只靠 input.key 重建。

能力声明

{
  "capabilities": ["host:input.focus"]
}

指针、键盘和滚轮事件只有在应用拥有对应绘图面且获得焦点时才送达。宿主能力表仍应明确公布事件名和 schema。

Reference

方法

  • input.focus():请求把输入焦点交给本应用绘图面。

事件

  • input.pointer:指针进入、移动、按下、抬起、取消和离开。
  • input.key:按键按下或抬起;用于控制键和快捷键。
  • input.wheel:二维滚动增量。

事件数据

PointerEvent {
  canvasId,
  kind: "enter" | "move" | "down" | "up" | "cancel" | "leave",
  pointerId: u32,
  pointerType: "mouse" | "touch" | "pen" | "unknown",
  x: f32, y: f32,
  buttons: u16,
  pressure?: f32,
  modifiers: ModifierSet
}

KeyEvent {
  canvasId,
  kind: "down" | "up",
  key: bounded-string,
  code: bounded-string,
  repeat: boolean,
  modifiers: ModifierSet
}

坐标使用绘图面的逻辑像素,不是屏幕坐标。pointerId 只在当前指针活动期内有意义,不能作为设备标识。

原生 WASM 示例

原生 guest 从统一事件队列读取类型化事件:

HostEvent event;
while (host_event_next(&event)) {
  if (event.type == INPUT_POINTER && event.pointer.kind == POINTER_DOWN) {
    begin_stroke(event.pointer.pointer_id, event.pointer.x, event.pointer.y);
  }
}

事件队列满时宿主可以合并连续 movewheel,但不能静默丢弃 downupcancel 或焦点变化。

生命周期与焦点

  • 事件仅在对应应用视图存活时送达。
  • 绘图面失焦时,宿主必须为仍按下的指针发送 cancel,并终止未完成的按键状态。
  • focus 是请求,不允许从后台窃取系统焦点;宿主可以返回 denied
  • 页面隐藏、系统手势或可信 UI 覆盖时暂停输入。

安全与预算

  • 信任档位:green;provenance 为 app-context
  • 不返回屏幕绝对坐标、设备序列号、全局按键状态或其他应用输入。
  • 字符串、坐标、压力和修饰键必须经过 schema 限制。
  • 高频移动事件按绘图面合并并设时间窗预算。
  • 宿主不得把密码管理器、系统快捷键或保留组合键泄露给 guest。

不属于本 API

手柄、传感器、全局热键、无障碍语义树和拖放文件都不是 v0.1 input。它们有不同资源、权限或生命周期,需要独立准入。

一致性测试

至少覆盖多指针、失焦取消、坐标缩放、事件合并、按键 repeat、保留快捷键、绘图面销毁、后台暂停,以及 JS/原生 guest 事件次序一致性。

Host API 版本与分层概览Host API v0.1版本非正式提议提议canvas API呈现canvas.getInfo()方法canvas.draw()方法canvas.present()方法canvas.measureText()方法canvas.frame event事件canvas.resize event事件asset API呈现asset.read()方法asset.loadFont()方法playback API呈现playback.open()方法playback.write()方法playback.stop()方法playback.ready event事件playback.ended event事件input API输入input.focus()方法input.pointer event事件input.key event事件input.wheel event事件ime API输入ime.openSession()方法ime.updateState()方法ime.updateGeometry()方法ime.closeSession()方法ime.textUpdate event事件ime.composition event事件ime.formatUpdate event事件ime.characterBoundsRequest event事件capture API输入capture.requestCamera()方法capture.requestMic()方法capture.frame()方法capture.readAudio()方法capture.stop()方法capture.ended event事件store API数据store.get()方法store.put()方法store.delete()方法store.list()方法store.deletePrefix()方法clipboard API数据clipboard.readText()方法clipboard.writeText()方法clipboard.readImage()方法clipboard.writeImage()方法net API网络net.fetch()方法identity API身份identity.status()方法identity.login()方法identity.logout()方法env API平台集成env.snapshot()方法env.change event事件print API平台集成print.open()方法开始调用 Host API指南构建交互式绘图应用指南构建自绘文本编辑器指南管理媒体采集与播放指南组织本地数据与同步指南