^[control-codes
live in libghostty-vt

Control sequences

XTWINOPS Window Operations

View as Markdown

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:

PsDoesAnswers
1, 2de-iconify, iconify
3 ; x ; ymove the window
4 ; h ; w, 8 ; rows ; colsresize it, in pixels or in characters
5, 6, 7raise, lower, refresh
9 ; n, 10 ; nmaximize, full screen
11report whether iconifiedCSI 1 t or CSI 2 t
13report the window’s positionCSI 3 ; x ; y t
14, 15, 16report the window, the screen, a character cell, in pixelsCSI 4 ; h ; w t, CSI 5 ; h ; w t, CSI 6 ; h ; w t
18, 19report the text area, the screen, in charactersCSI 8 ; rows ; cols t, CSI 9 ; rows ; cols t
20, 21report the icon name, the window titleOSC L name ST, OSC l title ST
22 ; n, 23 ; npush the title on a stack, pop it
24 and upresize 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

TerminalVersionSupportNotes
VT220manual, 2nd ed., 1984Nonot in the manual
VT510manual, 1st ed., 1993Partlyonly 24 and up, as DECSLPP
xtermpatch 412, xterm-411aPartly20 and 21 are refused by the default disallowedWindowOps; the rest are allowed
libghostty-vt0f171f6Partlyanswers 14, 16 and 18 through its host; no title stack or 11 (XTWINOPS-2, -4, -5)
kitty0.49.1, run in a VMPartlyfails XTWINOPS-2 of the 4 cases that show it working
foot1.28.0, run in a VMYespasses the 4 cases that show it working
pyte0.8.2, run as a libraryNofails the 4 cases that show it working
xterm.js headless6.0.0, run as a libraryNofails the 4 cases that show it working
alacritty_terminal0.26.0, run as a libraryPartlyfails XTWINOPS-2 of the 4 cases that show it working
ConEmubuild 230724, its documentationPartlylists only 18, 19 and 21; ANSI escape codes
rxvt-unicode9.31, run in a VMPartlyfails XTWINOPS-4, XTWINOPS-5 of the 4 cases that show it working
VTE0.84.1, run as a libraryYespasses 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"
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.