{"id":15992824,"url":"https://github.com/bash/terminal-unsolicited-reports","last_synced_at":"2025-04-04T23:24:01.163Z","repository":{"id":230254128,"uuid":"776543101","full_name":"bash/terminal-unsolicited-reports","owner":"bash","description":"Notify terminal applications about color changes","archived":false,"fork":false,"pushed_at":"2024-08-15T20:36:12.000Z","size":44,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-27T12:44:12.149Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://tau.garden/terminal-unsolicited-reports/","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bash.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-23T19:49:27.000Z","updated_at":"2024-08-15T20:36:16.000Z","dependencies_parsed_at":"2024-04-17T12:50:26.817Z","dependency_job_id":"216ea2c8-c28e-4ac1-b58e-581c0c4e4e27","html_url":"https://github.com/bash/terminal-unsolicited-reports","commit_stats":null,"previous_names":["bash/terminal-color-change"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bash%2Fterminal-unsolicited-reports","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bash%2Fterminal-unsolicited-reports/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bash%2Fterminal-unsolicited-reports/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bash%2Fterminal-unsolicited-reports/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bash","download_url":"https://codeload.github.com/bash/terminal-unsolicited-reports/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247263380,"owners_count":20910395,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-08T06:41:18.544Z","updated_at":"2025-04-04T23:24:01.142Z","avatar_url":"https://github.com/bash.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Unsolicited Reporting (of Colors)\n\n### Summary\nThis 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.\n\nThe following specification is largely based on a [discussion in VTE's issue tracker][vte-discussion].\n\n### Motivation\nApplications 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.\n\nThis can happen when the user changes their color scheme manually or when the terminal changes with the system's dark-light preference.\n\nThe current state is an issue for the following kinds of applications:\n* **multiplexers** such as tmux need to respond to one-time queries and have no way of knowing when the connected terminal changes its colors.\n* **TUIs** such as VIM only detect the users dark-light preference at startup and don't adapt to changes from the terminal.\n\n## Overview\nTerminals send an *unsolicited report* when the *effective value* of a *tracked query* changes.\n\nApplications 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 [^one-time-query-format].\n\nIn terminals that don't support the new *Unsolicited Reports Mode*\napplications get a graceful fallback i.e. they receive the current value in response to the query.\n\nUnsolicited reporting follows the granularity of the queries themselves[^granularity]. 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.\n\n[^one-time-query-format]: Namely that it also uses the *canonical form* if the query is in *canonical form*.\n[^granularity]: 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.\n\n## Definitions\n\n### Unsolicited Reports Mode\nUnsolicited Reports Mode is a new DEC private mode.\nIt uses the `DECSET`/`DECRST` number `2510` [^number].\n\n**Set**ting the mode using `DECSET` doesn't have an immediate effect. \\\nOne-time queries received while the mode is enabled add the query to the set of *tracked queries*.\n\n**Reset**ting the mode either indirectly or using `DECRST` will \\\nclear the set of *tracked queries*.\n\nWhile 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.\n\n[^number]: 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][dec-modes] of DEC modes.\n\n### Tracked Queries\nThe 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.\n\n### Unsolicited Report\nTerminals send an *unsolicited report* when the *effective value* of a *tracked query* changes.\n\nUnsolicited reports always use the *canonical form* of the one-time report if the *tracked query* was in *canonical form*.\nIf the *tracked query* was not in canonical form, then it is left undefined what form the report uses.\n\nTerminals may report a change even if the *effective value* has not changed [^feedback-loop].\n\nTerminals may choose to bundle up reports (e.g. to avoid reporting multiple changes in quick succession) and deliver them with a short delay.\nReports 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.\n\n[^feedback-loop]: \n\tApplications that have continuous reporting enabled\n    *and* want to use an OSC sequence\n    to set the queried value have to be careful to\n    avoid a possible feedback loop.\n\n### Effective Value\nThe *effective value* of a palette color is the value reported in response to a one-time `OSC` query (e.g. `OSC 11 ; ?`).\n\nSome sources that may affect the *effective value*:\n* The corresponding `OSC` color control sequence\n* The corresponding `OSC` reset sequence\n* User Preferences\n\nThis 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).\n\nAdditionally this definition accounts for terminals that have multiple \"levels\" per color (e.g. user preference and set via `OSC` sequence).\n\nFurthermore it leaves room for terminals to \"stub\" certain responses (e.g. VTE responds to queries for unimplemented *special colors* with the default foreground color).\n\n### Canonical Form\nAn `OSC` color control sequence is in *canonical form* if:\n* It is terminated by `ST` (instead of `BEL`).\n* It is encoded as `C0`.\n* It uses the `rgb:rrrr/gggg/bbbb` form for fully opaque colors and the `rgba:rrrr/gggg/bbbb/aaaa` [^partially-opaque] form for partially opaque colors. The channels (and opacity) are encoded as 16-bit hexadecimal numbers [^compatibility].\n\nFor *special colors* the canonical form is `OSC 5 ; n` instead of `OSC 4 ; 256+n`.\n\n\n[^partially-opaque]: \n\tThis rule is included because `urxvt` supports partially opaque colors. It is irrelevant for terminals that don't.\n[^compatibility]: \n\tApplications that want to be compatible with a wide range of terminals have to support some variation in the responses:\n\t* Both `st` and macOS' built-in terminal always terminate their response with `BEL`.\n\t* `urxvt`'s current version terminates responses with `ESC` if the query uses `ST` ([fixed](http://cvs.schmorp.de/rxvt-unicode/src/command.C?revision=1.600\u0026view=markup)).\n\t* Terminology's current version uses the `#rrggbb` format when responding to `OSC 10` queries ([fixed](https://git.enlightenment.org/enlightenment/terminology/issues/14)).\n\t* iTerm2 [can be configured](https://gitlab.com/gnachman/iterm2/-/commit/5c5785f3632b8e90dd69f458411a8b8b17aa0599) to use 8-bit color components instead of 16-bit.\n\n### OSC Color Control Sequence\n*These definitions are mostly taken from the [XTerm Control Sequences] document.*\n\nAn `OSC` color control sequence is one of the following `OSC` sequences:\n* `OSC 4 ; n`: 256-color palette color\n* `OSC 5 ; n`: Special color\n* `OSC 10`: VT100 text foreground color\n* `OSC 11`: VT100 text background color\n* `OSC 12`: Text cursor color\n* `OSC 13`: Pointer foreground color\n* `OSC 14`: Pointer background color\n* `OSC 15`: Tektronix foreground color\n* `OSC 16`: Tektronix background color\n* `OSC 17`: Highlight background color\n* `OSC 18`: Tektronix cursor color\n* `OSC 19`: Highlight foreground color\n\nEach of these colors has a corresponding reset sequence\n`OSC 100+x`. For example `OSC 13` is reset by `OSC 113`.\n\n## Prior Art and Alternatives\n\n### `SIGWINCH`\nThis mechanism is implemented by [iTerm2][iterm-sigwinch].\nSome tools such as [tmux][tmux-sigwinch] and [zellij][zellij-sigwinch] already interpret `SIGWINCH` as a color changed signal.\n\nUsing an escape sequence to deliver the change notification\nhas a couple of advantages over using `SIGWINCH`:\n\n* `SIWGINCH` is fired many times when the terminal is resized.\n  Programs that care about the color need to debounce the signal somehow\n  to avoid sending `OSC 10` / `OSC 11` too often.\n* There's a clear and granular opt-in for color notification\n  so programs can choose which colors they care about.\n* An escape sequence can deliver the new color value\n  directly so programs don't have to send `OSC 10` / `OSC 11`\n  themselves.\n* An escape sequences is portable to situations without side-channel (e.g. Windows or plain Telnet).\n\n### Dark and Light Mode Detection\nContour provides [dark and light mode detection][contour-dark-light] using a custom device status report sequence.\n\nWhile 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.\n\n### Extend OSC Queries with `+?` and `-?`\nSee the [discussion][vte-discussion] in VTE's issue tracker.\n\n### Colour Table Report\nSee the [discussion][vte-discussion] in VTE's issue tracker.\n\n## Resources\n\n* [XTerm Control Sequences]\n* [Tau's Exhaustive List of DEC Modes][dec-modes]\n* [Kitty's Terminal Protocol Extensions](https://sw.kovidgoyal.net/kitty/protocol-extensions/)\n* [WezTerm's Escape Sequences](https://wezfurlong.org/wezterm/escape-sequences.html)\n* [iTerm2's Escape Sequences](https://iterm2.com/documentation-escape-codes.html)\n* [Contour's VT extensions][contour-vt-ext]\n* [mintty's Control Sequences][mintty-ctrlseqs]\n* [`console_codes(4)` man page][linux-console-codes]\n\n\n[vte-discussion]: https://gitlab.gnome.org/GNOME/vte/-/issues/2740\n[XTerm Control Sequences]: https://www.invisible-island.net/xterm/ctlseqs/ctlseqs.html\n[iterm-sigwinch]: https://gitlab.com/gnachman/iterm2/-/issues/9855\n[tmux-sigwinch]: https://github.com/tmux/tmux/issues/3582\n[zellij-sigwinch]: https://github.com/zellij-org/zellij/pull/1358\n[contour-vt-ext]: http://contour-terminal.org/vt-extensions\n[contour-dark-light]: http://contour-terminal.org/vt-extensions/color-palette-update-notifications/\n[mintty-ctrlseqs]: https://github.com/mintty/mintty/wiki/CtrlSeqs\n[linux-console-codes]: https://man7.org/linux/man-pages/man4/console_codes.4.html\n[dec-modes]: https://tau.garden/dec-modes/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbash%2Fterminal-unsolicited-reports","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbash%2Fterminal-unsolicited-reports","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbash%2Fterminal-unsolicited-reports/lists"}