Skip to content

Support light/dark color-scheme query (CSI ?996n) - #339

Open
ghosthack wants to merge 2 commits into
JetBrains:masterfrom
ghosthack:upstream-pr/dsr-996-color-mode
Open

ghosthack wants to merge 2 commits into
JetBrains:masterfrom
ghosthack:upstream-pr/dsr-996-color-mode

Conversation

@ghosthack

Copy link
Copy Markdown

Summary

Several modern terminal emulators (Ghostty, Contour, foot) implement a VT
extension where a program queries the host terminal's light/dark color
preference with CSI ?996n and gets back CSI ?997;<n>n (0=unknown,
1=light, 2=dark). Some CLIs now send this to pick their own theme.

JediTerm currently treats this as an unrecognized DEC-specific Device
Status Report and silently drops it (Don't support DEC-specific Device Report Status), so the querying program never gets an answer.

This adds support for it:

  • Terminal.getColorMode() — new default method, returns UNKNOWN unless overridden
  • TerminalColorMode — new enum (UNKNOWN/LIGHT/DARK) carrying the reply code
  • JediTerminal.setColorMode(...) — lets the embedding application report its actual theme
  • JediEmulator answers CSI ?996n with CSI ?997;<code>n instead of warning and dropping it

Also improved the existing warning for any other unrecognized
DEC-specific DSR to include ControlSequence.getDebugInfo() (parsed args

  • raw ESC[...] sequence) instead of a generic message, which is how I
    found the ?996n case in the first place — useful for diagnosing future
    unsupported sequences without needing DEBUG-level logging enabled.

Fully additive/backwards compatible — no existing method signatures changed, getColorMode() is a default method, getColorMode/setColorMode only apply if the embedder opts in.

Test plan

  • ./gradlew :core:compileJava :core:compileKotlin against current master
  • Verified against a real-world repro: a CLI running inside a JediTerm-backed pty sending CSI ?996n, confirmed the correct CSI ?997;<n>n reply is now sent based on the embedding app's reported color mode

Answers the CSI ?996n Device Status Report (used by modern CLIs to detect
a terminal's light/dark preference) with CSI ?997;<n>n instead of leaving
it as an unsupported DEC-specific DSR. Terminal.getColorMode() defaults to
UNKNOWN; JediTerminal.setColorMode() lets the embedding app report its
actual theme.
@ghosthack
ghosthack force-pushed the upstream-pr/dsr-996-color-mode branch from 8ee41a8 to e643bd2 Compare October 10, 2026 21:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant