^[control-codes
live in libghostty-vt

Operating system commands

OSC 4 Change Color Palette

View as Markdown

Set and query the colors that SGR's color numbers stand for.

OSC 4 ; Pc ; Pt ST
ECMA-48
§8.3.89 OSC – Operating System Command, p. 51
xterm
Operating System Commands

The terminal’s palette is the 256 colors that SGR’s color numbers stand for: CSI 31 m uses color 1, CSI 38 ; 5 ; 196 m color 196. OSC 4 ; Pc ; Pt ST changes color Pc to Pt, and OSC 104 ; Pc ST puts it back as it started. These are xterm’s.

  • Pt is a color in any form X11’s XParseColor accepts: a name such as red or light sky blue, #rrggbb, or rgb:rr/gg/bb, where each part may have one to four hex digits.
  • Pt of ? asks what the color is. The answer is OSC 4 ; Pc ; rgb:rrrr/gggg/bbbb, sixteen bits a part, ended with whichever of ST or BEL ended the question.
  • One sequence can carry several pairs, OSC 4 ; 1 ; red ; 2 ; ? ST, mixing changes and questions. xterm stops at the first color it cannot parse or number it does not have, and ignores the rest (ChangeAnsiColorRequest, ReportAnsiColorRequest).
  • DECSTR and RIS both reset the palette (ReallyReset).

Where the palette starts is the host’s choice, made in xterm with resources such as color1. The cases are run in a terminal given a default xterm’s: black, red3, green3, yellow3, blue2, magenta3, cyan3 and gray90, then their bright versions, for colors 0 to 15 (charproc.c), and the 6×6×6 cube and the gray ramp for 16 to 255 (256colres.h). The answers assume a 24-bit display, where xterm reports each part of a color as its eight bits repeated, cd as cdcd.

xterm also has OSC 5 and OSC 105, which work the same way on its special colors, the ones it can use for bold, underlined, blinking, reversed and italic text. libghostty-vt does keep the palette through DECSTR, but its DECSTR is not implemented at all (see DECSTR).

Support

TerminalVersionSupportNotes
VT220manual, 2nd ed., 1984NoOSC is not among the controls it recognizes (§4.2)
VT510manual, 1st ed., 1993Noignores an OSC string (chapter 4)
xtermpatch 412, xterm-411aYes
libghostty-vt0f171f6YesDECSTR does not reset it, having no DECSTR (OSC4-8)
Konsole26.11.70, a24c3d71Partlyanswers only the first ? in a list, and sets every color in a list to the first one’s
kitty0.49.1, run in a VMPartlyfails OSC4-4 of the 3 cases that show it working; ends its replies with ST where xterm uses BEL
foot1.28.0, run in a VMPartlyfails OSC4-5 of the 2 cases that show it working
pyte0.8.2, run as a libraryNofails the 3 cases that show it working
xterm.js headless6.0.0, run as a libraryNofails the 3 cases that show it working
alacritty_terminal0.26.0, run as a libraryPartlyfails OSC4-5 of the 3 cases that show it working
ConEmubuild 230724, its documentationNonot in its ANSI escape codes
rxvt-unicode9.31, run in a VMPartlyfails OSC4-4, OSC4-7 of the 3 cases that show it working; writes colors as ff00 where xterm writes ffff
VTE0.84.1, run as a libraryPartlyfails OSC4-5 of the 3 cases that show it working

Validation

OSC4-1: Ask for a color

\e]4;1;?\a
|____|
reply \e]4;1;rgb:cdcd/0000/0000\a

OSC4-2: The answer ends as the question did

\e]4;12;?\e\\
|____|
reply \e]4;12;rgb:5c5c/5c5c/ffff\e\\

OSC4-3: From the cube and the gray ramp

\e]4;196;?;244;?\a
|____|
reply \e]4;196;rgb:ffff/0000/0000\a\e]4;244;rgb:8080/8080/8080\a

OSC4-4: Change a color, and text drawn in it

\e[31mA
\e]4;1;#123456\a
\e]4;1;?\a
|A___|
attr 1,1 fg=#123456
reply \e]4;1;rgb:1212/3434/5656\a

OSC4-5: By name, and by rgb:

\e]4;1;light sky blue;2;rgb:f/80/abc\a
\e]4;1;?;2;?\a
|____|
reply \e]4;1;rgb:8787/cece/fafa\a\e]4;2;rgb:ffff/8080/abab\a

OSC4-6: A color it cannot parse stops the rest

\e]4;1;nosuch;2;red\a
\e]4;1;?;2;?\a
|____|
reply \e]4;1;rgb:cdcd/0000/0000\a\e]4;2;rgb:0000/cdcd/0000\a

OSC4-7: RIS resets the palette

\e]4;1;red\a
\ec
\e]4;1;?\a
|____|
reply \e]4;1;rgb:cdcd/0000/0000\a

OSC4-8: So does DECSTR

\e]4;1;red\a
\e[!p
\e]4;1;?\a
|____|
reply \e]4;1;rgb:cdcd/0000/0000\a
Every example on these pages runs in your browser, in libghostty-vt compiled to WebAssembly.