跳到主要内容
ansicode

DEC 定位器套件 —— DECELR / DECEFR / DECSLE / DECRQLP(鼠标 / 定位器事件)

DEC 原版指点设备协议(比 xterm SGR 鼠标模式早十年)。四个序列分别 启用 / 过滤 / 选择 / 查询定位器事件;现代交互式 UI 改用 SGR 鼠标模式(?1000 + ?1006)。

字节形式

涵盖所有常见的字符串字面量写法,方便正反查找。

\\x1b[\x1b[<Pn>;<Pu>'z \x1b[<Pm>'{ \x1b[<Pt>;<Pl>;<Pb>;<Pr>'w \x1b[<Ps>'|
\\033[\033[1;2'z
\\e[\e[1;2'z
ESC [ESC [ ... ' z / ' { / ' w / ' |
hex1b 5b ... 27 7a / 7b / 77 / 7c

说明

DEC 定位器协议比 xterm 扩展鼠标模式早十年,是 VT300+ 硬件终端(以及软件模拟器在调到高 DECSCL 一致性级别 —— 见 decscl-compat-level —— 时)上报指点设备事件的方式。四个序列共同构成该族 —— 均以单引号(0x27)为中间字节:

- DECELR —— *启用定位器报告* —— \x1b[<Pn>;<Pu>'z - Pn0 = 关闭定位器报告;1 = 启用;2 = 启用一次报告后自动关闭。 - Pu02 = 坐标按字符单元;1 = 坐标按设备单位(像素)。 - 启用后,每次按键过 DECSLE 过滤都会发 DECLRP 报告;若 DECEFR 设了矩形,离开矩形时也发一份。

- DECSLE —— *选择定位器事件* —— \x1b[<Pm>'{ - Pm0 = 仅显式 DECRQLP 才回;1 = 按下事件回;2 = 关闭按下事件回;3 = 抬起事件回;4 = 关闭抬起事件回。 - 可多次发不同 Pm 同时开按下 + 抬起:\x1b[1'{\x1b[3'{

- DECEFR —— *启用过滤矩形* —— \x1b[<Pt>;<Pl>;<Pb>;<Pr>'w - 定义闭矩形:上行、左列、下行、右列。指点*离开*该矩形时触发一次 DECLRP,过滤器随即自动关闭。 - 用于只关心「鼠标离开我的控件」转换的光标追踪程序。

- DECRQLP —— *请求定位器位置* —— \x1b[<Ps>'| - Ps:事务数(目前总为 1)。 - 强制立刻发 DECLRP,与过滤 / 事件设置无关。

DECLRP —— 回复 —— \x1b[<Pe>;<Pb>;<Pr>;<Pc>;<Pp>&w(注意中间字节 &,与请求的 final 不同): - Pe = 事件类型:0 = 定位器不可用、1 = DECRQLP 的回复、2 = 左键按下、3 = 左键抬起、4 = 中键按下、5 = 中键抬起、6 = 右键按下、7 = 右键抬起、8 = M4(第 4 键)按下、9 = M4 抬起、10 = 离开过滤矩形。 - Pb = 按键状态位掩码:1 = 左、2 = 中、4 = 右、8 = 第 4 键。可 OR。 - PrPc = 行、列(1 起算),单位取自 DECELR 的 Pu。 - Pp = 页号(现代模拟器恒为 1 —— 多页是硬件终端概念)。

为何你几乎用不到:1980 年代写的若干 CAD、终端 GIS、radar / SCADA 程序仰赖此协议。某些 xterm 扩展(xterm*set-locator-events X 资源)仍允许启用。现代交互式 UI —— tmux、htop、mc、lazygit、fzf、neovim 的 :terminal —— 全部改用 SGR 鼠标模式(?1000 启用 + ?1006 SGR 编码;见 dec-mouse-trackingsgr-mouse-encoding):解析更简单、多字节坐标天然支持、跨模拟器覆盖近乎完美。

覆盖度xterm = 完整实现(唯一广泛部署的);gnome-terminal / konsole = 部分(DECRQLP 回合成的「无指点」DECLRP);iTerm2 / kitty / wezterm / alacritty / ghostty / Windows Terminal / cmd / Linux console / macOS Terminal = 无 —— 序列被静默吞掉,不回。

仍可能用到的场景:专门面向旧 XFCE / CDE 上的 xterm;移植旧 SCADA 终端程序;测 terminfo 的 locator_* capabilities。否则直接用 SGR 鼠标模式。

规范出处: DEC VT510 RM (DECELR / DECEFR / DECSLE / DECRQLP / DECLRP) / xterm-ctlseqs

示例

bash
# Enable locator reports (cell coords, one-shot), then query position.\nprintf \"\\033[2;0'z\"   # DECELR Pn=2 one-shot, Pu=0 cells\nprintf \"\\033[1'|\"     # DECRQLP — force immediate DECLRP reply\n# read reply matching: \\x1b[1;Pb;Pr;Pc;1&w
python
import sys\n# Set filter rectangle around rows 5-20, cols 10-60 then enable button-down events.\nsys.stdout.write(\"\\x1b[1;0'z\")        # DECELR enable, cells\nsys.stdout.write(\"\\x1b[5;10;20;60'w\") # DECEFR filter rect\nsys.stdout.write(\"\\x1b[1'{\")          # DECSLE enable button-down reports\nsys.stdout.flush()
go
// Disable locator reports (clean exit).\nfmt.Print(\"\\x1b[0;0'z\")
javascript
// Parse a DECLRP reply: \\x1b[Pe;Pb;Pr;Pc;Pp&w\nfunction parseDECLRP(buf) {\n  const m = /\\x1b\\[(\\d+);(\\d+);(\\d+);(\\d+);(\\d+)&w/.exec(buf);\n  if (!m) return null;\n  return { event: +m[1], buttons: +m[2], row: +m[3], col: +m[4], page: +m[5] };\n}
c
/* Force a single locator-position report (synchronous-ish probe). */\nprintf(\"\\x1b[1;0'z\");   /* DECELR enable, cells */\nprintf(\"\\x1b[1'|\");     /* DECRQLP */\nfflush(stdout);\n/* read reply: matches sscanf(\"\\x1b[%d;%d;%d;%d;%d&w\", &pe,&pb,&pr,&pc,&pp) */

终端支持

xterm
支持
Linux console (fbcon)
不支持
macOS Terminal.app
不支持
iTerm2
不支持
Windows Terminal
不支持
cmd.exe / ConPTY
不支持
kitty
不支持
alacritty
不支持
WezTerm
不支持
Ghostty
不支持
GNOME Terminal
部分
Konsole
部分
tmux
不支持
GNU screen
不支持

相关序列