Unsolicited Reporting (of Colors)

Summary

This specification introduces an opt-in mechanism for terminals to inform applications of individual changes to the color palette (background, foreground, etc.). This is done by augmenting the behaviour of the existing OSC color queries using a new DEC private mode.

The following specification is largely based on a discussion in VTE's issue tracker.

Motivation

Applications today can query the terminal's colors using XTerm's OSC 4; ?, OSC 5; ?, OSC 10; ?, ... sequences. There is however no way to be informed when these colors change.

This can happen when the user changes their color scheme manually or when the terminal changes with the system's dark-light preference.

The current state is an issue for the following kinds of applications:

Overview

Terminals send an unsolicited report when the effective value of a tracked query changes.

Applications opt in to this behaviour by enabling the new Unsolicited Reports Mode. One-time queries sent while this mode is enabled add the query to the terminal's set of tracked queries. The one-time report is still generated and follows the same principles as unsolicited reports with regards to its format 1.

In terminals that don't support the new Unsolicited Reports Mode applications get a graceful fallback i.e. they receive the current value in response to the query.

Unsolicited reporting follows the granularity of the queries themselves2. This means that individual colors of the 256-color palette can be tracked by sending an OSC 4 query while the unsolicited reports mode is enabled.

Definitions

Unsolicited Reports Mode

Unsolicited Reports Mode is a new DEC private mode. It uses the DECSET/DECRST number 2510 3.

Setting the mode using DECSET doesn't have an immediate effect.
One-time queries received while the mode is enabled add the query to the set of tracked queries.

Resetting the mode either indirectly or using DECRST will
clear the set of tracked queries.

While the mode initially only affects OSC color queries it is intentionally kept general to allow future extensions. For example unsolicited reports for CSI ... t window ops.

Tracked Queries

The set of tracked queries determines for which changes the terminal generates an unsolicited report. Queries can be added to this set by sending a one-time query while the unsolicited reports mode is enabled.

Unsolicited Report

Terminals send an unsolicited report when the effective value of a tracked query changes.

Unsolicited reports always use the canonical form of the one-time report if the tracked query was in canonical form. If the tracked query was not in canonical form, then it is left undefined what form the report uses.

Terminals may report a change even if the effective value has not changed 4.

Terminals may choose to bundle up reports (e.g. to avoid reporting multiple changes in quick succession) and deliver them with a short delay. Reports are emitted in the same order as the changes have occurred in. When multiple changes occur in one bundling interval the order is determined by the first change.

Effective Value

The effective value of a palette color is the value reported in response to a one-time OSC query (e.g. OSC 11 ; ?).

Some sources that may affect the effective value:

This definition leaves room for terminals to change a color's value without affecting the effective value as long as the one-time query also doesn't report the change (e.g. slight darkening of the background of an unfocused pane).

Additionally this definition accounts for terminals that have multiple "levels" per color (e.g. user preference and set via OSC sequence).

Furthermore it leaves room for terminals to "stub" certain responses (e.g. VTE responds to queries for unimplemented special colors with the default foreground color).

Canonical Form

An OSC color control sequence is in canonical form if:

For special colors the canonical form is OSC 5 ; n instead of OSC 4 ; 256+n.

OSC Color Control Sequence

These definitions are mostly taken from the XTerm Control Sequences document.

An OSC color control sequence is one of the following OSC sequences:

Each of these colors has a corresponding reset sequence OSC 100+x. For example OSC 13 is reset by OSC 113.

Prior Art and Alternatives

SIGWINCH

This mechanism is implemented by iTerm2. Some tools such as tmux and zellij already interpret SIGWINCH as a color changed signal.

Using an escape sequence to deliver the change notification has a couple of advantages over using SIGWINCH:

Dark and Light Mode Detection

Contour provides dark and light mode detection using a custom device status report sequence.

While this method is by far easier to use by applications, it is not sufficient for multiplexers that want to respond to one-time OSC color queries with up-to-date values.

Extend OSC Queries with +? and -?

See the discussion in VTE's issue tracker.

Colour Table Report

See the discussion in VTE's issue tracker.

Resources

1

Namely that it also uses the canonical form if the query is in canonical form.

2

This spec is lax enough that terminals can make the granularity more coarse if they choose to. For example, a terminal may choose to group all OSC 4 or OSC 5 queries together.

3

I chose this number to be close to the existing numbers chosen by VTE but not conflict with any existing DECSET numbers. See my exhaustive list of DEC modes.

4

Applications that have continuous reporting enabled and want to use an OSC sequence to set the queried value have to be careful to avoid a possible feedback loop.

5

This rule is included because urxvt supports partially opaque colors. It is irrelevant for terminals that don't.

6

Applications that want to be compatible with a wide range of terminals have to support some variation in the responses: