显示信息协议¶
在 0.50.0 版本加入.
绘图程序通常不了解输出最终到达的屏幕:彩色 LCD 还是十六级灰度电子墨水屏、覆盖多少色域、亮度有多高、每个字符单元有多少物理像素、以什么频率刷新。这些都会影响最佳渲染方式,从调色板和抖动策略,到是否值得运行动画。显示信息协议让程序查询这些信息,并在答案变化时收到通知,例如窗口被移到另一块屏幕。它与其他 kitty 协议一样,是小巧、低干扰、易于实现的开放终端扩展,不改变 TTY 的本质。
消息封装¶
帧使用带有 display 选择器的 OSC 777::
<OSC> 777 ; display ; v=1 : op=query : id=42 <ST>
帧遵循 OSC 777 扩展封装 规定的 OSC 777 共用规则:字段语法、拒绝哪些帧、单位和时钟。终端报告中的值为单词,或可带小数、不带前导 + 的十进制数,例如 headroom=1.5。协议版本 v 为 1,op 为 query、cap、mode 或 event。
查询¶
程序查询窗口所在的显示器::
<OSC> 777 ; display ; v=1 : op=query : id=42 <ST>
id 是程序自行选择的非负 31 位整数,回复原样返回,以便匹配查询。支持协议的终端回答::
<OSC> 777 ; display ; v=1 : op=cap : id=42 : mode=0 : kind=lcd : color=rgb : bits=8 : gamut=p3 : headroom=1 : scale=2 : period=8333 : ppi=254 <ST>
不支持本协议的终端会忽略查询,因此程序必须设置超时,并回退为假定普通彩色显示器。
回复字段如下:
mode下述模式的当前状态,
0或1。kindlcd、oled、eink或unknown。电子墨水屏更新较慢且会残影,因此程序应避免动画和平滑滚动,采用低频、大步幅重绘。colorrgb、gray或mono。bits每个颜色通道的位数,未知时为
0。十六级灰度表示为color=gray : bits=4。该字段与color一起供程序选择调色板,并决定是否以及如何抖动;少量灰度级也可进行良好的抗锯齿,此字段不决定抗锯齿策略。gamutsrgb、p3、rec2020或unknown,表示显示器覆盖的最宽色彩空间。headroom终端可显示亮度相对于普通文本白色的倍数;没有额外亮度时为
1。使用方式见 HDR 亮度协议。scale系统要求应用使用的帧缓冲区缩放比例:一个系统逻辑单位需要多少物理像素。多数高密度显示器为
2,其他显示器常用1.25或1.5等小数。未知时为0。用途见 像素。period显示器刷新周期,单位微秒,未知时为
0。ppi每英寸的物理像素数:程序绘制的多少像素对应屏幕上一英寸,供程序按真实尺寸绘制。未知时为
0。
终端无法确定的值为 unknown 或 0,绝不猜测。例如未连接客户端的多路复用器,若不了解显示器,所有字段均回答未知,程序的处境不会比查询前更差。
像素¶
本协议及终端所有以像素度量的协议(窗口和字符单元尺寸、图像尺寸和放置、指针/笔/手指位置、滚动距离)均使用物理像素,即终端绘制的帧缓冲区中的一个像素。不使用系统逻辑单位(每个逻辑单位对应 scale 个像素),终端也不会拉伸程序绘制的内容来弥补差异。因此,程序绘制的一像素宽直线就是一像素,而非扩散到多个像素的模糊斑块,程序能使用显示器提供的每一个像素。
scale 表示系统希望应用采用的尺寸,使内容看起来符合用户选择的大小。程序用它决定绘制多大,例如将一个逻辑单位粗的标尺绘制为 scale 像素;不要用它换算已经以物理像素表示的位置或尺寸。ppi 则把这些像素与屏幕的实际尺寸联系起来。
模式¶
程序可按终端窗口开启变化通知::
<OSC> 777 ; display ; v=1 : op=mode : mode=1 <ST>
用 mode=0 关闭。模式仅作用于当前窗口,并由 RIS 重置。程序必须在退出、挂起或失败时关闭,恢复时重新开启。多路复用器与其他终端状态一起保存它,并在脱离连接时关闭。终端可允许用户针对全部或部分程序拒绝模式;被拒绝时读回为关闭,不产生任何报告,因此程序应读回状态,而不是假定已获准。
不带 mode 字段的 mode 请求读取状态而不修改,回复为::
<OSC> 777 ; display ; v=1 : op=mode : mode=1 <ST>
程序重连后恢复时,应读回模式,确认是否仍然有效,而非假定状态保留。
事件¶
开启模式会先发送一次包含当前值的事件,无需单独查询。此后,只要模式开启,任何字段变化都会产生一条事件:窗口移到缩放比例或刷新率不同的显示器、显示亮度设置改变了亮度余量,或切换了色彩配置文件::
<OSC> 777 ; display ; v=1 : op=event : t=408211 : kind=lcd : color=rgb : bits=8 : gamut=srgb : headroom=1 : scale=1 : period=16666 : ppi=96 <ST>
字段与 cap 回复相同,但不含 id 和 mode,并带有 t,表示终端获知变化的时刻,以全部扩展共用时钟上的毫秒表示,见 OSC 777 扩展封装。变化相对于上次事件计算,因此关闭再开启模式会报告一次当前值,此后仅报告变化。变化可能稍后才报告,程序关闭模式后仍可能收到已经在途的事件。终端和中继绝不合并或丢弃事件。
中继与多路复用器¶
类似 mosh 客户端、将终端画面绘制到自己显示器的中继,应使用自身显示器回答查询,因为远端终端无法得知这些信息。中继重连到不同客户端时,会向每个开启模式的窗口发送一次事件,使原本按手机布局的程序能改为桌面布局,反之亦然。
多路复用器根据所连接客户端的显示器回答;脱离连接时所有字段为未知,连接到不同显示器的客户端时发送事件。
配置¶
操作系统能报告多数属性,但并非全部;例如没有信息直接告诉终端它位于电子墨水屏上。在 Silkie 中,eink_mode 声明电子纸显示器,并在未明确选择浅色或深色配色时启用白底黑字。它优先于检测到的显示器类型和 display_info kind=...。运行时用 set_eink_mode 切换会立即通知显示信息订阅者。display_info 可声明操作系统无法提供的个别属性,并覆盖检测;仅设置 display_info kind=eink 会改变报告而不改变颜色。两种设置都不猜测电子纸是灰度还是彩色。目前 Silkie 仅在 macOS 上报告 kind,在 macOS 及实现色彩管理协议的 Wayland 合成器上报告 gamut。后者由合成器提供显示器基色,gamut 选择显示器在 CIE 1931 色度图上覆盖面积至少十分之九的最宽色域;两种较宽色域均未达到时为 srgb。headroom 是 HDR 亮度协议 的亮度余量,已应用 hdr_max_headroom 上限;除非启用 hdr 且窗口实际显示 HDR,否则为 1。macOS 和 Wayland 何时可使用 HDR 见该页。
scale 是窗口系统提供给窗口的比例:macOS 的 backing scale factor、Wayland 表面的首选比例(合成器支持时可为小数),以及 X11 从 Xft.dpi 取得的桌面比例。在 X11 和能声明小数比例的 Wayland 合成器上,Silkie 绘制的像素对应面板像素。在 macOS 上,它们是系统为显示器保存的帧缓冲区像素,默认分辨率下对应面板原生像素。选择缩放分辨率(显示设置中的“更多空间”及相邻选项)时,系统会将帧缓冲区重采样到面板,类似 Wayland 合成器对只能提供整数缩放比例的窗口所做的处理。这时 Silkie 的像素不再严格对应面板像素,任何应用都无法避免;macOS 上的 ppi 统计的是 Silkie 绘制的像素。
不提供物理尺寸的显示器(例如远程会话或虚拟机中的虚拟显示器),其 ppi 为 0。窗口系统可能假定每英寸 96 或 72 像素,但这是猜测,不会转发给程序。