滚动协议¶
在 0.50.0 版本加入.
鼠标协议将滚动报告为虚拟滚轮按钮的按压,每行一次;程序看到的触控板像不连贯的滚轮,也不知道手势何时开始、结束或进入惯性滚动。滚动协议是开放终端扩展,按系统提供的方式报告滚动:以像素为单位的距离、产生事件的设备和手势阶段。封装与 数位板指针协议 相同,目标也一致:小巧、低干扰、易于实现,不改变 TTY 的本质。
消息封装¶
帧使用带有 scroll 选择器的 OSC 777::
<OSC> 777 ; scroll ; v=1 : op=query : id=7 <ST>
帧遵循 OSC 777 扩展封装 规定的 OSC 777 共用规则:字段语法、拒绝哪些帧、单位和时钟。协议版本 v 为 1,op 为 query、cap、mode 或 event。
能力探测¶
程序询问终端是否支持本协议::
<OSC> 777 ; scroll ; v=1 : op=query : id=7 <ST>
id 是程序自行选择的非负 31 位整数,回复原样返回。支持协议的终端回答::
<OSC> 777 ; scroll ; v=1 : op=cap : id=7 : caps=1 : mode=0 <ST>
caps 为位集合,目前只定义 1,表示终端报告像素距离。mode 为下述模式的当前状态。不支持本协议的终端会忽略查询,因此程序必须设置超时,并回退到鼠标报告。查询不改变模式。
模式¶
报告默认关闭,按终端窗口开启::
<OSC> 777 ; scroll ; v=1 : op=mode : mode=1 <ST>
用 mode=0 关闭。开启时,窗口中的滚动由本协议报告,不再作为滚轮按钮按压;点击和移动仍使用程序请求的鼠标报告方式。终端也不滚动自己的回滚缓冲区,滚动由程序控制。模式仅作用于当前窗口,并由 RIS 重置。程序必须在退出、挂起或失败时关闭,恢复时重新开启。多路复用器与其他终端状态一起保存它。终端可允许用户针对全部或部分程序拒绝该模式;被拒绝时读回为关闭,不报告滚动,因此程序应读回状态,不要假定已获准。
不带 mode 字段的 mode 请求读取状态而不修改,回复为::
<OSC> 777 ; scroll ; v=1 : op=mode : mode=1 <ST>
程序重连后恢复时,应读回模式,确认是否仍然有效,而非假定状态保留。
报告¶
每个滚动事件一帧::
<OSC> 777 ; scroll ; v=1 : op=event : t=408211 : tu=73 : dx=0 : dy=250 : x=8448 : y=3072 : mods=1 : src=1 : phase=2 <ST>
除 tu 外,所有字段均为必需:
|
系统认定滚动发生的时刻,以终端全部扩展共用时钟的毫秒表示,见 OSC 777 扩展封装。终端自行生成的报告(例如自身惯性滚动)使用生成报告的时刻 |
|
|
|
视图应移动的距离,以物理像素的百分之一为单位,有符号,向右和向下为正。触控板使用系统测得的距离;有刻度的滚轮将滚动行数按终端字符单元尺寸和滚动倍率转换,因此程序对两者使用相同单位 |
|
指针位置,以物理像素的 1/256 为单位,有符号、从零开始,相对于字符单元区域的左上角 |
|
Shift |
|
|
|
|
报告中的距离可以为零,尤其是阶段 1、3、4 和 6。自行实现惯性动画的程序应在阶段 4 停止自身动画,因为终端已经开始报告系统的惯性滚动。滚轮仅报告阶段 0。
无法跟上程序处理速度的终端或中继,只能将同一设备、同一阶段的连续报告合并:距离求和,其他字段使用最后一条报告的值,包括 t 和 tu。阶段变化绝不合并或丢弃,见 OSC 777 扩展封装。
多路复用器按窗格原点(含边框)转换 x,y,其余字段原样转发,并将报告交给指针下方的窗格。
silkie 实现说明¶
silkie 报告窗口系统提供的信息:
macOS:使用 AppKit 触控板事件的像素距离和上述全部阶段。距离与
x,y一样以物理像素表示,因此 Retina 显示器上为系统自身单位值的两倍。AppKit 事件带微秒时间戳,因此仅 macOS 发送tu;Wayland 和 X11 的时间戳为整毫秒。Wayland:从
wl_pointer轴事件取得像素距离。版本 5 及以上的 seat 通过轴来源和手指抬起时合成器发送的轴停止事件,提供手指阶段1至3。惯性阶段4至6来自终端自己的惯性滚动器,因此阶段4紧跟阶段3。惯性滚动被打断(例如手指重新落下),或手指仍在滚动时指针离开窗口,会发送阶段7。X11:可用时从 XInput 2 平滑滚动取得像素距离;否则将行数转换为像素,并设置
src=0。惯性阶段4至7由终端自身的惯性滚动器提供。X 服务器不报告手指何时抬起,滚动器只能根据停顿推测,因此不报告手指阶段1至3。