XTWINOPS Window Operations
Move, resize and raise the window, report its size and state, and save and restore its title.
CSI Ps ; Ps ; Ps t
- Defaults
- Ps = 0
- xterm
- Functions using CSI
CSI Ps ; Ps ; Ps t is xterm’s window manipulation sequence, taken from dtterm. The first parameter says what to do:
Ps | Does | Answers |
|---|---|---|
1, 2 | de-iconify, iconify | |
3 ; x ; y | move the window | |
4 ; h ; w, 8 ; rows ; cols | resize it, in pixels or in characters | |
5, 6, 7 | raise, lower, refresh | |
9 ; n, 10 ; n | maximize, full screen | |
11 | report whether iconified | CSI 1 t or CSI 2 t |
13 | report the window’s position | CSI 3 ; x ; y t |
14, 15, 16 | report the window, the screen, a character cell, in pixels | CSI 4 ; h ; w t, CSI 5 ; h ; w t, CSI 6 ; h ; w t |
18, 19 | report the text area, the screen, in characters | CSI 8 ; rows ; cols t, CSI 9 ; rows ; cols t |
20, 21 | report the icon name, the window title | OSC L name ST, OSC l title ST |
22 ; n, 23 ; n | push the title on a stack, pop it | |
24 and up | resize to that many lines, as DECSLPP; see below for 28 |
For 22 and 23 the second parameter says which title: 0 both, 1 the icon name, 2 the window title. The stack holds ten, and popping an empty one does nothing (xtermPushTitle, xtermPopTitle). Programs push the title before setting their own and pop it on leaving, so the shell’s title comes back.
xterm gates each operation by the allowWindowOps and disallowedWindowOps resources. allowWindowOps is off by default, but that only applies the list, and the default list names just GetIconTitle and GetWinTitle here, since reporting a title back lets a program type whatever it put there into the shell. A default xterm does everything else, resizing included (window_ops, main.h). The cases follow it.
Konsole once used CSI 28 ; color t to set the color of a tab’s text, with color a 24-bit number. Today’s Konsole ignores it, and its source says it is a Konsole extension from the KDE 3 days that is no longer implemented (Vt102Emulation.cpp). To xterm, 28 is just a number of lines: it resizes the window to 28 lines and ignores the color.
libghostty-vt answers 14, 16 and 18 through its host’s SIZE callback, which the runner installs, giving the case’s own size and an arbitrary cell of 6 by 13 pixels; the cases check only 18, since the pixel sizes depend on xterm’s font. It does nothing with the rest, which are the host’s window to move: it has no title stack, and does not report whether the window is iconified. Those cases are known differences.
Support
| Terminal | Version | Support | Notes |
|---|---|---|---|
| VT220 | manual, 2nd ed., 1984 | No | not in the manual |
| VT510 | manual, 1st ed., 1993 | Partly | only 24 and up, as DECSLPP |
| xterm | patch 412, xterm-411a | Partly | 20 and 21 are refused by the default disallowedWindowOps; the rest are allowed |
| libghostty-vt | 0f171f6 | Partly | answers 14, 16 and 18 through its host; no title stack or 11 (XTWINOPS-2, -4, -5) |
| kitty | 0.49.1, run in a VM | Partly | fails XTWINOPS-2 of the 4 cases that show it working |
| foot | 1.28.0, run in a VM | Yes | passes the 4 cases that show it working |
| pyte | 0.8.2, run as a library | No | fails the 4 cases that show it working |
| xterm.js headless | 6.0.0, run as a library | No | fails the 4 cases that show it working |
| alacritty_terminal | 0.26.0, run as a library | Partly | fails XTWINOPS-2 of the 4 cases that show it working |
| ConEmu | build 230724, its documentation | Partly | lists only 18, 19 and 21; ANSI escape codes |
| rxvt-unicode | 9.31, run in a VM | Partly | fails XTWINOPS-4, XTWINOPS-5 of the 4 cases that show it working |
| VTE | 0.84.1, run as a library | Yes | passes the 4 cases that show it working |
Validation
XTWINOPS-1: The text area in characters
\e[18t
|______|
|______|
reply \e[8;2;6t
XTWINOPS-2: Whether the window is iconified
\e[11t
|______|
reply \e[1t
XTWINOPS-3: The title is not reported
\e]2;secret\a
\e[21t
\e[20t
|______|
title "secret"
reply none
XTWINOPS-4: Push and pop the title
\e]2;shell\a
\e[22;0t # push
\e]2;editor\a
\e[23;0t # pop
|______|
title "shell"
XTWINOPS-5: A stack of them
\e]2;one\a
\e[22t
\e]2;two\a
\e[22t
\e]2;three\a
\e[23t
\e[23t
|______|
title "one"
XTWINOPS-6: Popping only the icon name
\e]2;one\a
\e[22;1t # push the icon name
\e]2;two\a
\e[23;1t # pop it: the window title stays
|______|
title "two"
XTWINOPS-7: Popping an empty stack
\e]2;same\a
\e[23;0t
|______|
title "same"