Send these to the terminal when TSE starts (and reset on exit):
ESC[?1002h   # button + drag tracking
ESC[?1006h   # SGR extended coordinates
…and to turn them off later:
ESC[?1002l
ESC[?1006l
These are standard xterm private modes for mouse reporting. (invisible-island.net)
Every mouse event arrives as:
ESC [ < b ; x ; y M     # press/drag
ESC [ < b ; x ; y m     # release (buttons 1–3)
where:
b = Button base + Modifier bits
x; y = 1-based column,row
Here the Modifier bits are: +4 for Shift, +8 for Alt (Meta), +16 for Ctrl
Here the Button bases:
Left=0, Middle=1, Right=2
WheelUp=64, WheelDown=65, WheelLeft=66, WheelRight=67
(Wheel sends only the M “press” form; there is no release.) (shuntksh.com)
Tip: For buttons (Left/Middle/Right), use
Mon press andmon release to distinguish down/up. For the wheels, you will only ever seeM. (invisible-island.net)
x;y into each)SEQ(b) means the literal escape sequence:
ESC[<b;x;yM   # for press/drag
ESC[<b;x;ym   # for release (buttons only)
<LeftBtn> → SEQ(0) / release SEQ(0)→m
<Alt LeftBtn> → SEQ(8) / release →m
<Ctrl LeftBtn> → SEQ(16) / release →m
<Shift LeftBtn> → SEQ(4) / release →m
<CtrlAlt LeftBtn> → SEQ(24) / release →m
<AltShift LeftBtn> → SEQ(12) / release →m
<CtrlShift LeftBtn> → SEQ(20) / release →m
<CtrlAltShift LeftBtn> → SEQ(28) / release →m
<CenterBtn> → SEQ(1) / release →m
<Alt CenterBtn> → SEQ(9) / release →m
<Ctrl CenterBtn> → SEQ(17) / release →m
<Shift CenterBtn> → SEQ(5) / release →m
<CtrlAlt CenterBtn> → SEQ(25) / release →m
<AltShift CenterBtn> → SEQ(13) / release →m
<CtrlShift CenterBtn> → SEQ(21) / release →m
<CtrlAltShift CenterBtn> → SEQ(29) / release →m
<RightBtn> → SEQ(2) / release →m
<Alt RightBtn> → SEQ(10) / release →m
<Ctrl RightBtn> → SEQ(18) / release →m
<Shift RightBtn> → SEQ(6) / release →m
<CtrlAlt RightBtn> → SEQ(26) / release →m
<AltShift RightBtn> → SEQ(14) / release →m
<CtrlShift RightBtn> → SEQ(22) / release →m
<CtrlAltShift RightBtn> → SEQ(30) / release →m
<WheelUp> → SEQ(64)
<Alt WheelUp> → SEQ(72)
<Ctrl WheelUp> → SEQ(80)
<Shift WheelUp> → SEQ(68)
<CtrlAlt WheelUp> → SEQ(88)
<AltShift WheelUp> → SEQ(76)
<CtrlShift WheelUp> → SEQ(84)
<CtrlAltShift WheelUp> → SEQ(92)
<WheelDown> → SEQ(65)
<Alt WheelDown> → SEQ(73)
<Ctrl WheelDown> → SEQ(81)
<Shift WheelDown> → SEQ(69)
<CtrlAlt WheelDown> → SEQ(89)
<AltShift WheelDown> → SEQ(77)
<CtrlShift WheelDown> → SEQ(85)
<CtrlAltShift WheelDown> → SEQ(93)
<WheelLeft> → SEQ(66)
<Alt WheelLeft> → SEQ(74)
<Ctrl WheelLeft> → SEQ(82)
<Shift WheelLeft> → SEQ(70)
<CtrlAlt WheelLeft> → SEQ(90)
<AltShift WheelLeft> → SEQ(78)
<CtrlShift WheelLeft> → SEQ(86)
<CtrlAltShift WheelLeft> → SEQ(94)
<WheelRight> → SEQ(67)
<Alt WheelRight> → SEQ(75)
<Ctrl WheelRight> → SEQ(83)
<Shift WheelRight> → SEQ(71)
<CtrlAlt WheelRight> → SEQ(91)
<AltShift WheelRight> → SEQ(79)
<CtrlShift WheelRight> → SEQ(87)
<CtrlAltShift WheelRight> → SEQ(95)
These are not standardized in terminals: many common Linux terminals (xterm, GNOME Terminal, Xfce4-terminal, Alacritty, tmux panes, etc.) do not report buttons 8/9 via DECSET 1006 at all, or they repurpose them (e.g., as browser back/forward at the window manager level). In practice you usually will not receive SGR packets for them. A common workaround is to map XButton1/XButton2 at the OS/WM level to keystrokes (e.g., Alt+Left / Alt+Right) and catch those as normal key escapes in TSE. (Unix & Linux Stack Exchange)
Release detection: Only buttons 1–3 (Left/Middle/Right) produce release packets (...m). Scroll wheels do not. (invisible-island.net)
Modifiers: The b field always adds +4 (Shift), +8 (Alt/Meta), +16 (Ctrl). If you enable xterm’s “special modifiers” off (ESC[?1035l), Alt tends to be reported as Meta rather than setting the high bit on keycodes—which is what you want for predictable Alt in terminals. (invisible-island.net)
Coordinates: x;y are 1-based cell positions (columns;rows). SGR works with big coordinates, unlike legacy X10/1000 mode. (invisible-island.net)
If you want, I can draft a tiny SAL helper that:
enables ?1002h/?1006h on entry,
reads ESC[<b;x;y(M|m) from the console,
decodes b → {button, modifiers, wheel}, and
dispatches to your 72 handler procedures.
